Skip to content

Commit

Permalink
feat: implement bondescalationmodule rpc calls (#43)
Browse files Browse the repository at this point in the history
# 🤖 Linear

Closes GRT-142

## Description
- Implements pledgeForDispute, pledgeAgainstDispute, settleDispute
(settleBondEscalation)
- Adds the custom contract errors in code comments (to be refactored
into a map in an error handling PR)

---------

Signed-off-by: jahabeebs <[email protected]>
  • Loading branch information
jahabeebs authored Sep 17, 2024
1 parent dcd5d89 commit 61ec14c
Show file tree
Hide file tree
Showing 7 changed files with 2,031 additions and 18 deletions.
1 change: 1 addition & 0 deletions apps/agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const config = {
oracle: "0x00",
epochManager: "0x00",
eboRequestCreator: "0x00",
bondEscalationModule: "0x00",
} as const,
privateKey: "0xsecret" as const,
},
Expand Down
1,710 changes: 1,710 additions & 0 deletions packages/automated-dispute/src/abis/bondEscalationModule.ts

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/automated-dispute/src/abis/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./oracle.js";
export * from "./epochManager.js";
export * from "./eboRequestCreator.js";
export * from "./bondEscalationModule.js";
7 changes: 6 additions & 1 deletion packages/automated-dispute/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
export const ProtocolContractsNames = ["oracle", "epochManager", "eboRequestCreator"] as const;
export const ProtocolContractsNames = [
"oracle",
"epochManager",
"eboRequestCreator",
"bondEscalationModule",
] as const;
161 changes: 147 additions & 14 deletions packages/automated-dispute/src/providers/protocolProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ import { privateKeyToAccount } from "viem/accounts";
import { arbitrum } from "viem/chains";

import type { Dispute, EboEvent, EboEventName, Epoch, Request, Response } from "../types/index.js";
import { eboRequestCreatorAbi, epochManagerAbi, oracleAbi } from "../abis/index.js";
import {
bondEscalationModuleAbi,
eboRequestCreatorAbi,
epochManagerAbi,
oracleAbi,
} from "../abis/index.js";
import {
InvalidAccountOnClient,
RpcUrlsEmpty,
Expand Down Expand Up @@ -56,6 +61,11 @@ export class ProtocolProvider implements IProtocolProvider {
typeof this.writeClient,
Address
>;
private bondEscalationContract: GetContractReturnType<
typeof bondEscalationModuleAbi,
typeof this.writeClient,
Address
>;

/**
* Creates a new ProtocolProvider instance
Expand Down Expand Up @@ -114,6 +124,14 @@ export class ProtocolProvider implements IProtocolProvider {
wallet: this.writeClient,
},
});
this.bondEscalationContract = getContract({
address: contracts.bondEscalationModule,
abi: bondEscalationModuleAbi,
client: {
public: this.readClient,
wallet: this.writeClient,
},
});
}

public write: IWriteProvider = {
Expand Down Expand Up @@ -403,29 +421,144 @@ export class ProtocolProvider implements IProtocolProvider {
}
}

/**
* Pledges support for a dispute.
*
* @param {Request["prophetData"]} request - The request data for the dispute.
* @param {Dispute["prophetData"]} dispute - The dispute data.
* @throws {TransactionExecutionError} Throws if the transaction fails during execution.
* @throws {ContractFunctionRevertedError} Throws if the contract function reverts.
* @returns {Promise<void>}
*/
async pledgeForDispute(
_request: Request["prophetData"],
_dispute: Dispute["prophetData"],
request: Request["prophetData"],
dispute: Dispute["prophetData"],
): Promise<void> {
// TODO: implement actual method
return;
try {
const { request: simulatedRequest } = await this.readClient.simulateContract({
address: this.bondEscalationContract.address,
abi: bondEscalationModuleAbi,
functionName: "pledgeForDispute",
args: [request, dispute],
account: this.writeClient.account,
});

const hash = await this.writeClient.writeContract(simulatedRequest);

const receipt = await this.readClient.waitForTransactionReceipt({
hash,
confirmations: TRANSACTION_RECEIPT_CONFIRMATIONS,
});

if (receipt.status !== "success") {
throw new TransactionExecutionError("pledgeForDispute transaction failed");
}
} catch (error) {
if (error instanceof BaseError) {
const revertError = error.walk(
(err) => err instanceof ContractFunctionRevertedError,
);
if (revertError instanceof ContractFunctionRevertedError) {
const errorName = revertError.data?.errorName ?? "";
throw ErrorFactory.createError(errorName);
}
}
throw error;
}
}

/**
* Pledges against a dispute.
*
* @param {Request["prophetData"]} request - The request data for the dispute.
* @param {Dispute["prophetData"]} dispute - The dispute data.
* @throws {TransactionExecutionError} Throws if the transaction fails during execution.
* @throws {ContractFunctionRevertedError} Throws if the contract function reverts.
* @returns {Promise<void>}
*/
async pledgeAgainstDispute(
_request: Request["prophetData"],
_dispute: Dispute["prophetData"],
request: Request["prophetData"],
dispute: Dispute["prophetData"],
): Promise<void> {
// TODO: implement actual method
return;
try {
const { request: simulatedRequest } = await this.readClient.simulateContract({
address: this.bondEscalationContract.address,
abi: bondEscalationModuleAbi,
functionName: "pledgeAgainstDispute",
args: [request, dispute],
account: this.writeClient.account,
});

const hash = await this.writeClient.writeContract(simulatedRequest);

const receipt = await this.readClient.waitForTransactionReceipt({
hash,
confirmations: TRANSACTION_RECEIPT_CONFIRMATIONS,
});

if (receipt.status !== "success") {
throw new TransactionExecutionError("pledgeAgainstDispute transaction failed");
}
} catch (error) {
if (error instanceof BaseError) {
const revertError = error.walk(
(err) => err instanceof ContractFunctionRevertedError,
);
if (revertError instanceof ContractFunctionRevertedError) {
const errorName = revertError.data?.errorName ?? "";
throw ErrorFactory.createError(errorName);
}
}
throw error;
}
}

/**
* Settles a dispute by finalizing the response.
*
* @param {Request["prophetData"]} request - The request data.
* @param {Response["prophetData"]} response - The response data.
* @param {Dispute["prophetData"]} dispute - The dispute data.
* @throws {TransactionExecutionError} Throws if the transaction fails during execution.
* @throws {ContractFunctionRevertedError} Throws if the contract function reverts.
* @returns {Promise<void>}
*/
async settleDispute(
_request: Request["prophetData"],
_response: Response["prophetData"],
_dispute: Dispute["prophetData"],
request: Request["prophetData"],
response: Response["prophetData"],
dispute: Dispute["prophetData"],
): Promise<void> {
// TODO: implement actual method
return;
try {
const { request: simulatedRequest } = await this.readClient.simulateContract({
address: this.bondEscalationContract.address,
abi: bondEscalationModuleAbi,
functionName: "settleBondEscalation",
args: [request, response, dispute],
account: this.writeClient.account,
});

const hash = await this.writeClient.writeContract(simulatedRequest);

const receipt = await this.readClient.waitForTransactionReceipt({
hash,
confirmations: TRANSACTION_RECEIPT_CONFIRMATIONS,
});

if (receipt.status !== "success") {
throw new TransactionExecutionError("settleBondEscalation transaction failed");
}
} catch (error) {
if (error instanceof BaseError) {
const revertError = error.walk(
(err) => err instanceof ContractFunctionRevertedError,
);
if (revertError instanceof ContractFunctionRevertedError) {
const errorName = revertError.data?.errorName ?? "";
throw ErrorFactory.createError(errorName);
}
}
throw error;
}
}

/**
Expand Down
21 changes: 21 additions & 0 deletions packages/automated-dispute/src/services/errorFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,27 @@ export class ErrorFactory {
// case "EBOFinalityModule_InvalidRequester":
// case "Oracle_InvalidFinalizedResponse":
// case "Oracle_FinalizableResponseExists":
// case "ValidatorLib_InvalidDispute":
// case "BondEscalationModule_CannotBreakTieDuringTyingBuffer":
// case "BondEscalationModule_CanOnlySurpassByOnePledge":
// case "BondEscalationModule_MaxNumberOfEscalationsReached":
// case "BondEscalationModule_BondEscalationOver":
// case "BondEscalationModule_InvalidDispute":
// case "Validator_InvalidDispute":
// case "ArbitratorModule_InvalidArbitrator":
// case "BondEscalationAccounting_AlreadySettled":
// case "BondEscalationAccounting_InsufficientFunds":
// case "AccountingExtension_InsufficientFunds":
// case "AccountingExtension_NotAllowed":
// case "AccountingExtension_UnauthorizedModule":
// case "Oracle_InvalidDisputeId":
// case "Oracle_InvalidDispute":
// case "BondEscalationModule_NotEscalatable":
// case "BondEscalationModule_BondEscalationNotOver":
// case "Oracle_NotDisputeOrResolutionModule":
// case "BondEscalationModule_ShouldBeEscalated":
// case "BondEscalationModule_BondEscalationCantBeSettled":
// case "ValidatorLib_InvalidResponseBody":
return new Error(`Contract reverted: ${errorName}`);
default:
return new Error(`Unknown error: ${errorName}`);
Expand Down
Loading

0 comments on commit 61ec14c

Please sign in to comment.