Skip to content
Open
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
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export/
typechain/
19 changes: 18 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,22 @@
},
"rules": {
"new-cap": "off"
}
},
"overrides": [
{
"files": ["*.ts"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"extends": ["plugin:@typescript-eslint/recommended"],
"rules": {
"@typescript-eslint/no-floating-promises": [
"error",
{ "ignoreVoid": false }
],
"@typescript-eslint/no-misused-promises": "error"
}
}
]
}
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ deployments/
docgen-templates/
export/
export.json
typechain/
17 changes: 15 additions & 2 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,29 @@ Once packages are installed, you can build the smart contracts using:
```
yarn build
```
Compiled contracts will land in the `build` directory.
Compiled contracts will land in the `build` directory. The build also generates
ethers v5 contract types in `typechain`; these files should not be edited or
committed.

=== Test contracts

There are multiple test scenarios living in the `test` directory.
The tests in the `test` directory use TypeScript and generated contract types.
You can run them by doing:
```
yarn test
```

To regenerate contract types and check the tests, deployment scripts, tasks, and
Hardhat configuration with strict TypeScript settings, run:
```
yarn typecheck
```

`yarn format` runs type checking, linting, and formatting checks in CI. Linting
also rejects unhandled promises, so asynchronous setup and contract calls must
be awaited or returned. The package continues to export JavaScript deployment
scripts; tests and generated contract types are not published.

=== Deploy contracts

To deploy all contracts on the given network, please run:
Expand Down
2 changes: 1 addition & 1 deletion deploy/02_mint_t.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { execute, read, log } = deployments
const { to1e18, from1e18 } = helpers.number

const T = await deployments.get("T")
await deployments.get("T")

const totalSupply: BigNumber = await read("T", "totalSupply")

Expand Down
15 changes: 6 additions & 9 deletions deploy/07_deploy_token_staking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HardhatRuntimeEnvironment } from "hardhat/types"
import { DeployFunction } from "hardhat-deploy/types"

import { ethers, upgrades } from "hardhat"
import * as fs from "fs"

const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { getNamedAccounts, deployments } = hre
Expand All @@ -11,7 +12,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const T = await deployments.get("T")

const tokenStakingConstructorArgs = [T.address]
const tokenStakingInitializerArgs = []
const tokenStakingInitializerArgs: [] = []

// TODO: Consider upgradable deployment also for sepolia.
let tokenStakingAddress
Expand All @@ -29,22 +30,18 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
log(`Deployed TokenStaking with TransparentProxy at ${tokenStakingAddress}`)

const implementationInterface = tokenStaking.interface
let jsonAbi = implementationInterface.format(ethers.utils.FormatTypes.json)
const jsonAbi = implementationInterface.format(
ethers.utils.FormatTypes.json
)

const tokenStakingDeployment = {
address: tokenStakingAddress,
abi: JSON.parse(jsonAbi as string),
}
const fs = require("fs")
fs.writeFileSync(
"TokenStaking.json",
JSON.stringify(tokenStakingDeployment, null, 2),
"utf8",
function (err) {
if (err) {
console.log(err)
}
}
"utf8"
)
log(`Saved TokenStaking address and ABI in TokenStaking.json`)
} else {
Expand Down
2 changes: 1 addition & 1 deletion deploy/30_deploy_tokenholder_timelock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { getNamedAccounts, deployments } = hre
const { deployer } = await getNamedAccounts()

const proposers = []
const proposers: string[] = []
const executors = [ethers.constants.AddressZero]
const minDelay = 172800 // 2 days in seconds (2 * 24 * 60 * 60)

Expand Down
2 changes: 1 addition & 1 deletion deploy/31_deploy_tokenholder_governor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deployer, thresholdCouncil } = await getNamedAccounts()

// TODO: fail if thresholdCouncil is undefined on mainnet
let vetoer = thresholdCouncil ?? deployer
const vetoer = thresholdCouncil ?? deployer

