diff --git a/packages/automated-dispute/README.md b/packages/automated-dispute/README.md new file mode 100644 index 0000000..f3e73ca --- /dev/null +++ b/packages/automated-dispute/README.md @@ -0,0 +1,120 @@ +# ebo-agent: automated dispute + +The `automated-dispute` package in `ebo-agent` provides services for interacting with Prophet contracts to create EBO requests, responses and disputes. + +## Available Scripts + +Available scripts that can be run using `pnpm`: + +| Script | Description | +| ------------ | ------------------------------------------------------- | +| `build` | Build the library | +| `lint` | Run ESLint to check for coding standards | +| `lint:fix` | Run linter and automatically fix code formatting issues | +| `format` | Check code formatting and style using Prettier | +| `format:fix` | Run formatter and automatically fix issues | +| `test` | Run unit tests using Vitest | +| `coverage` | Run tests with coverage report | + +## API + +The primary services available within the `automated-dispute` package are the following: + +### [EboProcessor](./src/services/eboProcessor.ts) + +Class responsible for orchestrating the whole agent's flow. It fetches Prophet events and routes them (per request) to be handled by `EboActor` instances. + +The general flow of each periodic check can be summarized with the following diagram: + +```mermaid +sequenceDiagram + title EboProcessor General Flow + + participant EboProcessor + participant ProtocolProvider + participant EboActor + + EboProcessor->>ProtocolProvider: getCurrentEpoch() + ProtocolProvider-->>EboProcessor: epoch: Epoch + + EboProcessor->>ProtocolProvider: getEvents(lastCheckedBlock, lastBlock) + ProtocolProvider-->>EboProcessor: events: EboEvent[] + + EboProcessor->>EboProcessor: group events by request id + + loop group in groups + loop event in groups + EboProcessor->>EboActor: enqueue(event) + end + + EboProcessor->>EboActor: processEvents() + EboActor-->>EboProcessor: void + EboProcessor->>EboActor: onLastBlockUpdated() + EboActor-->>EboProcessor: void + + Note over EboProcessor,EboActor: If actor can be terminated (eg. request was finalized) + EboProcessor->>EboActor: terminate() + end + +``` + +It also creates new requests if a chain has no request created for the current epoch. + +### [EboActor](./src/services/eboActor.ts) + +Class responsible for Prophet and EBO business logic implementation that handles a single request (ie each request should have an instance of an `EboActor`). + +It triggers actions based on a stream of recent unprocessed events, eg: + +- Propose responses to new requests +- Dispute responses when there's an error with the response +- Pledge for/against disputes +- Finalize requests +- Etc. + +It's suggested to enqueue all unprocessed on chain events prior triggering `processEvents()`, as the actor assumes the last enqueued event is the last event on chain. + +### [ProtocolProvider](./src/services/protocolProvider.ts) + +Class responsible for calling all smart contracts related with EBO: + +- Oracle ([source](https://github.com/defi-wonderland/prophet-core/blob/dev/solidity/contracts/Oracle.sol)) +- BondEscalationModule ([source](https://github.com/defi-wonderland/prophet-modules/blob/dev/solidity/contracts/modules/dispute/BondEscalationModule.sol)) +- EBORequestCreator ([source](https://github.com/defi-wonderland/EBO-core/blob/dev/src/contracts/EBORequestCreator.sol)) +- HorizonAccountingExtension ([source](https://github.com/defi-wonderland/EBO-core/blob/dev/src/contracts/HorizonAccountingExtension.sol)) +- EpochManager ([source](https://github.com/defi-wonderland/EBO-core/blob/dev/src/contracts/EBORequestCreator.sol)) + +All contract write calls are being simulated first. After submitting the transaction, the `ProtocolProvider` instance will wait for transaction receipts. + +#### Available methods + +```ts +// General +getAccountAddress(); +getLastFinalizedBlock(); + +// EpochManager +getCurrentEpoch(); + +// EBORequestCreator +getAvailableChains(); + +// HorizonAccountingExtension +getAccountingModuleAddress(); +approveModule(module: Address); +getApprovedModules(user?: Address); + +// Oracle +getEvents(fromBlock: bigint, toBlock: bigint); +createRequest(epoch: bigint, chain: Caip2ChainId); +proposeResponse(request: Request["prophetData"], response: Response["prophetData"]); +disputeResponse(request: Request["prophetData"], response: Response["prophetData"], dispute: Dispute["prophetData"]); +pledgeForDispute(request: Request["prophetData"], dispute: Dispute["prophetData"]); +pledgeAgainstDispute(request: Request["prophetData"], dispute: Dispute["prophetData"]); +settleDispute(request: Request["prophetData"], response: Response["prophetData"], dispute: Dispute["prophetData"]); +escalateDispute(request: Request["prophetData"], response: Response["prophetData"], dispute: Dispute["prophetData"]); +finalize(request: Request["prophetData"], response: Response["prophetData"]) + +// BondEscalationModule +getEscalation(requestId: RequestId); +```