Skip to content

Release to Beta #120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Jul 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ Refresh the list of deployed contracts by running `./scripts/generateDeployments
### Devnet
#### Arbitrum Sepolia

- [EscrowCustomBuyer](https://sepolia.arbiscan.io/address/0xA01e6B988aeDae1fD4a748D6bfBcB8A438601DeE)
- [EscrowUniversal](https://sepolia.arbiscan.io/address/0x5ef185810BCe41c03c9E5ca271B8C91F1024F953)
- [EscrowView](https://sepolia.arbiscan.io/address/0x6451046caB9291a919FCba045bf6Bb8E0Bb71467)
- [EscrowViewCustomBuyer](https://sepolia.arbiscan.io/address/0xe0892815E8958f0ad6Dab876995987c4F439954D)

## Getting Started

Expand Down Expand Up @@ -91,7 +93,8 @@ yarn hardhat node --tags nothing
**Shell 2: the deploy script**

```bash
yarn deploy --network localhost --tags Escrow>
yarn deploy --network localhost --tags EscrowUniversal
yarn deploy --network localhost --tags EscrowCustomBuyer
```

#### 2. Deploy to a Public Network Fork
Expand All @@ -115,7 +118,8 @@ yarn deploy-testnet-fork
#### 3. Deploy to Public Testnets

```bash
yarn deploy --network arbitrumSepolia --tags Escrow
yarn deploy --network arbitrumSepolia --tags EscrowUniversal
yarn deploy --network arbitrumSepolia --tags EscrowCustomBuyer
```

The deployed addresses should be displayed to the screen after the deployment is complete. If you missed them, you can always go to the `deployments/<network>` directory and look for the respective file.
Expand All @@ -129,7 +133,7 @@ Same steps as above but append `Devnet` to the `--network` parameter.
**Shell 1: the node**

```bash
yarn hardhat node --tags Escrow
yarn hardhat node --tags EscrowUniversal
```

**Shell 2: the test scripts**
Expand Down
8 changes: 5 additions & 3 deletions contracts/README.md.template
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ yarn hardhat node --tags nothing
**Shell 2: the deploy script**

```bash
yarn deploy --network localhost --tags Escrow>
yarn deploy --network localhost --tags EscrowUniversal
yarn deploy --network localhost --tags EscrowCustomBuyer
```

#### 2. Deploy to a Public Network Fork
Expand All @@ -101,7 +102,8 @@ yarn deploy-testnet-fork
#### 3. Deploy to Public Testnets

```bash
yarn deploy --network arbitrumSepolia --tags Escrow
yarn deploy --network arbitrumSepolia --tags EscrowUniversal
yarn deploy --network arbitrumSepolia --tags EscrowCustomBuyer
```

The deployed addresses should be displayed to the screen after the deployment is complete. If you missed them, you can always go to the `deployments/<network>` directory and look for the respective file.
Expand All @@ -115,7 +117,7 @@ Same steps as above but append `Devnet` to the `--network` parameter.
**Shell 1: the node**

```bash
yarn hardhat node --tags Escrow
yarn hardhat node --tags EscrowUniversal
```

**Shell 2: the test scripts**
Expand Down
15 changes: 15 additions & 0 deletions contracts/deploy/00-escrow-custom-buyer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { HomeChains, isSkipped } from "./utils";
import deployEscrow from "./shared";

const deploy: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
await deployEscrow(hre, "customBuyer");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the "customBuyer" parameter matches shared deployment logic.

Ensure the "customBuyer" parameter is correctly handled in the shared deployment function.


🏁 Script executed:

#!/bin/bash
# Description: Check shared deployment function handles customBuyer parameter
# Expected: Function should have logic for customBuyer variant

ast-grep --pattern 'function deployEscrow($_, $_) {
  $$$
}'

Length of output: 62


🏁 Script executed:

#!/bin/bash
# Locate the deployEscrow definition and its usages across the repo
rg -n "deployEscrow" .

Length of output: 483


🏁 Script executed:

#!/bin/bash
# Display the implementation of deployEscrow in shared.ts
sed -n '1,200p' contracts/deploy/shared.ts

Length of output: 3524


Ensure customBuyer is configured before deploying

The deployEscrow helper assumes config[network.name].escrowDeployments.customBuyer is defined. On networks like arbitrum, this entry is undefined, so running:

await deployEscrow(hre, "customBuyer");

will throw at runtime. Please address this by:

  • In contracts/deploy/shared.ts, adding a guard or explicit error when escrowDeployments[escrowDeployment] is undefined before accessing .escrow/.view.
  • Or in contracts/deploy/00-escrow-custom-buyer.ts, wrapping the deployEscrow(hre, "customBuyer") call in a conditional that skips or falls back when customBuyer isn’t configured.
🤖 Prompt for AI Agents
In contracts/deploy/00-escrow-custom-buyer.ts at line 7, the call to
deployEscrow with "customBuyer" assumes the configuration exists, but on some
networks like arbitrum it is undefined causing runtime errors. Fix this by
adding a check before calling deployEscrow to verify that
config[network.name].escrowDeployments.customBuyer is defined; if not, skip the
deployment or provide a fallback. Alternatively, modify
contracts/deploy/shared.ts to add a guard or throw a clear error when
escrowDeployments[escrowDeployment] is undefined before accessing its
properties.

};

deploy.tags = ["EscrowCustomBuyer"];
deploy.skip = async ({ network }) => {
return isSkipped(network, !HomeChains[network.config.chainId ?? 0]);
};

export default deploy;
15 changes: 15 additions & 0 deletions contracts/deploy/00-escrow-universal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { HomeChains, isSkipped } from "./utils";
import deployEscrow from "./shared";

const deploy: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
await deployEscrow(hre, "universal");
};

deploy.tags = ["EscrowUniversal"];
deploy.skip = async ({ network }) => {
return isSkipped(network, !HomeChains[network.config.chainId ?? 0]);
};

export default deploy;
67 changes: 52 additions & 15 deletions contracts/deploy/00-escrow.ts → contracts/deploy/shared.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,54 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeployFunction } from "hardhat-deploy/types";
import { HomeChains, isSkipped } from "./utils";
import { HomeChains } from "./utils";
import { EscrowUniversal } from "../typechain-types";
import { getArbitratorContracts } from "./utils/getContracts";

