Skip to content
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

npm package support #7

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ test/contracts/*.json
# Hardhat files
cache
artifacts
deployments/localhost
typechain
deployments/localhost
coverage.json
coverage
*.log
Expand Down
1 change: 1 addition & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"semi": false,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "all",
"overrides": [
{
Expand Down
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,31 @@

This repository contains the core smart contracts for Vanilla. For documentation, see [the technical overview](contracts/README.md) of the contracts.

## Install PNPM
## Install Yarn

We use [pnpm](https://pnpm.io/) instead of npm. Use npm to install pnpm:
We use [Yarn](https://yarnpkg.com/) instead of npm.

```shell
npm install -g pnpm
curl --compressed -o- -L https://yarnpkg.com/install.sh | bash
```

## Build and Test

We use [Hardhat](https://hardhat.org/) as a build tool.

To build, generate Typechain bindings, and run model tests:
On first `yarn install` the typechain generation will fail, as the contracts aren't built on `postinstall`. Just run

To build, `yarn install`, build contracts with `yarn run compile:sol`, generate Typechain bindings with `yarn run generate:typechain`, and run model tests:
```
pnpm install
pnpm run compile:sol
pnpm run generate:typechain
pnpm test
yarn install
yarn run compile:sol
yarn run generate:typechain
yarn test
```

To run coverage reports
```
pnpm run coverage:sol
yarn run coverage:sol
```

## Lint and reformat
Expand All @@ -33,14 +35,14 @@ We use [ESLint](https://eslint.org/) for JS/TS code and [Prettier](https://prett

To run lint checks:
```
pnpm run lint:js
pnpm run lint:sol
yarn run lint:js
yarn run lint:sol
```

To reformat / prettify:
```
pnpm run format:js
pnpm run format:sol
yarn run format:js
yarn run format:sol
```

## Deployment
Expand Down
46 changes: 35 additions & 11 deletions deploy/007-DeployVanillaV1Router02.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
/* eslint-disable camelcase */
import { HardhatRuntimeEnvironment } from "hardhat/types"
import { DeployFunction } from "hardhat-deploy/dist/types"
import { HardhatRuntimeEnvironment } from "hardhat/types"
import {
VanillaV1MigrationState__factory,
VanillaV1Router02__factory,
VanillaV1Safelist01__factory,
} from "../typechain/vanilla_v1.1"
import { SafeLedgerSigner } from "../utils/SafeLedgerSigner.util"
import { connectUsing } from "../utils/DeploymentTools"
import { SafeLedgerSigner } from "../utils/SafeLedgerSigner.util"