const T = await deployments.get("T")
const TokenStaking = await deployments.get("TokenStaking")
Expand Down
8 changes: 7 additions & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import "@nomiclabs/hardhat-ethers"
import "@nomicfoundation/hardhat-chai-matchers"
import "@openzeppelin/hardhat-upgrades"
import "@nomicfoundation/hardhat-verify"
import "@typechain/hardhat"
import { Tenderly } from "@tenderly/hardhat-tenderly/dist/Tenderly"
import "@tenderly/hardhat-tenderly/dist/type-extensions"

Expand Down Expand Up @@ -43,6 +44,11 @@ const config: HardhatUserConfig = {
paths: {
artifacts: "./build",
},
typechain: {
outDir: "typechain",
target: "ethers-v5",
alwaysGenerateOverloads: true,
},
networks: {
hardhat: {
forking: {
Expand All @@ -68,7 +74,7 @@ const config: HardhatUserConfig = {
accounts: process.env.CONTRACT_OWNER_ACCOUNT_PRIVATE_KEY
? [
process.env.CONTRACT_OWNER_ACCOUNT_PRIVATE_KEY,
process.env.KEEP_CONTRACT_OWNER_ACCOUNT_PRIVATE_KEY, // TODO: verify if we have different owner here or can we remove this
process.env.KEEP_CONTRACT_OWNER_ACCOUNT_PRIVATE_KEY!, // TODO: verify if we have different owner here or can we remove this
]
: undefined,
tags: ["tenderly"],
Expand Down
19 changes: 13 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@
"format:fix": "npm run lint:fix && prettier --write .",
"lint": "npm run typecheck && npm run lint:js && npm run lint:sol",
"lint:fix": "npm run lint:fix:js && npm run lint:fix:sol",
"lint:fix:js": "eslint . --fix",
"lint:fix:js": "eslint . --ext .js,.ts --fix",
"lint:fix:sol": "solhint 'contracts/**/*.sol' --fix",
"lint:js": "eslint . ",
"lint:js": "eslint . --ext .js,.ts",
"lint:sol": "solhint 'contracts/**/*.sol'",
"test": "hardhat test",
"test:system": "NODE_ENV=system-test hardhat test ./test/system/*.test.js",
"typecheck": "tsc --noEmit -p tsconfig.json",
"prepack": "tsc -p tsconfig.export.json && hardhat export-artifacts export/artifacts",
"test:system": "NODE_ENV=system-test hardhat test ./test/system/*.test.ts",
"typecheck": "hardhat typechain && tsc --noEmit -p tsconfig.json",
"prepack": "hardhat typechain && tsc -p tsconfig.export.json && hardhat export-artifacts export/artifacts",
"prepublishOnly": "rm -rf artifacts/ && hardhat export-deployment-artifacts --network $npm_config_network"
},
"devDependencies": {
Expand All @@ -39,11 +39,17 @@
"@nomiclabs/hardhat-ethers": "^2.2.3",
"@openzeppelin/hardhat-upgrades": "^1.28.0",
"@tenderly/hardhat-tenderly": "1.8.0",
"@typechain/ethers-v5": "10.2.1",
"@typechain/hardhat": "6.1.6",
"@types/chai": "^4.3.20",
"@types/chai-as-promised": "7.1.8",
"@types/debug": "4.1.12",
"@types/mocha": "^10.0.10",
"@types/node": "^22.20.1",
"@typescript-eslint/eslint-plugin": "8.70.0",
"@typescript-eslint/parser": "8.70.0",
"chai": "^4.5.0",
"eslint": "^7.32.0",
"eslint": "8.57.1",
"eslint-config-keep": "github:keep-network/eslint-config-keep#0c27ade",
"ethers": "^5.8.0",
"hardhat": "^2.29.0",
Expand All @@ -57,6 +63,7 @@
"solhint-config-keep": "github:keep-network/solhint-config-keep",
"solidity-docgen": "^0.6.0-beta.36",
"ts-node": "^10.9.2",
"typechain": "8.3.2",
"typescript": "^5.9.3"
},
"dependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
const { expect } = require("chai")
import type { ContractTransaction } from "ethers"
import type { TestGovernorParameters } from "../../typechain"
import type { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"
import { ethers } from "hardhat"
import { expect } from "chai"

describe("ParametersGovernor", () => {
let executor
let other
let tGov: TestGovernorParameters
let executor: SignerWithAddress
let other: SignerWithAddress

beforeEach(async () => {
;[executor, other] = await ethers.getSigners()
Expand Down Expand Up @@ -37,10 +42,10 @@ describe("ParametersGovernor", () => {
})

describe("parameters are updated", () => {
let tx1
let tx2
let tx3
let tx4
let tx1: ContractTransaction
let tx2: ContractTransaction
let tx3: ContractTransaction
let tx4: ContractTransaction
beforeEach(async () => {
tx1 = await tGov.connect(executor).updateQuorumNumerator(100)
tx2 = await tGov.connect(executor).updateProposalThresholdNumerator(200)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,33 @@
const { expect } = require("chai")

const { upgrades } = require("hardhat")
import type {
ProxyAdmin,
ProxyAdminWithDeputy,
SimpleStorage,
SimpleStorage__factory as SimpleStorageFactory,
TestTokenholderGovernorStubV2,
} from "../../typechain"
import type { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"
import { ethers, upgrades } from "hardhat"
import { expect } from "chai"

describe("ProxyAdminWithDeputy", () => {
let deployer
let deputy
let timelock
let adminWithDeputy

let SimpleStorage
let tGov: TestTokenholderGovernorStubV2
let storage: SimpleStorage
let deployer: SignerWithAddress
let deputy: SignerWithAddress
let timelock: SignerWithAddress
let adminWithDeputy: ProxyAdminWithDeputy

let SimpleStorage: SimpleStorageFactory
const initialState = 42

beforeEach(async () => {
;[deployer, deputy, timelock] = await ethers.getSigners()
SimpleStorage = await ethers.getContractFactory("SimpleStorage")
const initializerArgs = [initialState] // stored value in proxy state
storage = await upgrades.deployProxy(SimpleStorage, initializerArgs, {
storage = (await upgrades.deployProxy(SimpleStorage, initializerArgs, {
kind: "transparent",
constructorArgs: [1], // implementation version 1
})
})) as SimpleStorage
await storage.deployed()

const GovernorStub = await ethers.getContractFactory(
Expand All @@ -38,18 +47,21 @@ describe("ProxyAdminWithDeputy", () => {
})

describe("Plain Upgrades deployment - No ProxyAdminWithDeputy", () => {
let newImplementationAddress
let adminInstance
let newImplementationAddress: string
let adminInstance: ProxyAdmin

beforeEach(async () => {
newImplementationAddress = await upgrades.prepareUpgrade(
const implementation = await upgrades.prepareUpgrade(
storage.address,
SimpleStorage,
{
constructorArgs: [2],
}
)
adminInstance = await upgrades.admin.getInstance()
if (typeof implementation !== "string")
throw new Error("Expected implementation address")
newImplementationAddress = implementation
adminInstance = (await upgrades.admin.getInstance()) as ProxyAdmin
})

it("ProxyAdmin is the admin for the UpgradeableProxy", async () => {
Expand Down Expand Up @@ -98,16 +110,19 @@ describe("ProxyAdminWithDeputy", () => {
})

describe("Upgrades procedure with ProxyAdminWithDeputy", () => {
let newImplementationAddress
let newImplementationAddress: string

beforeEach(async () => {
newImplementationAddress = await upgrades.prepareUpgrade(
const implementation = await upgrades.prepareUpgrade(
storage.address,
SimpleStorage,
{
constructorArgs: [2],
}
)
if (typeof implementation !== "string")
throw new Error("Expected implementation address")
newImplementationAddress = implementation
})

it("before upgrade, implementation version is 1", async () => {
Expand Down
Loading
Loading