diff --git a/apps/agent/config.example.yml b/apps/agent/config.example.yml index 2813274..3a09782 100644 --- a/apps/agent/config.example.yml +++ b/apps/agent/config.example.yml @@ -8,6 +8,7 @@ protocolProvider: epochManager: "0x1234567890123456789012345678901234567890" eboRequestCreator: "0x1234567890123456789012345678901234567890" bondEscalationModule: "0x1234567890123456789012345678901234567890" + horizonAccountingExtension: "0x1234567890123456789012345678901234567890" blockNumberService: blockmetaConfig: diff --git a/apps/agent/src/config/schemas.ts b/apps/agent/src/config/schemas.ts index d5b387a..89089bf 100644 --- a/apps/agent/src/config/schemas.ts +++ b/apps/agent/src/config/schemas.ts @@ -43,6 +43,7 @@ const protocolProviderConfigSchema = z.object({ epochManager: addressSchema, eboRequestCreator: addressSchema, bondEscalationModule: addressSchema, + horizonAccountingExtension: addressSchema, }), }); diff --git a/packages/automated-dispute/src/abis/horizonAccountingExtension.ts b/packages/automated-dispute/src/abis/horizonAccountingExtension.ts new file mode 100644 index 0000000..87aa601 --- /dev/null +++ b/packages/automated-dispute/src/abis/horizonAccountingExtension.ts @@ -0,0 +1,430 @@ +export const horizonAccountingExtensionAbi = [ + { + type: "constructor", + inputs: [ + { name: "_horizonStaking", type: "address", internalType: "contract IHorizonStaking" }, + { name: "_oracle", type: "address", internalType: "contract IOracle" }, + { name: "_grt", type: "address", internalType: "contract IERC20" }, + { name: "_minThawingPeriod", type: "uint256", internalType: "uint256" }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "GRT", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract IERC20" }], + stateMutability: "view", + }, + { + type: "function", + name: "HORIZON_STAKING", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract IHorizonStaking" }], + stateMutability: "view", + }, + { + type: "function", + name: "MAX_SLASHING_USERS", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "MAX_USERS_TO_CHECK", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "MAX_VERIFIER_CUT", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "MIN_THAWING_PERIOD", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "ORACLE", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract IOracle" }], + stateMutability: "view", + }, + { + type: "function", + name: "approveModule", + inputs: [{ name: "_module", type: "address", internalType: "address" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "approvedModules", + inputs: [{ name: "_user", type: "address", internalType: "address" }], + outputs: [{ name: "_approvedModules", type: "address[]", internalType: "address[]" }], + stateMutability: "view", + }, + { + type: "function", + name: "bond", + inputs: [ + { name: "_bonder", type: "address", internalType: "address" }, + { name: "_requestId", type: "bytes32", internalType: "bytes32" }, + { name: "_amount", type: "uint256", internalType: "uint256" }, + { name: "_sender", type: "address", internalType: "address" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "bond", + inputs: [ + { name: "_bonder", type: "address", internalType: "address" }, + { name: "_requestId", type: "bytes32", internalType: "bytes32" }, + { name: "_amount", type: "uint256", internalType: "uint256" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "bondedForRequest", + inputs: [ + { name: "_bonder", type: "address", internalType: "address" }, + { name: "_requestId", type: "bytes32", internalType: "bytes32" }, + ], + outputs: [{ name: "_amount", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "claimEscalationReward", + inputs: [ + { name: "_disputeId", type: "bytes32", internalType: "bytes32" }, + { name: "_pledger", type: "address", internalType: "address" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "escalationResults", + inputs: [{ name: "_disputeId", type: "bytes32", internalType: "bytes32" }], + outputs: [ + { name: "requestId", type: "bytes32", internalType: "bytes32" }, + { name: "amountPerPledger", type: "uint256", internalType: "uint256" }, + { name: "bondSize", type: "uint256", internalType: "uint256" }, + { + name: "bondEscalationModule", + type: "address", + internalType: "contract IBondEscalationModule", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "onSettleBondEscalation", + inputs: [ + { + name: "_request", + type: "tuple", + internalType: "struct IOracle.Request", + components: [ + { name: "nonce", type: "uint96", internalType: "uint96" }, + { name: "requester", type: "address", internalType: "address" }, + { name: "requestModule", type: "address", internalType: "address" }, + { name: "responseModule", type: "address", internalType: "address" }, + { name: "disputeModule", type: "address", internalType: "address" }, + { name: "resolutionModule", type: "address", internalType: "address" }, + { name: "finalityModule", type: "address", internalType: "address" }, + { name: "requestModuleData", type: "bytes", internalType: "bytes" }, + { name: "responseModuleData", type: "bytes", internalType: "bytes" }, + { name: "disputeModuleData", type: "bytes", internalType: "bytes" }, + { name: "resolutionModuleData", type: "bytes", internalType: "bytes" }, + { name: "finalityModuleData", type: "bytes", internalType: "bytes" }, + ], + }, + { + name: "_dispute", + type: "tuple", + internalType: "struct IOracle.Dispute", + components: [ + { name: "disputer", type: "address", internalType: "address" }, + { name: "proposer", type: "address", internalType: "address" }, + { name: "responseId", type: "bytes32", internalType: "bytes32" }, + { name: "requestId", type: "bytes32", internalType: "bytes32" }, + ], + }, + { name: "_amountPerPledger", type: "uint256", internalType: "uint256" }, + { name: "_winningPledgersLength", type: "uint256", internalType: "uint256" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "pay", + inputs: [ + { name: "_requestId", type: "bytes32", internalType: "bytes32" }, + { name: "_payer", type: "address", internalType: "address" }, + { name: "_receiver", type: "address", internalType: "address" }, + { name: "_amount", type: "uint256", internalType: "uint256" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "pledge", + inputs: [ + { name: "_pledger", type: "address", internalType: "address" }, + { + name: "_request", + type: "tuple", + internalType: "struct IOracle.Request", + components: [ + { name: "nonce", type: "uint96", internalType: "uint96" }, + { name: "requester", type: "address", internalType: "address" }, + { name: "requestModule", type: "address", internalType: "address" }, + { name: "responseModule", type: "address", internalType: "address" }, + { name: "disputeModule", type: "address", internalType: "address" }, + { name: "resolutionModule", type: "address", internalType: "address" }, + { name: "finalityModule", type: "address", internalType: "address" }, + { name: "requestModuleData", type: "bytes", internalType: "bytes" }, + { name: "responseModuleData", type: "bytes", internalType: "bytes" }, + { name: "disputeModuleData", type: "bytes", internalType: "bytes" }, + { name: "resolutionModuleData", type: "bytes", internalType: "bytes" }, + { name: "finalityModuleData", type: "bytes", internalType: "bytes" }, + ], + }, + { + name: "_dispute", + type: "tuple", + internalType: "struct IOracle.Dispute", + components: [ + { name: "disputer", type: "address", internalType: "address" }, + { name: "proposer", type: "address", internalType: "address" }, + { name: "responseId", type: "bytes32", internalType: "bytes32" }, + { name: "requestId", type: "bytes32", internalType: "bytes32" }, + ], + }, + { name: "_amount", type: "uint256", internalType: "uint256" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "pledgerClaimed", + inputs: [ + { name: "_requestId", type: "bytes32", internalType: "bytes32" }, + { name: "_pledger", type: "address", internalType: "address" }, + ], + outputs: [{ name: "_claimed", type: "bool", internalType: "bool" }], + stateMutability: "view", + }, + { + type: "function", + name: "pledges", + inputs: [{ name: "_disputeId", type: "bytes32", internalType: "bytes32" }], + outputs: [{ name: "_amount", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "release", + inputs: [ + { name: "_bonder", type: "address", internalType: "address" }, + { name: "_requestId", type: "bytes32", internalType: "bytes32" }, + { name: "_amount", type: "uint256", internalType: "uint256" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "releasePledge", + inputs: [ + { + name: "_request", + type: "tuple", + internalType: "struct IOracle.Request", + components: [ + { name: "nonce", type: "uint96", internalType: "uint96" }, + { name: "requester", type: "address", internalType: "address" }, + { name: "requestModule", type: "address", internalType: "address" }, + { name: "responseModule", type: "address", internalType: "address" }, + { name: "disputeModule", type: "address", internalType: "address" }, + { name: "resolutionModule", type: "address", internalType: "address" }, + { name: "finalityModule", type: "address", internalType: "address" }, + { name: "requestModuleData", type: "bytes", internalType: "bytes" }, + { name: "responseModuleData", type: "bytes", internalType: "bytes" }, + { name: "disputeModuleData", type: "bytes", internalType: "bytes" }, + { name: "resolutionModuleData", type: "bytes", internalType: "bytes" }, + { name: "finalityModuleData", type: "bytes", internalType: "bytes" }, + ], + }, + { + name: "_dispute", + type: "tuple", + internalType: "struct IOracle.Dispute", + components: [ + { name: "disputer", type: "address", internalType: "address" }, + { name: "proposer", type: "address", internalType: "address" }, + { name: "responseId", type: "bytes32", internalType: "bytes32" }, + { name: "requestId", type: "bytes32", internalType: "bytes32" }, + ], + }, + { name: "_pledger", type: "address", internalType: "address" }, + { name: "_amount", type: "uint256", internalType: "uint256" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "revokeModule", + inputs: [{ name: "_module", type: "address", internalType: "address" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "slash", + inputs: [ + { name: "_disputeId", type: "bytes32", internalType: "bytes32" }, + { name: "_usersToSlash", type: "uint256", internalType: "uint256" }, + { name: "_maxUsersToCheck", type: "uint256", internalType: "uint256" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "totalBonded", + inputs: [{ name: "_user", type: "address", internalType: "address" }], + outputs: [{ name: "_bonded", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "event", + name: "BondEscalationSettled", + inputs: [ + { name: "_requestId", type: "bytes32", indexed: false, internalType: "bytes32" }, + { name: "_disputeId", type: "bytes32", indexed: false, internalType: "bytes32" }, + { name: "_amountPerPledger", type: "uint256", indexed: false, internalType: "uint256" }, + { + name: "_winningPledgersLength", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Bonded", + inputs: [ + { name: "_requestId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "_bonder", type: "address", indexed: true, internalType: "address" }, + { name: "_amount", type: "uint256", indexed: false, internalType: "uint256" }, + ], + anonymous: false, + }, + { + type: "event", + name: "EscalationRewardClaimed", + inputs: [ + { name: "_requestId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "_disputeId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "_pledger", type: "address", indexed: true, internalType: "address" }, + { name: "_reward", type: "uint256", indexed: false, internalType: "uint256" }, + { name: "_released", type: "uint256", indexed: false, internalType: "uint256" }, + ], + anonymous: false, + }, + { + type: "event", + name: "Paid", + inputs: [ + { name: "_requestId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "_beneficiary", type: "address", indexed: true, internalType: "address" }, + { name: "_payer", type: "address", indexed: true, internalType: "address" }, + { name: "_amount", type: "uint256", indexed: false, internalType: "uint256" }, + ], + anonymous: false, + }, + { + type: "event", + name: "PledgeReleased", + inputs: [ + { name: "_requestId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "_disputeId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "_pledger", type: "address", indexed: true, internalType: "address" }, + { name: "_amount", type: "uint256", indexed: false, internalType: "uint256" }, + ], + anonymous: false, + }, + { + type: "event", + name: "Pledged", + inputs: [ + { name: "_pledger", type: "address", indexed: true, internalType: "address" }, + { name: "_requestId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "_disputeId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "_amount", type: "uint256", indexed: false, internalType: "uint256" }, + ], + anonymous: false, + }, + { + type: "event", + name: "Released", + inputs: [ + { name: "_requestId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "_beneficiary", type: "address", indexed: true, internalType: "address" }, + { name: "_amount", type: "uint256", indexed: false, internalType: "uint256" }, + ], + anonymous: false, + }, + { + type: "event", + name: "WinningPledgersPaid", + inputs: [ + { name: "_requestId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { name: "_disputeId", type: "bytes32", indexed: true, internalType: "bytes32" }, + { + name: "_winningPledgers", + type: "address[]", + indexed: true, + internalType: "address[]", + }, + { name: "_amountPerPledger", type: "uint256", indexed: false, internalType: "uint256" }, + ], + anonymous: false, + }, + { type: "error", name: "HorizonAccountingExtension_AlreadyClaimed", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_AlreadySettled", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_FeeOnTransferToken", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_InsufficientBondedTokens", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_InsufficientFunds", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_InsufficientTokens", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_InvalidMaxVerifierCut", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_InvalidThawingPeriod", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_NoEscalationResult", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_NotAllowed", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_UnauthorizedModule", inputs: [] }, + { type: "error", name: "HorizonAccountingExtension_UnauthorizedUser", inputs: [] }, + { type: "error", name: "Validator_InvalidDispute", inputs: [] }, + { type: "error", name: "Validator_InvalidResponse", inputs: [] }, +] as const; diff --git a/packages/automated-dispute/src/abis/index.ts b/packages/automated-dispute/src/abis/index.ts index b958884..f5c80b6 100644 --- a/packages/automated-dispute/src/abis/index.ts +++ b/packages/automated-dispute/src/abis/index.ts @@ -2,3 +2,4 @@ export * from "./oracle.js"; export * from "./epochManager.js"; export * from "./eboRequestCreator.js"; export * from "./bondEscalationModule.js"; +export * from "./horizonAccountingExtension.js"; diff --git a/packages/automated-dispute/src/constants.ts b/packages/automated-dispute/src/constants.ts index f976123..e2290c5 100644 --- a/packages/automated-dispute/src/constants.ts +++ b/packages/automated-dispute/src/constants.ts @@ -3,4 +3,5 @@ export const ProtocolContractsNames = [ "epochManager", "eboRequestCreator", "bondEscalationModule", + "horizonAccountingExtension", ] as const; diff --git a/packages/automated-dispute/src/interfaces/protocolProvider.ts b/packages/automated-dispute/src/interfaces/protocolProvider.ts index 5508e18..f2ab854 100644 --- a/packages/automated-dispute/src/interfaces/protocolProvider.ts +++ b/packages/automated-dispute/src/interfaces/protocolProvider.ts @@ -53,6 +53,14 @@ export interface IReadProvider { * @returns A promise that resolves with an array of approved modules. */ getAccountingApprovedModules(): Promise
; + + /** + * 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; } /** @@ -161,6 +169,14 @@ export interface IWriteProvider { * @param modules an array of addresses for the modules to be approved */ approveAccountingModules(modules: Address[]): Promise