const func: DeployFunction = async function ({ ethers, deployments, network }: HardhatRuntimeEnvironment) {
const func: DeployFunction = async function ({
ethers,
deployments,
network,
}: HardhatRuntimeEnvironment) {
const { getOrNull, get, save } = deployments

const connect = connectUsing(ethers.provider)
Expand All @@ -20,15 +24,23 @@ const func: DeployFunction = async function ({ ethers, deployments, network }: H

let receipt
if (network.name === "localhost" || network.name === "hardhat") {
let signer = await ethers.getNamedSigner("deployer")
let contractDeployment = new VanillaV1Router02__factory(signer).getDeployTransaction(peripheryState, v1)
let signer = (await ethers.getSigners())[0]
let contractDeployment = new VanillaV1Router02__factory(
signer,
).getDeployTransaction(peripheryState, v1)
let pendingTransaction = await signer.sendTransaction(contractDeployment)
receipt = await pendingTransaction.wait()
} else {
let safeSigner = await SafeLedgerSigner(ethers.provider, network)
let contractDeployment = new VanillaV1Router02__factory(safeSigner).getDeployTransaction(peripheryState, v1)
console.log("Deploying VanillaV1Router02 - sign the transaction in Ledger")
let pendingTransaction = await safeSigner.sendTransaction(contractDeployment)
let contractDeployment = new VanillaV1Router02__factory(
safeSigner,
).getDeployTransaction(peripheryState, v1)
console.log(
"Deploying VanillaV1Router02 - sign the transaction in Ledger",
)
let pendingTransaction = await safeSigner.sendTransaction(
contractDeployment,
)
console.log("Deployment waiting in Safe for approval and execution")
receipt = await pendingTransaction.wait()
console.log("Deployment done", receipt)
Expand All @@ -43,7 +55,11 @@ const func: DeployFunction = async function ({ ethers, deployments, network }: H
let router = connect.router(address)
let [safeList, migrationState] = await Promise.all([
router.safeList().then(connect.safelist),
router.vnlContract().then(connect.vnlToken).then(vnl => vnl.migrationState()).then(connect.migrationState),
router
.vnlContract()
.then(connect.vnlToken)
.then((vnl) => vnl.migrationState())
.then(connect.migrationState),
])
await save("VanillaV1Safelist01", {
abi: VanillaV1Safelist01__factory.abi,
Expand All @@ -53,10 +69,18 @@ const func: DeployFunction = async function ({ ethers, deployments, network }: H
abi: VanillaV1MigrationState__factory.abi,
address: migrationState.address,
})
console.log("Deployed contracts", { router: address, safelist: safeList.address, migrationState: migrationState.address })
console.log("Deployed contracts", {
router: address,
safelist: safeList.address,
migrationState: migrationState.address,
})
console.log(`Gas usage: ${receipt.gasUsed}`)
}
}
func.dependencies = ["UniswapV3SwapRouter", "VanillaV1Router01"]
func.tags = ["VanillaV1Router02", "VanillaV1Safelist01", "VanillaV1MigrationState"]
func.tags = [
"VanillaV1Router02",
"VanillaV1Safelist01",
"VanillaV1MigrationState",
]
export default func
9 changes: 4 additions & 5 deletions hardhat.base.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/* eslint-disable camelcase */
import { Networks } from "./network.config"
import { HardhatUserConfig } from "hardhat/config"

import "@nomiclabs/hardhat-ethers"
import "@nomiclabs/hardhat-etherscan"
import "@nomiclabs/hardhat-waffle"
import "@typechain/hardhat"
import "hardhat-deploy"
import "hardhat-deploy-ethers"
import "@typechain/hardhat"
import { HardhatUserConfig } from "hardhat/config"
import "solidity-coverage"
import "@nomiclabs/hardhat-etherscan"
import { Networks } from "./network.config"

let isMainnetFork = process.env.FORK === "mainnet"
let localChainId = isMainnetFork ? 1 : 31337
Expand Down
42 changes: 33 additions & 9 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,53 @@
/* eslint-disable camelcase */
import hardhatConfig from "./hardhat.base"
import { task } from "hardhat/config"
import hardhatConfig from "./hardhat.base"
import checkEpochAction from "./hardhat/CheckEpoch.action"
import listTestAccounts from "./hardhat/ListTestAccounts.action"
import checkMigrationEligibility from "./hardhat/CheckMigrationEligibility.action"
import checkReserves from "./hardhat/CheckUniV2Reserves.action"
import inspectSafelist from "./hardhat/InspectSafelist.action"
import checkMigrationEligibility from "./hardhat/CheckMigrationEligibility.action"
import listTestAccounts from "./hardhat/ListTestAccounts.action"
import testTrading from "./hardhat/TestTrading.action"
import updateMigrationState from "./hardhat/UpdateMigrationState.action"
import updateSafeList from "./hardhat/UpdateSafeList.action"

task("check-epoch", "Checks the epoch of the deployed VanillaRouter", checkEpochAction)
task(
"check-epoch",
"Checks the epoch of the deployed VanillaRouter",
checkEpochAction,
)

task("test-accounts", "Prints the list of test accounts", listTestAccounts)

task("reserve-check", "checks the Uniswap pair reserves in the network", checkReserves)
task(
"reserve-check",
"checks the Uniswap pair reserves in the network",
checkReserves,
)

task("inspect-safelist", "verifies the status of safelist token pools in Uni v3", inspectSafelist)
task(
"inspect-safelist",
"verifies the status of safelist token pools in Uni v3",
inspectSafelist,
)

task("migration-eligibility", "verifies the given address is eligible for migration")
task(
"migration-eligibility",
"verifies the given address is eligible for migration",
)
.addParam("account", "The account's address")
.setAction(checkMigrationEligibility)

task("trading-test", "executes buy- and sell- transactions in a test network", testTrading)
task(
"trading-test",
"executes buy- and sell- transactions in a test network",
testTrading,
)

task("update-migration-state", "updates Vanilla v1.1 migration state", updateMigrationState)
task(
"update-migration-state",
"updates Vanilla v1.1 migration state",
updateMigrationState,
)
task("update-safelist", "updates Vanilla v1.1 safelist", updateSafeList)

export default hardhatConfig
15 changes: 12 additions & 3 deletions hardhat/CheckEpoch.action.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import { HardhatRuntimeEnvironment } from "hardhat/types"

export default async (_: never, { network, ethers, artifacts, deployments }: HardhatRuntimeEnvironment): Promise<void> => {
export default async (
_: never,
{ network, ethers, artifacts, deployments }: HardhatRuntimeEnvironment,
): Promise<void> => {
const { get } = deployments
let { abi } = await artifacts.readArtifact("VanillaRouter")

try {
console.log(`Checking VanillaRouter deployment in '${network.name}':`)
let { address } = await get("VanillaRouter")
let router = new ethers.Contract(address, abi, await ethers.getNamedSigner("deployer"))
let router = new ethers.Contract(
address,
abi,
(await ethers.getSigners())[0],
)
let epoch = await router.epoch()
console.log(`VanillaRouter deployed in ${address}, at block ${epoch.toNumber()}`)
console.log(
`VanillaRouter deployed in ${address}, at block ${epoch.toNumber()}`,
)
} catch (e) {
console.error(e)
}
Expand Down
82 changes: 57 additions & 25 deletions hardhat/TestTrading.action.ts
Original file line number Diff line number Diff line change
@@ -1,57 +1,89 @@
/* eslint-disable camelcase */
import { HardhatRuntimeEnvironment } from "hardhat/types"
import { tokenAddress } from "../utils/safelists"
import Decimal from "decimal.js"
import { BigNumber, constants } from "ethers"
import { HardhatRuntimeEnvironment } from "hardhat/types"
import { VanillaV1Router02__factory } from "../typechain/vanilla_v1.1"
import { tokenAddress } from "../utils/safelists"

export default async (_:never, { ethers, deployments }: HardhatRuntimeEnvironment): Promise<void> => {
export default async (
_: never,
{ ethers, deployments }: HardhatRuntimeEnvironment,
): Promise<void> => {
const { get } = deployments
const deployer = await ethers.getNamedSigner("deployer")
const deployer = (await ethers.getSigners())[0]

let { address: router02 } = await get("VanillaV1Router02")

let vanilla = VanillaV1Router02__factory.connect(router02, ethers.provider)

let _10eth = BigNumber.from(10n * (10n ** 18n))
let _10eth = BigNumber.from(10n * 10n ** 18n)
let uniAddress = tokenAddress("UNI")
console.log("Executing UNI buy and sell", router02)
let allUni
{
let tx = await vanilla.connect(deployer).executePayable([vanilla.interface.encodeFunctionData("buy",
[{
token: uniAddress,
fee: 500,
numToken: 1,
numEth: _10eth,
blockTimeDeadline: constants.MaxUint256,
useWETH: false,
}])], { value: _10eth })
let tx = await vanilla.connect(deployer).executePayable(
[
vanilla.interface.encodeFunctionData("buy", [
{
token: uniAddress,
fee: 500,
numToken: 1,
numEth: _10eth,
blockTimeDeadline: constants.MaxUint256,
useWETH: false,
},
]),
],
{ value: _10eth },
)

let { gasUsed } = await tx.wait()
let { ethSum, tokenSum } = await vanilla.tokenPriceData(deployer.address, uniAddress)
let { ethSum, tokenSum } = await vanilla.tokenPriceData(
deployer.address,
uniAddress,
)
allUni = tokenSum
console.log("Buy successful", `owner=${deployer.address}`,
`ethSum=${new Decimal(ethSum.toHexString()).dividedBy(10 ** 18).toDecimalPlaces(4)}`,
`tokenSum=${new Decimal(tokenSum.toHexString()).dividedBy(10 ** 18).toDecimalPlaces(4)}`, `gasUsed=${gasUsed}`)
console.log(
"Buy successful",
`owner=${deployer.address}`,
`ethSum=${new Decimal(ethSum.toHexString())
.dividedBy(10 ** 18)
.toDecimalPlaces(4)}`,
`tokenSum=${new Decimal(tokenSum.toHexString())
.dividedBy(10 ** 18)
.toDecimalPlaces(4)}`,
`gasUsed=${gasUsed}`,
)
}

{
let tx = await vanilla.connect(deployer).executePayable([
vanilla.interface.encodeFunctionData("sell",
[{
vanilla.interface.encodeFunctionData("sell", [
{
token: uniAddress,
fee: 500,
numToken: allUni,
numEth: 1,
blockTimeDeadline: constants.MaxUint256,
useWETH: false,
}]),
},
]),
])
let { gasUsed } = await tx.wait()
let { ethSum, tokenSum } = await vanilla.tokenPriceData(deployer.address, uniAddress)
console.log("Sell successful", `owner=${deployer.address}`,
`ethSum=${new Decimal(ethSum.toHexString()).dividedBy(10 ** 18).toDecimalPlaces(4)}`,
`tokenSum=${new Decimal(tokenSum.toHexString()).dividedBy(10 ** 18).toDecimalPlaces(4)}`, `gasUsed=${gasUsed}`)
let { ethSum, tokenSum } = await vanilla.tokenPriceData(
deployer.address,
uniAddress,
)
console.log(
"Sell successful",
`owner=${deployer.address}`,
`ethSum=${new Decimal(ethSum.toHexString())
.dividedBy(10 ** 18)
.toDecimalPlaces(4)}`,
`tokenSum=${new Decimal(tokenSum.toHexString())
.dividedBy(10 ** 18)
.toDecimalPlaces(4)}`,
`gasUsed=${gasUsed}`,
)
}
}
Loading