Commit 0749d62c authored by Matthew Slipper's avatar Matthew Slipper Committed by GitHub

actor-tests: Bedrock actor tests (#3161)

* actor-tests: Bedrock actor tests

- Moves actors into their own package
- Minor updates to logging, etc.
- Adds Cloudbuild config so that we can get Docker images on every commit to Develop
- Updates Actors to support Bedrock

Currently supported actors:

- Deposits
- Contract deployments
- Simple sends

* doctoc only look at specs
parent 04a39a47
...@@ -282,7 +282,7 @@ jobs: ...@@ -282,7 +282,7 @@ jobs:
command: yarn install --production=false command: yarn install --production=false
- run: - run:
name: specs toc name: specs toc
command: yarn lint:specs:toc && git diff --exit-code command: yarn lint:specs:toc && git diff --exit-code ./specs
- run: - run:
name: markdown lint name: markdown lint
command: yarn lint:specs:check command: yarn lint:specs:check
...@@ -585,6 +585,12 @@ workflows: ...@@ -585,6 +585,12 @@ workflows:
- op-bindings-build: - op-bindings-build:
requires: requires:
- yarn-monorepo - yarn-monorepo
- js-lint-test:
name: actor-tests-tests
package_name: actor-tests
dependencies: "(core-utils|sdk)"
requires:
- yarn-monorepo
- js-lint-test: - js-lint-test:
name: contracts-governance-tests name: contracts-governance-tests
package_name: contracts-governance package_name: contracts-governance
......
...@@ -32,5 +32,14 @@ steps: ...@@ -32,5 +32,14 @@ steps:
- --cache=true - --cache=true
- --cache-ttl=48h - --cache-ttl=48h
waitFor: ['-'] waitFor: ['-']
- name: 'gcr.io/kaniko-project/executor:latest'
args:
- --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/actor-tests-bedrock:$_TAG
- --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/actor-tests-bedrock:$COMMIT_SHA
- --dockerfile=./ops/docker/Dockerfile.packages
- --target=actor-tests-bedrock
- --cache=true
- --cache-ttl=48h
waitFor: ['-']
options: options:
machineType: N1_HIGHCPU_32 machineType: N1_HIGHCPU_32
\ No newline at end of file
import { actor, run, setupActor } from './lib/convenience'
import { OptimismEnv } from '../test/shared/env'
actor('Chain reader', () => {
let env: OptimismEnv
setupActor(async () => {
env = await OptimismEnv.new()
})
run(async (b) => {
const blockNumber = await b.bench('get block number', () =>
env.l2Provider.getBlockNumber()
)
await b.bench('get random block', () =>
env.l2Provider.getBlock(Math.floor(blockNumber * Math.random()))
)
})
})
import { utils, Wallet, BigNumber } from 'ethers'
import { expect } from 'chai'
import { setupActor, setupRun, actor, run } from './lib/convenience'
import { OptimismEnv } from '../test/shared/env'
interface BenchContext {
l1Wallet: Wallet
l2Wallet: Wallet
}
const DEFAULT_TEST_GAS_L1 = 330_000
const DEFAULT_TEST_GAS_L2 = 1_300_000
actor('Funds depositor', () => {
let env: OptimismEnv
setupActor(async () => {
env = await OptimismEnv.new()
})
setupRun(async () => {
const wallet = Wallet.createRandom()
const tx = await env.l1Wallet.sendTransaction({
to: wallet.address,
value: utils.parseEther('0.01'),
})
await tx.wait()
return {
l1Wallet: wallet.connect(env.l1Wallet.provider),
l2Wallet: wallet.connect(env.l2Wallet.provider),
}
})
run(async (b, ctx: BenchContext) => {
const { l1Wallet, l2Wallet } = ctx
const balBefore = await l2Wallet.getBalance()
await b.bench('deposit', async () => {
await env.waitForXDomainTransaction(
env.messenger.contracts.l1.L1StandardBridge.connect(
l1Wallet
).depositETH(DEFAULT_TEST_GAS_L2, '0xFFFF', {
value: 0x42,
gasLimit: DEFAULT_TEST_GAS_L1,
})
)
})
// Converting BigNumber to hex string prevents chai from incorrectly considering inherited properties
// for strict equality - https://github.com/chaijs/chai/issues/948
expect(
(await l2Wallet.getBalance()).sub(balBefore).toString()
).to.deep.equal(BigNumber.from(0x42).toString())
})
})
import { utils, Wallet, Contract } from 'ethers'
import { expect } from 'chai'
import { actor, run, setupActor, setupRun } from './lib/convenience'
import { OptimismEnv } from '../test/shared/env'
import ERC721 from '../artifacts/contracts/NFT.sol/NFT.json'
interface Context {
wallet: Wallet
contract: Contract
}
actor('NFT claimer', () => {
let env: OptimismEnv
let contract: Contract
setupActor(async () => {
env = await OptimismEnv.new()
contract = new Contract(process.env.ERC_721_ADDRESS, ERC721.abi)
})
setupRun(async () => {
const wallet = Wallet.createRandom().connect(env.l2Wallet.provider)
const tx = await env.l2Wallet.sendTransaction({
to: wallet.address,
value: utils.parseEther('0.01'),
})
await tx.wait()
return {
wallet,
contract: contract.connect(wallet),
}
})
run(async (b, ctx: Context) => {
let receipt: any
await b.bench('mint', async () => {
const tx = await ctx.contract.give()
receipt = await tx.wait()
})
expect(receipt.events[0].event).to.equal('Transfer')
expect(receipt.events[0].args[1]).to.equal(ctx.wallet.address)
})
})
import { utils, Wallet } from 'ethers'
import { expect } from 'chai'
import { actor, setupRun, setupActor, run } from './lib/convenience'
import { OptimismEnv } from '../test/shared/env'
interface Context {
wallet: Wallet
}
actor('Value sender', () => {
let env: OptimismEnv
setupActor(async () => {
env = await OptimismEnv.new()
})
setupRun(async () => {
const wallet = Wallet.createRandom()
const tx = await env.l2Wallet.sendTransaction({
to: wallet.address,
value: utils.parseEther('0.01'),
})
await tx.wait()
return {
wallet: wallet.connect(env.l2Wallet.provider),
}
})
run(async (b, ctx: Context) => {
const randWallet = Wallet.createRandom().connect(env.l2Wallet.provider)
await b.bench('send funds', async () => {
const tx = await ctx.wallet.sendTransaction({
to: randWallet.address,
value: 0x42,
})
await tx.wait()
})
expect((await randWallet.getBalance()).toString()).to.deep.equal('66')
})
})
import { utils, Wallet, Contract } from 'ethers'
import { ethers } from 'hardhat'
import { expect } from 'chai'
import { actor, setupActor, run, setupRun } from './lib/convenience'
import { OptimismEnv } from '../test/shared/env'
interface Context {
wallet: Wallet
}
actor('Trie DoS accounts', () => {
let env: OptimismEnv
let contract: Contract
setupActor(async () => {
env = await OptimismEnv.new()
const factory = await ethers.getContractFactory('StateDOS', env.l2Wallet)
contract = await factory.deploy()
await contract.deployed()
})
setupRun(async () => {
const wallet = Wallet.createRandom()
const tx = await env.l2Wallet.sendTransaction({
to: wallet.address,
value: utils.parseEther('1'),
})
await tx.wait()
return {
wallet: wallet.connect(env.l2Wallet.provider),
}
})
run(async (b, ctx: Context) => {
await b.bench('DOS transactions', async () => {
const tx = await contract.connect(ctx.wallet).attack({
gasLimit: 9000000 + Math.floor(1000000 * Math.random()),
})
const receipt = await tx.wait()
// make sure that this was an actual transaction in a block
expect(receipt.blockNumber).to.be.gt(1)
expect(receipt.gasUsed.gte(8000000)).to.be.true
})
})
})
import { Contract, utils, Wallet } from 'ethers'
import { FeeAmount } from '@uniswap/v3-sdk'
import { abi as NFTABI } from '@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'
import { abi as RouterABI } from '@uniswap/v3-periphery/artifacts/contracts/SwapRouter.sol/SwapRouter.json'
import { actor, run, setupActor, setupRun } from './lib/convenience'
import { OptimismEnv } from '../test/shared/env'
import ERC20 from '../artifacts/contracts/ERC20.sol/ERC20.json'
interface Context {
contracts: { [name: string]: Contract }
wallet: Wallet
}
actor('Uniswap swapper', () => {
let env: OptimismEnv
let tokens: [Contract, Contract]
let contracts: { [name: string]: Contract }
setupActor(async () => {
env = await OptimismEnv.new()
contracts = {
positionManager: new Contract(
process.env.UNISWAP_POSITION_MANAGER_ADDRESS,
NFTABI
).connect(env.l2Wallet),
router: new Contract(
process.env.UNISWAP_ROUTER_ADDRESS,
RouterABI
).connect(env.l2Wallet),
}
tokens = [
new Contract(process.env.UNISWAP_TOKEN_0_ADDRESS, ERC20.abi).connect(
env.l2Wallet
),
new Contract(process.env.UNISWAP_TOKEN_1_ADDRESS, ERC20.abi).connect(
env.l2Wallet
),
]
tokens =
tokens[0].address.toLowerCase() < tokens[1].address.toLowerCase()
? [tokens[0], tokens[1]]
: [tokens[1], tokens[0]]
})
setupRun(async () => {
const wallet = Wallet.createRandom().connect(env.l2Provider)
const sendTx = await env.l2Wallet.sendTransaction({
to: wallet.address,
value: utils.parseEther('0.1'),
})
await sendTx.wait()
for (const token of tokens) {
let tx = await token.transfer(wallet.address, 1000000)
await tx.wait()
const boundToken = token.connect(wallet)
tx = await boundToken.approve(
contracts.positionManager.address,
1000000000
)
await tx.wait()
tx = await boundToken.approve(contracts.router.address, 1000000000)
await tx.wait()
}
return {
contracts: Object.entries(contracts).reduce((acc, [name, value]) => {
acc[name] = value.connect(wallet)
return acc
}, {}),
wallet,
}
})
run(async (b, ctx: Context) => {
await b.bench('swap', async () => {
const tx = await ctx.contracts.router.exactInputSingle(
{
tokenIn: tokens[0].address,
tokenOut: tokens[1].address,
fee: FeeAmount.MEDIUM,
recipient: ctx.wallet.address,
deadline: Date.now() * 2,
amountIn: Math.max(Math.floor(1000 * Math.random()), 100),
amountOutMinimum: 0,
sqrtPriceLimitX96: 0,
},
{
gasLimit: 10000000,
}
)
await tx.wait()
})
})
})
...@@ -48,10 +48,8 @@ ...@@ -48,10 +48,8 @@
"@uniswap/v3-core": "1.0.0", "@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "^1.0.1", "@uniswap/v3-periphery": "^1.0.1",
"@uniswap/v3-sdk": "^3.6.2", "@uniswap/v3-sdk": "^3.6.2",
"async-mutex": "^0.3.2",
"chai": "^4.3.4", "chai": "^4.3.4",
"chai-as-promised": "^7.1.1", "chai-as-promised": "^7.1.1",
"commander": "^8.3.0",
"dotenv": "^10.0.0", "dotenv": "^10.0.0",
"envalid": "^7.1.0", "envalid": "^7.1.0",
"eslint": "^7.27.0", "eslint": "^7.27.0",
...@@ -69,7 +67,6 @@ ...@@ -69,7 +67,6 @@
"lint-staged": "11.0.0", "lint-staged": "11.0.0",
"mocha": "^8.4.0", "mocha": "^8.4.0",
"node-fetch": "^2.6.7", "node-fetch": "^2.6.7",
"prom-client": "^14.0.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"typescript": "^4.3.5", "typescript": "^4.3.5",
"uniswap-v3-deploy-plugin": "^0.1.0" "uniswap-v3-deploy-plugin": "^0.1.0"
......
...@@ -35,6 +35,7 @@ COPY --from=foundry /usr/local/bin/cast /usr/local/bin/cast ...@@ -35,6 +35,7 @@ COPY --from=foundry /usr/local/bin/cast /usr/local/bin/cast
WORKDIR /opt/optimism WORKDIR /opt/optimism
COPY *.json yarn.lock ./ COPY *.json yarn.lock ./
COPY packages/sdk/package.json ./packages/sdk/package.json COPY packages/sdk/package.json ./packages/sdk/package.json
COPY packages/actor-tests/package.json ./packages/actor-tests/package.json
COPY packages/core-utils/package.json ./packages/core-utils/package.json COPY packages/core-utils/package.json ./packages/core-utils/package.json
COPY packages/common-ts/package.json ./packages/common-ts/package.json COPY packages/common-ts/package.json ./packages/common-ts/package.json
COPY packages/contracts/package.json ./packages/contracts/package.json COPY packages/contracts/package.json ./packages/contracts/package.json
...@@ -57,6 +58,9 @@ COPY ./integration-tests ./integration-tests ...@@ -57,6 +58,9 @@ COPY ./integration-tests ./integration-tests
# build it! # build it!
RUN yarn build RUN yarn build
FROM base as actor-tests-bedrock
WORKDIR /opt/optimism/packages/actor-tests
ENTRYPOINT ["yarn", "run:bedrock"]
FROM base as deployer FROM base as deployer
WORKDIR /opt/optimism/packages/contracts WORKDIR /opt/optimism/packages/contracts
......
ignores: [
"typescript"
]
module.exports = {
extends: '../../.eslintrc.js',
}
module.exports = {
...require('../../.prettierrc.js'),
}
(The MIT License)
Copyright 2020-2021 Optimism
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import { Wallet, utils } from 'ethers'
import { expect } from 'chai'
import { actor, setupActor, run, setupRun } from '../lib/convenience'
import { devWalletsL2 } from './utils'
interface Context {
wallet: Wallet
}
actor('Sender', () => {
let sourceWallet: Wallet
let destWallet: Wallet
setupActor(async () => {
const devWallets = devWalletsL2()
sourceWallet = devWallets[0]
destWallet = devWallets[1]
})
setupRun(async () => {
const newWallet = Wallet.createRandom().connect(sourceWallet.provider)
const tx = await sourceWallet.sendTransaction({
to: newWallet.address,
value: utils.parseEther('0.1'),
})
await tx.wait()
return {
wallet: newWallet,
}
})
run(async (b, ctx: Context, logger) => {
const { wallet } = ctx
logger.log(`Sending funds to ${destWallet.address}.`)
const tx = await wallet.sendTransaction({
to: destWallet.address,
value: 0x42,
})
logger.log(`Awaiting receipt for send tx ${tx.hash}.`)
const receipt = await tx.wait()
expect(receipt.status).to.eq(1)
logger.log(`Send completed in block ${receipt.blockNumber}.`)
})
})
This diff is collapsed.
import { Wallet, ContractFactory } from 'ethers'
import { actor, setupActor, run } from '../lib/convenience'
import { devWalletsL2 } from './utils'
import * as ERC20 from './contracts/ERC20.json'
actor('Deployer', () => {
let wallets: Wallet[]
setupActor(async () => {
wallets = devWalletsL2()
})
run(async (b, ctx, logger) => {
const sender = wallets[Math.floor(Math.random() * wallets.length)]
const contract = new ContractFactory(ERC20.abi, ERC20.bytecode).connect(
sender
)
logger.log(`Deploying contract with ${sender.address}.`)
const deployment = await contract.deploy(
Math.floor(1_000_000 * Math.random()),
'Test Token',
18,
'OP'
)
logger.log(
`Awaiting receipt for deployment tx ${deployment.deployTransaction.hash}.`
)
await deployment.deployed()
const receipt = await sender.provider.getTransactionReceipt(
deployment.deployTransaction.hash
)
logger.log(`Deployment completed in block ${receipt.blockNumber}.`)
})
})
import { utils, Wallet, providers, constants } from 'ethers'
import {
CrossChainMessenger,
ETHBridgeAdapter,
StandardBridgeAdapter,
} from '@eth-optimism/sdk'
import { predeploys } from '@eth-optimism/contracts-bedrock'
import { sleep } from '@eth-optimism/core-utils'
import { actor, setupActor, run } from '../lib/convenience'
interface Context {
wallet: Wallet
}
actor('Dev account sender', () => {
let l1Provider: providers.JsonRpcProvider
let l2Provider: providers.JsonRpcProvider
let wallet: Wallet
let messenger: CrossChainMessenger
let contracts: any
setupActor(async () => {
l1Provider = new providers.JsonRpcProvider(process.env.L1_RPC)
l2Provider = new providers.JsonRpcProvider(process.env.L2_RPC)
wallet = new Wallet(process.env.PRIVATE_KEY)
contracts = require(process.env.CONTRACTS_JSON_PATH)
messenger = new CrossChainMessenger({
l1SignerOrProvider: wallet.connect(l1Provider),
l2SignerOrProvider: wallet.connect(l2Provider),
l1ChainId: (await l1Provider.getNetwork()).chainId,
l2ChainId: (await l2Provider.getNetwork()).chainId,
bridges: {
Standard: {
Adapter: StandardBridgeAdapter,
l1Bridge: contracts.L1StandardBridgeProxy,
l2Bridge: predeploys.L2StandardBridge,
},
ETH: {
Adapter: ETHBridgeAdapter,
l1Bridge: contracts.L1StandardBridgeProxy,
l2Bridge: predeploys.L2StandardBridge,
},
},
contracts: {
l1: {
AddressManager: constants.AddressZero,
StateCommitmentChain: constants.AddressZero,
CanonicalTransactionChain: constants.AddressZero,
BondManager: constants.AddressZero,
L1StandardBridge: contracts.L1StandardBridgeProxy,
L1CrossDomainMessenger: contracts.L1CrossDomainMessengerProxy,
L2OutputOracle: contracts.L2OutputOracleProxy,
OptimismPortal: contracts.OptimismPortalProxy,
},
},
bedrock: true,
})
})
run(async (b, ctx: Context, logger) => {
const recipient = Wallet.createRandom().connect(l2Provider)
logger.log(`Depositing funds to ${recipient.address}.`)
const depositTx = await messenger.depositETH(utils.parseEther('0.0001'), {
recipient: recipient.address,
})
logger.log(`Awaiting receipt for deposit tx ${depositTx.hash}.`)
await depositTx.wait()
// Temporary until this is supported in the SDK.
for (let i = 0; i < 60; i++) {
const recipBal = await recipient.getBalance()
logger.log(`Polling L2 for deposit completion.`)
if (recipBal.eq(utils.parseEther('0.0001'))) {
logger.log('Deposit successful.')
return
}
await sleep(1000)
}
throw new Error('Timed out.')
})
})
import { providers, Wallet } from 'ethers'
const DEV_MNEMONIC =
'test test test test test test test test test test test junk'
export const devWalletsL2 = () => {
const provider = new providers.JsonRpcProvider(process.env.L2_RPC)
const wallets = []
for (let i = 0; i < 20; i++) {
wallets.push(
Wallet.fromMnemonic(DEV_MNEMONIC, `m/44'/60'/0'/0/${i}`).connect(provider)
)
}
return wallets
}
...@@ -22,7 +22,11 @@ export interface Bencher { ...@@ -22,7 +22,11 @@ export interface Bencher {
bench: (name: string, cb: () => Promise<any>) => Promise<any> bench: (name: string, cb: () => Promise<any>) => Promise<any>
} }
export type RunCB<C> = (b: Bencher, ctx: C) => Promise<void> export type RunCB<C> = (
b: Bencher,
ctx: C,
logger: WorkerLogger
) => Promise<void>
export interface RunOpts { export interface RunOpts {
runs: number | null runs: number | null
...@@ -138,7 +142,7 @@ export class Runner { ...@@ -138,7 +142,7 @@ export class Runner {
} }
try { try {
await this.actor.run(this.stepper, ctx) await this.actor.run(this.stepper, ctx, this.logger)
} catch (e) { } catch (e) {
console.error('Error in actor run:') console.error('Error in actor run:')
console.error(`Benchmark name: ${actor.name}`) console.error(`Benchmark name: ${actor.name}`)
...@@ -147,6 +151,7 @@ export class Runner { ...@@ -147,6 +151,7 @@ export class Runner {
console.error('Stack trace:') console.error('Stack trace:')
console.error(e) console.error(e)
failedActorRunsTotal.inc(metricLabels) failedActorRunsTotal.inc(metricLabels)
await sleep(1000)
continue continue
} }
...@@ -154,7 +159,10 @@ export class Runner { ...@@ -154,7 +159,10 @@ export class Runner {
i++ i++
if (opts.runs && (i % 10 === 0 || i === opts.runs)) { if (
(opts.runs && (i % 10 === 0 || i === opts.runs)) ||
now - lastDurPrint > 10000
) {
this.logger.log(`Completed run ${i} of ${opts.runs}.`) this.logger.log(`Completed run ${i} of ${opts.runs}.`)
} }
...@@ -185,7 +193,8 @@ export class Actor { ...@@ -185,7 +193,8 @@ export class Actor {
private _tearDownRun: <C>(ctx: C) => Promise<void> = asyncNoop as any private _tearDownRun: <C>(ctx: C) => Promise<void> = asyncNoop as any
// eslint-disable-next-line @typescript-eslint/no-empty-function // eslint-disable-next-line @typescript-eslint/no-empty-function
private _run: <C>(b: Bencher, ctx: C) => Promise<void> = asyncNoop private _run: <C>(b: Bencher, ctx: C, logger: WorkerLogger) => Promise<void> =
asyncNoop
private logger: ActorLogger private logger: ActorLogger
......
...@@ -5,7 +5,7 @@ import { Command } from 'commander' ...@@ -5,7 +5,7 @@ import { Command } from 'commander'
import { defaultRuntime } from './convenience' import { defaultRuntime } from './convenience'
import { RunOpts } from './actor' import { RunOpts } from './actor'
import { serveMetrics } from './metrics' import { serveMetrics } from './metrics'
import pkg from '../../package.json' import pkg from '../package.json'
const program = new Command() const program = new Command()
program.version(pkg.version) program.version(pkg.version)
......
{
"name": "@eth-optimism/actor-tests",
"version": "0.0.1",
"description": "A library and suite of tests to stress test Optimism Bedrock.",
"license": "MIT",
"author": "",
"main": "index.js",
"directories": {
"lib": "lib"
},
"scripts": {
"lint": "yarn lint:fix && yarn lint:check",
"lint:check": "eslint . --max-warnings=0",
"lint:fix": "yarn lint:check --fix",
"pre-commit": "lint-staged",
"run:bedrock": "ts-node ./lib/runner.ts -f",
"test": "echo 'No tests specified.'",
"test:coverage": "yarn test"
},
"dependencies": {
"@eth-optimism/contracts-bedrock": "0.5.2",
"@eth-optimism/core-utils": "^0.9.2",
"@eth-optimism/sdk": "^1.3.1",
"@types/chai": "^4.2.18",
"@types/chai-as-promised": "^7.1.4",
"async-mutex": "^0.3.2",
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"commander": "^8.3.0",
"eslint": "^7.27.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsdoc": "^35.1.2",
"eslint-plugin-prefer-arrow": "^1.2.3",
"eslint-plugin-prettier": "^3.4.0",
"ethers": "^5.6.9",
"prom-client": "^14.0.1",
"typescript": "^4.3.5"
}
}
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"resolveJsonModule": true
},
"include": [
"./lib",
"./bedrock/**/*.(ts|json)",
"./package.json"
]
}
...@@ -652,6 +652,27 @@ ...@@ -652,6 +652,27 @@
minimatch "^3.1.2" minimatch "^3.1.2"
strip-json-comments "^3.1.1" strip-json-comments "^3.1.1"
"@eth-optimism/contracts-bedrock@0.5.2":
version "0.5.2"
resolved "https://registry.yarnpkg.com/@eth-optimism/contracts-bedrock/-/contracts-bedrock-0.5.2.tgz#9e7c364afe0791e54f311d3a2135623448881936"
integrity sha512-5QFEmudbU9Q6rOxZibPRTqW6q/gKQ7H6toC9v645pYJ4Aw2mB+FIQDbeJ4hDLwV/GRjaHXOuU9uGEqLMk+y8Cw==
dependencies:
"@eth-optimism/core-utils" "^0.9.2"
"@ethereumjs/trie" "^5.0.0-beta.1"
"@ethereumjs/util" "^8.0.0-beta.1"
"@openzeppelin/contracts" "^4.5.0"
"@openzeppelin/contracts-upgradeable" "^4.5.2"
"@rari-capital/solmate" "https://github.com/rari-capital/solmate.git#8f9b23f8838670afda0fd8983f2c41e8037ae6bc"
bip39 "^3.0.4"
ds-test "https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5"
ethereumjs-wallet "^1.0.2"
ethers "^5.6.8"
excessively-safe-call "https://github.com/nomad-xyz/ExcessivelySafeCall.git#4fcdfd3593d21381f696c790fa6180b8ef559c1e"
forge-std "https://github.com/foundry-rs/forge-std.git#f18682b2874fc57d7c80a511fed0b35ec4201ffa"
hardhat "^2.9.6"
merkle-patricia-tree "^4.2.4"
rlp "^2.2.7"
"@ethereum-waffle/chai@^3.4.0": "@ethereum-waffle/chai@^3.4.0":
version "3.4.0" version "3.4.0"
resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.0.tgz#2477877410a96bf370edd64df905b04fb9aba9d5" resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.0.tgz#2477877410a96bf370edd64df905b04fb9aba9d5"
...@@ -951,6 +972,21 @@ ...@@ -951,6 +972,21 @@
"@ethersproject/properties" "^5.6.0" "@ethersproject/properties" "^5.6.0"
"@ethersproject/strings" "^5.6.1" "@ethersproject/strings" "^5.6.1"
"@ethersproject/abi@5.6.4":
version "5.6.4"
resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.6.4.tgz#f6e01b6ed391a505932698ecc0d9e7a99ee60362"
integrity sha512-TTeZUlCeIHG6527/2goZA6gW5F8Emoc7MrZDC7hhP84aRGvW3TEdTnZR08Ls88YXM1m2SuK42Osw/jSi3uO8gg==
dependencies:
"@ethersproject/address" "^5.6.1"
"@ethersproject/bignumber" "^5.6.2"
"@ethersproject/bytes" "^5.6.1"
"@ethersproject/constants" "^5.6.1"
"@ethersproject/hash" "^5.6.1"
"@ethersproject/keccak256" "^5.6.1"
"@ethersproject/logger" "^5.6.0"
"@ethersproject/properties" "^5.6.0"
"@ethersproject/strings" "^5.6.1"
"@ethersproject/abi@^5.0.12": "@ethersproject/abi@^5.0.12":
version "5.4.1" version "5.4.1"
resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.4.1.tgz#6ac28fafc9ef6f5a7a37e30356a2eb31fa05d39b" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.4.1.tgz#6ac28fafc9ef6f5a7a37e30356a2eb31fa05d39b"
...@@ -1298,6 +1334,13 @@ ...@@ -1298,6 +1334,13 @@
dependencies: dependencies:
"@ethersproject/logger" "^5.6.0" "@ethersproject/logger" "^5.6.0"
"@ethersproject/networks@5.6.4":
version "5.6.4"
resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.4.tgz#51296d8fec59e9627554f5a8a9c7791248c8dc07"
integrity sha512-KShHeHPahHI2UlWdtDMn2lJETcbtaJge4k7XSjDR9h79QTd6yQJmv6Cp2ZA4JdqWnhszAOLSuJEd9C0PRw7hSQ==
dependencies:
"@ethersproject/logger" "^5.6.0"
"@ethersproject/pbkdf2@5.4.0", "@ethersproject/pbkdf2@^5.4.0": "@ethersproject/pbkdf2@5.4.0", "@ethersproject/pbkdf2@^5.4.0":
version "5.4.0" version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.4.0.tgz#ed88782a67fda1594c22d60d0ca911a9d669641c" resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.4.0.tgz#ed88782a67fda1594c22d60d0ca911a9d669641c"
...@@ -2821,6 +2864,11 @@ ...@@ -2821,6 +2864,11 @@
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.1.tgz#f63fc384255d6ac139e0a2561aa207fd7c14183c" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.1.tgz#f63fc384255d6ac139e0a2561aa207fd7c14183c"
integrity sha512-5EFiZld3DYFd8aTL8eeMnhnaWh1/oXLXFNuFMrgF3b1DNPshF3LCyO7VR6lc+gac2URJ0BlVcZoCfkk/3MoEfg== integrity sha512-5EFiZld3DYFd8aTL8eeMnhnaWh1/oXLXFNuFMrgF3b1DNPshF3LCyO7VR6lc+gac2URJ0BlVcZoCfkk/3MoEfg==
"@openzeppelin/contracts-upgradeable@^4.5.2":
version "4.7.2"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.2.tgz#414096e21f048200cbb7ad4fe4c6de2e822513bf"
integrity sha512-3dgc6qVmFch/uOmlmKnw5/v3JxwXcZD4T10/9CI1OUbX8AqjoZrBGKfxN1z3QxnIXRU/X31/BItJezJSDDTe7Q==
"@openzeppelin/contracts@3.4.1-solc-0.7-2": "@openzeppelin/contracts@3.4.1-solc-0.7-2":
version "3.4.1-solc-0.7-2" version "3.4.1-solc-0.7-2"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz#371c67ebffe50f551c3146a9eec5fe6ffe862e92"
...@@ -2851,6 +2899,11 @@ ...@@ -2851,6 +2899,11 @@
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.4.0.tgz#4a1df71f736c31230bbbd634dfb006a756b51e6b" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.4.0.tgz#4a1df71f736c31230bbbd634dfb006a756b51e6b"
integrity sha512-dlKiZmDvJnGRLHojrDoFZJmsQVeltVeoiRN7RK+cf2FmkhASDEblE0RiaYdxPNsUZa6mRG8393b9bfyp+V5IAw== integrity sha512-dlKiZmDvJnGRLHojrDoFZJmsQVeltVeoiRN7RK+cf2FmkhASDEblE0RiaYdxPNsUZa6mRG8393b9bfyp+V5IAw==
"@openzeppelin/contracts@^4.5.0":
version "4.7.2"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.7.2.tgz#7587416fe2d35abf574193515b8971bfe9f64bc7"
integrity sha512-4n/JL9izql8303mPqPdubuna/DWEMbmOzWYUWyCPhjhiEr2w3nQrjE7vZz1fBF+wzzP6dZbIcsgqACk53c9FGA==
"@primitivefi/hardhat-dodoc@^0.1.3": "@primitivefi/hardhat-dodoc@^0.1.3":
version "0.1.3" version "0.1.3"
resolved "https://registry.yarnpkg.com/@primitivefi/hardhat-dodoc/-/hardhat-dodoc-0.1.3.tgz#338ecff24b93d3b43fa35a98909f6840af86c27c" resolved "https://registry.yarnpkg.com/@primitivefi/hardhat-dodoc/-/hardhat-dodoc-0.1.3.tgz#338ecff24b93d3b43fa35a98909f6840af86c27c"
...@@ -2858,6 +2911,11 @@ ...@@ -2858,6 +2911,11 @@
dependencies: dependencies:
squirrelly "^8.0.8" squirrelly "^8.0.8"
"@rari-capital/solmate@git+https://github.com/rari-capital/solmate.git#8f9b23f8838670afda0fd8983f2c41e8037ae6bc":
version "7.0.0-alpha.3"
uid "8f9b23f8838670afda0fd8983f2c41e8037ae6bc"
resolved "git+https://github.com/rari-capital/solmate.git#8f9b23f8838670afda0fd8983f2c41e8037ae6bc"
"@rari-capital/solmate@https://github.com/rari-capital/solmate.git#8f9b23f8838670afda0fd8983f2c41e8037ae6bc": "@rari-capital/solmate@https://github.com/rari-capital/solmate.git#8f9b23f8838670afda0fd8983f2c41e8037ae6bc":
version "7.0.0-alpha.3" version "7.0.0-alpha.3"
resolved "https://github.com/rari-capital/solmate.git#8f9b23f8838670afda0fd8983f2c41e8037ae6bc" resolved "https://github.com/rari-capital/solmate.git#8f9b23f8838670afda0fd8983f2c41e8037ae6bc"
...@@ -7168,6 +7226,11 @@ drbg.js@^1.0.1: ...@@ -7168,6 +7226,11 @@ drbg.js@^1.0.1:
create-hash "^1.1.2" create-hash "^1.1.2"
create-hmac "^1.1.4" create-hmac "^1.1.4"
"ds-test@git+https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5":
version "0.0.0"
uid "9310e879db8ba3ea6d5c6489a579118fd264a3f5"
resolved "git+https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5"
"ds-test@https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5": "ds-test@https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5":
version "0.0.0" version "0.0.0"
resolved "https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5" resolved "https://github.com/dapphub/ds-test.git#9310e879db8ba3ea6d5c6489a579118fd264a3f5"
...@@ -8496,6 +8559,42 @@ ethers@^5.5.2, ethers@^5.5.3, ethers@^5.6.8: ...@@ -8496,6 +8559,42 @@ ethers@^5.5.2, ethers@^5.5.3, ethers@^5.6.8:
"@ethersproject/web" "5.6.1" "@ethersproject/web" "5.6.1"
"@ethersproject/wordlists" "5.6.1" "@ethersproject/wordlists" "5.6.1"
ethers@^5.6.9:
version "5.6.9"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.6.9.tgz#4e12f8dfcb67b88ae7a78a9519b384c23c576a4d"
integrity sha512-lMGC2zv9HC5EC+8r429WaWu3uWJUCgUCt8xxKCFqkrFuBDZXDYIdzDUECxzjf2BMF8IVBByY1EBoGSL3RTm8RA==
dependencies:
"@ethersproject/abi" "5.6.4"
"@ethersproject/abstract-provider" "5.6.1"
"@ethersproject/abstract-signer" "5.6.2"
"@ethersproject/address" "5.6.1"
"@ethersproject/base64" "5.6.1"
"@ethersproject/basex" "5.6.1"
"@ethersproject/bignumber" "5.6.2"
"@ethersproject/bytes" "5.6.1"
"@ethersproject/constants" "5.6.1"
"@ethersproject/contracts" "5.6.2"
"@ethersproject/hash" "5.6.1"
"@ethersproject/hdnode" "5.6.2"
"@ethersproject/json-wallets" "5.6.1"
"@ethersproject/keccak256" "5.6.1"
"@ethersproject/logger" "5.6.0"
"@ethersproject/networks" "5.6.4"
"@ethersproject/pbkdf2" "5.6.1"
"@ethersproject/properties" "5.6.0"
"@ethersproject/providers" "5.6.8"
"@ethersproject/random" "5.6.1"
"@ethersproject/rlp" "5.6.1"
"@ethersproject/sha2" "5.6.1"
"@ethersproject/signing-key" "5.6.2"
"@ethersproject/solidity" "5.6.1"
"@ethersproject/strings" "5.6.1"
"@ethersproject/transactions" "5.6.2"
"@ethersproject/units" "5.6.1"
"@ethersproject/wallet" "5.6.2"
"@ethersproject/web" "5.6.1"
"@ethersproject/wordlists" "5.6.1"
ethjs-unit@0.1.6: ethjs-unit@0.1.6:
version "0.1.6" version "0.1.6"
resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699"
...@@ -8540,6 +8639,10 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: ...@@ -8540,6 +8639,10 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4" md5.js "^1.3.4"
safe-buffer "^5.1.1" safe-buffer "^5.1.1"
"excessively-safe-call@git+https://github.com/nomad-xyz/ExcessivelySafeCall.git#4fcdfd3593d21381f696c790fa6180b8ef559c1e":
version "0.0.1-rc.1"
resolved "git+https://github.com/nomad-xyz/ExcessivelySafeCall.git#4fcdfd3593d21381f696c790fa6180b8ef559c1e"
"excessively-safe-call@https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0": "excessively-safe-call@https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0":
version "0.0.1-rc.1" version "0.0.1-rc.1"
resolved "https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0" resolved "https://github.com/nomad-xyz/ExcessivelySafeCall.git#81cd99ce3e69117d665d7601c330ea03b97acce0"
...@@ -9056,6 +9159,11 @@ forever-agent@~0.6.1: ...@@ -9056,6 +9159,11 @@ forever-agent@~0.6.1:
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
"forge-std@git+https://github.com/foundry-rs/forge-std.git#f18682b2874fc57d7c80a511fed0b35ec4201ffa":
version "0.0.0"
uid f18682b2874fc57d7c80a511fed0b35ec4201ffa
resolved "git+https://github.com/foundry-rs/forge-std.git#f18682b2874fc57d7c80a511fed0b35ec4201ffa"
"forge-std@https://github.com/foundry-rs/forge-std.git#f18682b2874fc57d7c80a511fed0b35ec4201ffa": "forge-std@https://github.com/foundry-rs/forge-std.git#f18682b2874fc57d7c80a511fed0b35ec4201ffa":
version "0.0.0" version "0.0.0"
resolved "https://github.com/foundry-rs/forge-std.git#f18682b2874fc57d7c80a511fed0b35ec4201ffa" resolved "https://github.com/foundry-rs/forge-std.git#f18682b2874fc57d7c80a511fed0b35ec4201ffa"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment