Skip to content

Commit 2f37929

Browse files
committedAug 3, 2023
feat: retrieval of the DisputeRequest event, refactored to accommodate other foreign chains
1 parent ad3f194 commit 2f37929

File tree

6 files changed

+128
-48
lines changed

6 files changed

+128
-48
lines changed
 

‎contracts/hardhat.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const config: HardhatUserConfig = {
4848
saveDeployments: true,
4949
tags: ["test", "local"],
5050
companionNetworks: {
51+
home: "localhost",
5152
foreign: "localhost",
5253
},
5354
},

‎contracts/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
"simulate": "hardhat simulate:all",
2727
"simulate-local": "hardhat simulate:all --network localhost",
2828
"bot:keeper": "NODE_NO_WARNINGS=1 NODE_OPTIONS=--experimental-fetch hardhat run ./scripts/keeperBot.ts",
29-
"bot:relayer": "NODE_NO_WARNINGS=1 NODE_OPTIONS=--experimental-fetch hardhat run ./scripts/disputeRelayerBot.ts",
29+
"bot:relayer-from-chiado": "NODE_NO_WARNINGS=1 NODE_OPTIONS=--experimental-fetch hardhat run ./scripts/disputeRelayerBotFromChiado.ts",
30+
"bot:relayer-from-goerli": "NODE_NO_WARNINGS=1 NODE_OPTIONS=--experimental-fetch hardhat run ./scripts/disputeRelayerBotFromGoerli.ts",
31+
"bot:relayer-from-hardhat": "NODE_NO_WARNINGS=1 NODE_OPTIONS=--experimental-fetch hardhat run ./scripts/disputeRelayerBotFromHardhat.ts",
3032
"etherscan-verify": "hardhat etherscan-verify",
3133
"sourcify": "hardhat sourcify --write-failing-metadata",
3234
"size": "hardhat size-contracts --no-compile",

‎contracts/scripts/disputeRelayerBot.ts

Lines changed: 66 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,39 @@
11
import { ethers } from "hardhat";
22
import hre = require("hardhat");
3-
import { KlerosCore, PolicyRegistry, ForeignGateway__factory, HomeGateway, TestERC20 } from "../typechain-types";
3+
import {
4+
KlerosCore,
5+
ForeignGateway__factory,
6+
HomeGateway,
7+
TestERC20,
8+
IArbitrableV2__factory,
9+
} from "../typechain-types";
10+
import { DisputeRequestEventObject } from "../typechain-types/src/arbitration/interfaces/IArbitrableV2";
11+
import { HttpNetworkConfig } from "hardhat/types";
12+
import { DeploymentsExtension } from "hardhat-deploy/types";
413