const config = {
export type EscrowDeployment = {
escrow: string;
view: string;
};

export type EscrowDeployments = {
universal: EscrowDeployment;
customBuyer?: EscrowDeployment;
};

export const config = {
arbitrumSepoliaDevnet: {
feeTimeout: 600, // 10 minutes
settlementTimeout: 600, // 10 minutes
jurors: 1,
courtId: 1,
escrowDeployments: {
universal: {
escrow: "EscrowUniversal",
view: "EscrowView",
},
customBuyer: {
escrow: "EscrowCustomBuyer",
view: "EscrowViewCustomBuyer",
},
} satisfies EscrowDeployments,
},
arbitrum: {
feeTimeout: 302400, // 84 hours
settlementTimeout: 172800, // 48 hours
jurors: 3,
courtId: 1,
escrowDeployments: {
universal: {
escrow: "EscrowUniversal",
view: "EscrowView",
},
customBuyer: undefined,
} satisfies EscrowDeployments,
},
};

const deploy: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
const deployEscrow = async (
hre: HardhatRuntimeEnvironment,
escrowDeployment: keyof EscrowDeployments
) => {
const { deployments, getNamedAccounts, getChainId, ethers, network } = hre;
const { deploy } = deployments;

Expand All @@ -29,10 +58,10 @@ const deploy: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
console.log("deploying to %s with deployer %s", HomeChains[chainId], deployer);

const { disputeTemplateRegistry, klerosCore } = await getArbitratorContracts(hre);
const { feeTimeout, settlementTimeout, jurors, courtId } = config[network.name];
const { feeTimeout, settlementTimeout, jurors, courtId, escrowDeployments } = config[network.name];
const extraData = ethers.AbiCoder.defaultAbiCoder().encode(["uint96", "uint96"], [courtId, jurors]);

await deploy("EscrowUniversal", {
await deploy(escrowDeployments[escrowDeployment].escrow, {
from: deployer,
args: [
klerosCore.target,
Expand All @@ -47,30 +76,38 @@ const deploy: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
});

// Set the value cap to about USD 1000
const escrow = (await ethers.getContract("EscrowUniversal")) as EscrowUniversal;
const escrow = (await ethers.getContract(escrowDeployments[escrowDeployment].escrow)) as EscrowUniversal;
const WETH = await deployments.get("WETH");
const DAI = await deployments.get("DAI");
const PNK = await deployments.getOrNull("PNK");
const USDC = await deployments.getOrNull("USDC");
const USDCe = await deployments.getOrNull("USDCe"); // USDC.e (Bridged USDC)
const caps = {
[ethers.ZeroAddress]: ethers.parseUnits("0.3"),
[WETH.address]: ethers.parseUnits("0.3"),
[DAI.address]: ethers.parseUnits("1000"),
};
if (PNK) {
caps[PNK.address] = ethers.parseUnits("100000"); // 100,000 PNK
}
if (USDC) {
caps[USDC.address] = ethers.parseUnits("1000", 6);
}
if (USDCe) {
caps[USDCe.address] = ethers.parseUnits("1000", 6);
}
for (const [token, cap] of Object.entries(caps)) {
console.log("Setting cap for", token, cap);
await escrow.changeAmountCap(token, cap);
}

await deploy("EscrowView", {
await deploy(escrowDeployments[escrowDeployment].view, {
contract: "EscrowView",
from: deployer,
args: [escrow.target],
gasLimit: 50000000,
gasLimit: 30000000,
log: true,
});
};

deploy.tags = ["Escrow"];
deploy.skip = async ({ network }) => {
return isSkipped(network, !HomeChains[network.config.chainId ?? 0]);
};

export default deploy;
export default deployEscrow;
6 changes: 4 additions & 2 deletions contracts/deploy/utils/getContracts.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { DeploymentName, getContractsEthers as _getArbitratorContracts } from "@kleros/kleros-v2-contracts";
import { EscrowView, EscrowUniversal } from "../../typechain-types";
import { EscrowView, EscrowUniversal, EscrowCustomBuyer } from "../../typechain-types";

const NETWORK_TO_DEPLOYMENT: Record<string, DeploymentName> = {
arbitrumSepoliaDevnet: "devnet",
Expand All @@ -24,5 +24,7 @@ export const getContracts = async (hre: HardhatRuntimeEnvironment) => {
const { klerosCore, disputeTemplateRegistry } = await getArbitratorContracts(hre);
const escrow = await ethers.getContract<EscrowUniversal>("EscrowUniversal");
const view = await ethers.getContract<EscrowView>("EscrowView");
return { escrow, view, disputeTemplateRegistry, klerosCore };
const escrowCustomBuyer = await ethers.getContract<EscrowCustomBuyer>("EscrowCustomBuyer");
const customBuyerView = await ethers.getContract<EscrowView>("EscrowViewCustomBuyer");
return { escrow, view, escrowCustomBuyer, customBuyerView, disputeTemplateRegistry, klerosCore };
};
Loading