Skip to content

Commit

Permalink
Add escapetest project (#420)
Browse files Browse the repository at this point in the history
* Add escapetest project with hardhat forking

* Rename escapetest package to testescape

* Trigger the freeze in local fork

* Fix merkle proof for perpetuals

* Update escapetest with failure scenario

* Test performin escape()

* Verify that withdrawal is allowed after escape.

* Make sure funds can be withdrawn to user

* Add comments

* Add comments

* Validate freeze grace period

* Add yarn startfork and console

* Add mineGracePeriod to utils

* Add util functions

* after merge fix

* remove state changes

* remove backend changes

* cleanup

* add margin to tutorial page

* if no metamask delete all accounts from local storage

* improve utils

* fix constructor

* Update yarn.lock

* add spinner to buttons

* adjust style

* fix linter

* format fix

* add sql script to readme

* add get balance of to utils

* improve configs

* change name of package

* add readme

* fork adjustments

* add reference to escape hatch test

* add comments to test to make it more verbose

* exclude package and lock versions of contracts

* change yarn lock

* fix linter issues

* revert vscode changes

* format fix

---------

Co-authored-by: Tomasz Tórz <[email protected]>
  • Loading branch information
adamiak and torztomasz authored Sep 12, 2024
1 parent f0f06b5 commit a7805be
Show file tree
Hide file tree
Showing 39 changed files with 5,847 additions and 88 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This repository is a monorepo consisting of five projects:
- `packages/crypto`
- `packages/encoding`
- `packages/testnet` - [README.md](./packages/testnet/README.md)
- `packages/escape-hatch-test` - [README.md](./packages/test-hatch-testnet/README.md)

## Setup

Expand Down
9 changes: 8 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@
},
"workspaces": {
"packages": [
"packages/*"
"packages/backend",
"packages/crypto",
"packages/encoding",
"packages/frontend",
"packages/shared",
"packages/state",
"packages/testnet",
"packages/types"
]
},
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions packages/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"test": "mocha",
"test:watch": "mocha --watch --watch-files src/**/*.ts,test/**/*.ts",
"start": "node -r source-map-support/register build",
"start:fork": "HARDHAT_FORK=true yarn start",
"dev": "node -r esbuild-register src"
},
"dependencies": {
Expand Down
14 changes: 13 additions & 1 deletion packages/backend/src/config/environments/config.local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { Config } from '../Config'
import { getStarkexConfig } from '../starkex'

export function getLocalConfig(env: Env): Config {
const starkexConfig = getStarkexConfig(env)
const isHardhatFork = env.optionalBoolean('HARDHAT_FORK')

return {
name: 'StarkexExplorer/Local',
logger: {
Expand All @@ -18,6 +21,15 @@ export function getLocalConfig(env: Env): Config {
enablePreprocessing: env.boolean('ENABLE_PREPROCESSING', true),
freshStart: env.boolean('FRESH_START', false),
forceHttps: false,
starkex: getStarkexConfig(env),
starkex: {
...starkexConfig,
blockchain: {
...starkexConfig.blockchain,
chainId: isHardhatFork ? 31337 : starkexConfig.blockchain.chainId,
jsonRpcUrl: isHardhatFork
? 'http://localhost:8545'
: starkexConfig.blockchain.jsonRpcUrl,
},
},
}
}
3 changes: 3 additions & 0 deletions packages/escape-hatch-test/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
PERPETUAL_ADDRESS=
ESCAPE_VERIFIER_ADDRESS=
JSON_RPC_URL=
1 change: 1 addition & 0 deletions packages/escape-hatch-test/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('../../.eslintrc.json')
3 changes: 3 additions & 0 deletions packages/escape-hatch-test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Hardhat files
cache
artifacts
8 changes: 8 additions & 0 deletions packages/escape-hatch-test/.mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"spec": "{src,test}/**/*.test.ts",
"require": ["esbuild-register"],
"watchExtensions": "ts",
"extension": "ts",
"file": "src/test/setup.ts",
"reporterOption": "maxDiffSize=0"
}
5 changes: 5 additions & 0 deletions packages/escape-hatch-test/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
build
.cache
.nyc_output
coverage
6 changes: 6 additions & 0 deletions packages/escape-hatch-test/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"semi": false,
"singleQuote": true,
"printWidth": 80,
"bracketSpacing": true
}
116 changes: 116 additions & 0 deletions packages/escape-hatch-test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Escape Hatch Test

## Scripts

- `yarn test` - run automated tests
- `yarn startfork BLOCK_NUMBER` - start a local Ethereum node with a forked mainnet at a specific block
- `yarn console` - connect to a local forked network, can be used to run arbitary commands on the node (see `packages/escape-hatch-test/src/utils.ts` for all available commands)

## Setup

```bash
yarn install
yarn build
```

## Where to find exchange addresses?
Check out all config files in `packages/backend/src/config/starkex` directory for all needed addresses.

## Environment variables

```bash
PERPETUAL_ADDRESS=
ESCAPE_VERIFIER_ADDRESS=
JSON_RPC_URL=
```
`ESCAPE_VERIFIER_ADDRESS` is only needed for automated testing.

## Automated test

Simply run `yarn test-escape` to run the test.

## Manual testing with local explorer

> [!IMPORTANT]
> To test it manually you need to have some funds to escape with on the chosen exchange.

1. Check latest block number synced with explorer:
```sql
select max(number) from blocks;
```

2. Start hardhat node with a forked mainnet at the block number from the previous step:
```bash
yarn startfork BLOCK_NUMBER
```

3. Connect to the hardhat node console:
```bash
yarn console
```

4. Go to Metamask, switch to the forked network:
```
Network name: Hardhat Fork
RPC URL: http://localhost:8545
Chain ID: 31337
Currency symbol: ETH
```

5. Open terminal with hardhat console and give yourself some ETH to test everything:
```bash
await utils.impersonateAccount(ETHEREUM_ADDRESS)
await utils.setBalanceOf(ETHEREUM_ADDRESS, ETH_AMOUNT)
```

6. Run local explorer:
- Go to `packages/backend`
- Run `yarn start:fork`
- Open `http://localhost:3000` in your browser

7. Right now the explorer should be connected to the forked network. So let's freeze the exchange.

7.1. Using the UI
- Go to the user page and submit a forced withdrawal
- Go to the console and run
```bash
await utils.mineGracePeriod()
```
- It mines 14 days into the future - after this period of not including the withdrawal in the state the exchange can be frozen.
- After refresh you should see that the exchange is freezable.
- Freeze the exchange by clicking the "Freeze" button.
- After refresh you should see that the exchange is frozen.

7.2. Using the console
- Run
```bash
await utils.triggerFreezable()
```
- After you refresh the page you should see that the exchange is freezable. You can freeze by:
```bash
await utils.freeze()
```
- After you refresh the page you should see that the exchange is frozen.

8. Go to your user page and start escaping.



>[!CAUTION]
> Make sure to reset the explorer to a specific block number when you are done with testing.
```sql
BEGIN;
delete from blocks where number > ${blockNumber};
delete from withdrawable_assets where block_number > ${blockNumber};
delete from user_transactions where block_number > ${blockNumber};
delete from transaction_status where block_number > ${blockNumber};
delete from state_updates where block_number > ${blockNumber};
delete from state_transitions where block_number > ${blockNumber};
delete from preprocessed_user_statistics where block_number > ${blockNumber};
delete from preprocessed_state_details where block_number > ${blockNumber};
delete from sent_transactions where sent_transactions.mined_block_number > ${blockNumber} OR sent_transactions.mined_block_number IS NULL;
update key_values SET value = ${blockNumber} where key = 'lastBlockNumberSynced';
update key_values SET value = 'not-frozen' where key = 'freezeStatus';
COMMIT;
```
28 changes: 28 additions & 0 deletions packages/escape-hatch-test/hardhat.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import '@nomicfoundation/hardhat-toolbox'

import { getEnv } from '@l2beat/backend-tools'
import { extendEnvironment, HardhatUserConfig } from 'hardhat/config'

import { HardhatUtils } from './src/utils'

const env = getEnv()

const config: HardhatUserConfig = {
solidity: '0.8.18',
networks: {
hardhat: {
accounts: [],
forking: {
url: env.string('JSON_RPC_URL'),
},
},
},
}

extendEnvironment((hre) => {
const provider = new hre.ethers.providers.JsonRpcProvider()
// @ts-expect-error
hre.utils = new HardhatUtils(provider, env.string('PERPETUAL_ADDRESS'))
})

export default config
33 changes: 33 additions & 0 deletions packages/escape-hatch-test/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@explorer/escape-hatch-test",
"version": "0.1.0",
"private": true,
"engines": {
"node": "^16.0.0",
"yarn": ">=1.22.0"
},
"scripts": {
"test-escape": "npx hardhat test",
"startfork": "env-cmd -f ./.env scripts/startfork.sh",
"console": "npx hardhat console --network localhost"
},
"dependencies": {
"@l2beat/backend-tools": "^0.3.0",
"env-cmd": "10.1.0"
},
"devDependencies": {
"@nomicfoundation/hardhat-chai-matchers": "2.0.0",
"@nomicfoundation/hardhat-ethers": "3.0.0",
"@nomicfoundation/hardhat-network-helpers": "1.0.11",
"@nomicfoundation/hardhat-toolbox": "3.0.0",
"@nomicfoundation/hardhat-verify": "1.0.0",
"@typechain/ethers-v6": "0.4.0",
"@typechain/hardhat": "8.0.0",
"@types/chai": "4.2.0",
"chai": "4.2.0",
"hardhat": "2.16.1",
"hardhat-gas-reporter": "1.0.8",
"solidity-coverage": "0.8.1",
"ts-node": "10.9.2"
}
}
24 changes: 24 additions & 0 deletions packages/escape-hatch-test/scripts/startfork.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash
# ------------------------------------------------------------------
# Starts a local hardhat node that forks mainnet from the specified block number
# ------------------------------------------------------------------

# Make sure that the JSON_RPC_URL environment variable is set
if [ -z "$JSON_RPC_URL" ]
then
echo ""
echo "Please set the JSON_RPC_URL environment variable"
echo ""
exit 1
fi

# Make sure that at least one parameter (fork block number) is passed in
if [ $# -eq 0 ]
then
echo ""
echo "Please provide a parameter for the fork block number"
echo ""
exit 1
fi

npx hardhat node --fork-block-number $1
Loading

0 comments on commit a7805be

Please sign in to comment.