5-
async function main() {
14+
export default async function main(
15+
foreignNetwork: HttpNetworkConfig,
16+
foreignDeployments: DeploymentsExtension,
17+
foreignGatewayArtifact: string,
18+
homeGatewayArtifact: string,
19+
feeTokenArtifact?: string
20+
) {
621
const core = (await ethers.getContract("KlerosCore")) as KlerosCore;
7-
const policyRegistry = (await ethers.getContract("PolicyRegistry")) as PolicyRegistry;
8-
const homeGateway = (await ethers.getContract("HomeGatewayToGnosis")) as HomeGateway;
9-
const dai = (await ethers.getContract("DAI")) as TestERC20;
22+
const homeGateway = (await ethers.getContract(homeGatewayArtifact)) as HomeGateway;
23+
const feeToken = feeTokenArtifact ? ((await ethers.getContract(feeTokenArtifact)) as TestERC20) : undefined;
1024

11-
const foreignChainProvider = new ethers.providers.JsonRpcProvider(hre.config.networks.chiado.url);
12-
const foreignGatewayDeployment = await hre.companionNetworks.foreignChiado.deployments.get("ForeignGatewayOnGnosis");
25+
const foreignChainProvider = new ethers.providers.JsonRpcProvider(foreignNetwork.url);
26+
const foreignGatewayDeployment = await foreignDeployments.get(foreignGatewayArtifact);
1327
const foreignGateway = await ForeignGateway__factory.connect(foreignGatewayDeployment.address, foreignChainProvider);
28+
const foreignChainId = await foreignChainProvider.getNetwork().then((network) => network.chainId);
29+
const arbitrableInterface = IArbitrableV2__factory.createInterface();
1430

31+
// Event subscription
32+
// WARNING: The callback might run more than once if the script is restarted in the same block
33+
// type Listener = [ eventArg1, ...eventArgN, transactionReceipt ]
1534
foreignGateway.on(
1635
"CrossChainDisputeOutgoing",
17-
async (foreignBlockHash, foreignArbitrable, foreignDisputeID, choices, extraData) => {
36+
async (foreignBlockHash, foreignArbitrable, foreignDisputeID, choices, extraData, txReceipt) => {
1837
console.log(
1938
"CrossChainDisputeOutgoing: %s %s %s %s %s",
2039
foreignBlockHash,
@@ -23,52 +42,52 @@ async function main() {
2342
choices,
2443
extraData
2544
);
45+
// console.log("tx receipt: %O", txReceipt);
2646

27-
const cost = (await core.functions["arbitrationCost(bytes,address)"](extraData, dai.address)).cost;
47+
// txReceipt is missing the full logs for this tx so we need to request it here
48+
const fullTxReceipt = await foreignChainProvider.getTransactionReceipt(txReceipt.transactionHash);
2849

29-
await dai.approve(homeGateway.address, cost);
50+
// Retrieve the DisputeRequest event
51+
const disputeRequest = fullTxReceipt.logs
52+
.filter((log) => log.topics[0] === arbitrableInterface.getEventTopic("DisputeRequest"))
53+
.map((log) => arbitrableInterface.parseLog(log).args as unknown as DisputeRequestEventObject)[0];
54+
console.log("tx events DisputeRequest: %O", disputeRequest);
55+
// TODO: log a warning if there are multiple DisputeRequest events
3056

31-
await homeGateway.functions[
32-
"relayCreateDispute((bytes32,uint256,address,uint256,uint256,uint256,string,uint256,bytes),uint256)"
33-
](
34-
{
35-
foreignBlockHash: foreignBlockHash,
36-
foreignChainID: 10200,
37-
foreignArbitrable: foreignArbitrable,
38-
foreignDisputeID: foreignDisputeID,
39-
externalDisputeID: ethers.utils.keccak256(ethers.utils.toUtf8Bytes("future of france")), // FIXME
40-
templateId: 1, // FIXME
41-
templateUri: "", // FIXME
42-
choices: choices,
43-
extraData: extraData,
44-
},
45-
cost
46-
);
57+
const relayCreateDisputeParams = {
58+
foreignBlockHash: foreignBlockHash,
59+
foreignChainID: foreignChainId,
60+
foreignArbitrable: foreignArbitrable,
61+
foreignDisputeID: foreignDisputeID,
62+
externalDisputeID: disputeRequest._externalDisputeID,
63+
templateId: disputeRequest._templateId,
64+
templateUri: disputeRequest._templateUri,
65+
choices: choices,
66+
extraData: extraData,
67+
};
68+
console.log("Relaying dispute to home chain... %O", relayCreateDisputeParams);
69+
70+
let tx;
71+
if (feeToken === undefined) {
72+
// Paying in native Arbitrum ETH
73+
const cost = (await core.functions["arbitrationCost(bytes)"](extraData)).cost;
74+
tx = await homeGateway.functions[
75+
"relayCreateDispute((bytes32,uint256,address,uint256,uint256,uint256,string,uint256,bytes))"
76+
](relayCreateDisputeParams, { value: cost });
77+
} else {
78+
// Paying in ERC20
79+
const cost = (await core.functions["arbitrationCost(bytes,address)"](extraData, feeToken.address)).cost;
80+
await (await feeToken.approve(homeGateway.address, cost)).wait();
81+
tx = await homeGateway.functions[
82+
"relayCreateDispute((bytes32,uint256,address,uint256,uint256,uint256,string,uint256,bytes),uint256)"
83+
](relayCreateDisputeParams, cost);
84+
}
85+
tx = tx.wait();
86+
console.log("relayCreateDispute txId: %O", tx.transactionHash);
4787
}
4888
);
4989

50-
// type Listener = [ eventArg1, ...eventArgN, transactionReceipt ]
51-
52-
// policyRegistry.on("PolicyUpdate", (courtId, courtName, policy, receipt) => {
53-
// console.log("PolicyUpdate: %d %s %s %O", courtId, courtName, policy, receipt);
54-
// // WARNING: This callback might run more than once if the script is restarted in the same block
55-
// });
56-
57-
// core.on("DisputeCreation", (disputeID, arbitrable) => {
58-
// console.log("DisputeCreation: %d %s %s %d %s %s", disputeID, arbitrable);
59-
// // WARNING: This callback might run more than once if the script is restarted in the same block
60-
61-
// // if phase is staking and minStakingTime has passed, then passPhase()
62-
// });
63-
6490
console.log("Listening for events...");
6591
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
6692
await delay(1000000);
6793
}
68-
69-
main()
70-
.then(() => process.exit(0))
71-
.catch((error) => {
72-
console.error(error);
73-
process.exit(1);
74-
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import hre = require("hardhat");
2+
import relayer from "./disputeRelayerBot";
3+
import { HttpNetworkConfig } from "hardhat/types";
4+
5+
async function main() {
6+
await relayer(
7+
hre.config.networks.chiado as HttpNetworkConfig,
8+
hre.companionNetworks.foreignChiado.deployments,
9+
"ForeignGatewayOnGnosis",
10+
"HomeGatewayToGnosis",
11+
"DAI"
12+
);
13+
}
14+
15+
main()
16+
.then(() => process.exit(0))
17+
.catch((error) => {
18+
console.error(error);
19+
process.exit(1);
20+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import hre = require("hardhat");
2+
import relayer from "./disputeRelayerBot";
3+
import { HttpNetworkConfig } from "hardhat/types";
4+
5+
async function main() {
6+
await relayer(
7+
hre.config.networks.goerli as HttpNetworkConfig,
8+
hre.companionNetworks.foreignGoerli.deployments,
9+
"ForeignGatewayOnEthereum",
10+
"HomeGatewayToEthereum"
11+
);
12+
}
13+
14+
main()
15+
.then(() => process.exit(0))
16+
.catch((error) => {
17+
console.error(error);
18+
process.exit(1);
19+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import hre = require("hardhat");
2+
import relayer from "./disputeRelayerBot";
3+
import { HttpNetworkConfig } from "hardhat/types";
4+
5+
async function main() {
6+
await relayer(
7+
hre.config.networks.localhost as HttpNetworkConfig,
8+
hre.companionNetworks.foreign.deployments,
9+
"ForeignGatewayOnEthereum",
10+
"HomeGatewayToEthereum"
11+
);
12+
}
13+
14+
main()
15+
.then(() => process.exit(0))
16+
.catch((error) => {
17+
console.error(error);
18+
process.exit(1);
19+
});

0 commit comments

Comments
 (0)
Please sign in to comment.