diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4af3b15c4a77..5559b6401930 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -8,7 +8,6 @@ # packages/specs/protocol/ @smartcontracts @ben-chain @maurelian # ops/ @tynes @karlfloersch # packages/hardhat-ovm/ @smartcontracts -# packages/smock/ @smartcontracts @maurelian # packages/core-utils/ @smartcontracts @annieke @ben-chain # packages/common-ts/ @annieke # packages/core-utils/src/watcher.ts @K-Ho diff --git a/.github/labeler.yml b/.github/labeler.yml index f2631e3cae4d..b0750af88a22 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -42,7 +42,3 @@ M-hardhat-ovm: M-ops: - any: ['ops/**/*'] - -M-smock: - - any: ['packages/smock/**/*'] - diff --git a/.vscode/settings.json b/.vscode/settings.json index a08382372dd7..ceb11b1aefd6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,6 @@ {"directory": "packages/core-utils", "changeProcessCWD": true }, {"directory": "packages/common-ts", "changeProcessCWD": true }, {"directory": "packages/hardhat-ovm", "changeProcessCWD": true }, - {"directory": "packages/smock", "changeProcessCWD": true }, {"directory": "packages/contracts", "changeProcessCWD": true }, {"directory": "packages/data-transport-layer", "changeProcessCWD": true }, {"directory": "packages/batch-submitter", "changeProcessCWD": true }, diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f3c276d25d1a..cf30ba1b1120 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,6 @@ These packages only require 1 reviewer (all other packages require 2 reviewers, unless the changes do not affect production or test code). -- packages/smock - packages/core-utils - packages/hardhat-ovm - packages/common-ts diff --git a/README.md b/README.md index f9316d3bb025..807cffbe00ed 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ Extensive documentation is available [here](http://community.optimism.io/docs/). * [`core-utils`](./packages/core-utils): Low-level utilities and encoding packages * [`common-ts`](./packages/common-ts): Common tools for TypeScript code that runs in Node * [`hardhat-ovm`](./packages/hardhat-ovm): Hardhat plugin which enables the [OVM Compiler](https://github.com/ethereum-optimism/solidity) - * [`smock`](./packages/smock): Testing utility for mocking smart contract return values and storage * [`data-transport-layer`](./packages/data-transport-layer): Event indexer, allowing the `l2geth` node to access L1 data * [`batch-submitter`](./packages/batch-submitter): Daemon for submitting L2 transaction and state root batches to L1 * [`message-relayer`](./packages/message-relayer): Service for relaying L2 messages to L1 diff --git a/ops/docker/Dockerfile.monorepo b/ops/docker/Dockerfile.monorepo index 30a4753bf8bb..2a3508c6d772 100644 --- a/ops/docker/Dockerfile.monorepo +++ b/ops/docker/Dockerfile.monorepo @@ -27,7 +27,6 @@ COPY *.json yarn.lock ./ COPY packages/core-utils/package.json ./packages/core-utils/package.json COPY packages/common-ts/package.json ./packages/common-ts/package.json COPY packages/hardhat-ovm/package.json ./packages/hardhat-ovm/package.json -COPY packages/smock/package.json ./packages/smock/package.json COPY packages/contracts/package.json ./packages/contracts/package.json COPY packages/data-transport-layer/package.json ./packages/data-transport-layer/package.json COPY packages/batch-submitter/package.json ./packages/batch-submitter/package.json diff --git a/packages/message-relayer/package.json b/packages/message-relayer/package.json index 15492c5623e5..1131a002e22b 100644 --- a/packages/message-relayer/package.json +++ b/packages/message-relayer/package.json @@ -45,6 +45,7 @@ }, "devDependencies": { "@eth-optimism/smock": "^1.1.9", + "@nomiclabs/ethereumjs-vm": "^4", "@nomiclabs/hardhat-ethers": "^2.0.2", "@nomiclabs/hardhat-waffle": "^2.0.1", "@types/chai": "^4.2.18", @@ -52,24 +53,24 @@ "@types/mocha": "^8.2.2", "@typescript-eslint/eslint-plugin": "^4.26.0", "@typescript-eslint/parser": "^4.26.0", + "babel-eslint": "^10.1.0", "chai": "^4.3.4", "chai-as-promised": "^7.1.1", - "eslint-plugin-prettier": "^3.4.0", + "eslint": "^7.27.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-ban": "^1.5.2", "eslint-plugin-import": "^2.23.4", "eslint-plugin-jsdoc": "^35.1.2", "eslint-plugin-prefer-arrow": "^1.2.3", + "eslint-plugin-prettier": "^3.4.0", "eslint-plugin-react": "^7.24.0", "eslint-plugin-unicorn": "^32.0.1", "ethereum-waffle": "^3.3.0", "hardhat": "^2.3.0", + "lint-staged": "11.0.0", "lodash": "^4.17.21", "mocha": "^8.4.0", - "babel-eslint": "^10.1.0", - "eslint": "^7.27.0", - "lint-staged": "11.0.0", "prettier": "^2.2.1", "typescript": "^4.2.3" } -} \ No newline at end of file +} diff --git a/packages/smock/.eslintrc.js b/packages/smock/.eslintrc.js deleted file mode 100644 index bfd2057be80b..000000000000 --- a/packages/smock/.eslintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: '../../.eslintrc.js', -} diff --git a/packages/smock/.github/workflows/lint-build-test.yml b/packages/smock/.github/workflows/lint-build-test.yml deleted file mode 100644 index 8f61ec4f562f..000000000000 --- a/packages/smock/.github/workflows/lint-build-test.yml +++ /dev/null @@ -1,50 +0,0 @@ -name: smock - lint, build, test - -on: - push: - branches: - - main - pull_request: - branches: - - main - -jobs: - build-test-lint: - name: Run job on ${{matrix.node}} - runs-on: ubuntu-latest - - strategy: - matrix: - node: [ '10', '12', '14' ] - - steps: - - uses: actions/checkout@v2 - - - name: Setup node ${{ matrix.node }} - uses: actions/setup-node@v1 - with: - node-version: ${{ matrix.node }} - - # START DEPENDENCY CACHING - - name: Cache root deps - uses: actions/cache@v1 - id: cache_base - with: - path: node_modules - key: ${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('package.json') }} - - # END DEPENDENCY CACHING - - - name: Install Dependencies - run: yarn install - - - name: Lint - run: yarn lint - - - name: Build - run: | - yarn clean - yarn build - - - name: Test - run: yarn test diff --git a/packages/smock/.github/workflows/version-to-release.yml b/packages/smock/.github/workflows/version-to-release.yml deleted file mode 100644 index 01768cb0f07c..000000000000 --- a/packages/smock/.github/workflows/version-to-release.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Auto tag-release-publish - -on: - push: - branches: - - main - -jobs: - tag: - name: Create tag for new version - runs-on: ubuntu-latest - outputs: - tag_name: ${{ steps.create_new_tag.outputs.tag }} - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 2 - - uses: salsify/action-detect-and-tag-new-version@v2 - id: create_new_tag - - release: - name: Create release - runs-on: ubuntu-latest - needs: tag - if: needs.tag.outputs.tag_name - steps: - - uses: actions/checkout@v2 - - uses: actions/create-release@v1 - id: create_release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ needs.tag.outputs.tag_name }} - release_name: ${{ needs.tag.outputs.tag_name }} - draft: false - prerelease: false - - publish: - name: Build and publish - runs-on: ubuntu-latest - needs: tag - if: needs.tag.outputs.tag_name - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: '14.x' - registry-url: 'https://registry.npmjs.org' - - run: yarn - - run: yarn build - - run: npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/packages/smock/.gitignore b/packages/smock/.gitignore deleted file mode 100644 index 7d9d6ae919af..000000000000 --- a/packages/smock/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -node_modules/ -cache/ -artifacts/ -build/ -.DS_Store -temp/ \ No newline at end of file diff --git a/packages/smock/.lintstagedrc.yml b/packages/smock/.lintstagedrc.yml deleted file mode 100644 index a3035a2299b2..000000000000 --- a/packages/smock/.lintstagedrc.yml +++ /dev/null @@ -1,2 +0,0 @@ -"*.{ts,js}": - - eslint diff --git a/packages/smock/.prettierrc.js b/packages/smock/.prettierrc.js deleted file mode 100644 index 6b3fa8e2ce23..000000000000 --- a/packages/smock/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('../../.prettierrc.js'), -}; \ No newline at end of file diff --git a/packages/smock/CHANGELOG.md b/packages/smock/CHANGELOG.md deleted file mode 100644 index b7f863464aad..000000000000 --- a/packages/smock/CHANGELOG.md +++ /dev/null @@ -1,111 +0,0 @@ -# @eth-optimism/smock - -## 1.1.10 - -### Patch Changes - -- 269b0788: Adds naive support for packed storage slots - -## 1.1.9 - -### Patch Changes - -- c73c3939: Update the typescript version to `4.3.5` -- Updated dependencies [c73c3939] - - @eth-optimism/core-utils@0.5.1 - -## 1.1.8 - -### Patch Changes - -- d1da05be: Add a test and a doc section for returning multiple uint256 arrays - -## 1.1.7 - -### Patch Changes - -- Updated dependencies [049200f4] - - @eth-optimism/core-utils@0.5.0 - -## 1.1.6 - -### Patch Changes - -- 71349a4e: Minor smock patch to add support for hardhat 2.4.0 and up -- Updated dependencies [d9644c34] -- Updated dependencies [df5ff890] - - @eth-optimism/core-utils@0.4.6 - -## 1.1.5 - -### Patch Changes - -- 5e3c5d1c: Fixes a bug that would break call assertions for overloaded smocked functions -- e6e87ae1: Fix a bug where overloaded functions would not be handled correctly -- Updated dependencies [a64f8161] -- Updated dependencies [750a5021] -- Updated dependencies [c2b6e14b] - - @eth-optimism/core-utils@0.4.5 - -## 1.1.4 - -### Patch Changes - -- a656f06: Adds a wallet object to smock contracts that can be used to send transactions - -## 1.1.3 - -### Patch Changes - -- 1d40586: Removed various unused dependencies -- Updated dependencies [1d40586] -- Updated dependencies [ce7fa52] - - @eth-optimism/core-utils@0.4.1 - -## 1.1.2 - -### Patch Changes - -- Updated dependencies [28dc442] -- Updated dependencies [a0a0052] - - @eth-optimism/core-utils@0.4.0 - -## 1.1.1 - -### Patch Changes - -- 6daa408: update hardhat versions so that solc is resolved correctly -- Updated dependencies [6daa408] -- Updated dependencies [dee74ef] -- Updated dependencies [d64b66d] - - @eth-optimism/core-utils@0.3.2 - -## 1.1.0 - -### Minor Changes - -- 79f812d: Adds support for hardhat ^2.2.0, required because of move to ethereumjs-vm v5. - -## 1.0.2 - -### Patch Changes - -- Updated dependencies [91460d9] -- Updated dependencies [a0a7956] -- Updated dependencies [0497d7d] - - @eth-optimism/core-utils@0.3.0 - -## 1.0.1 - -### Patch Changes - -- 5362d38: adds build files which were not published before to npm -- Updated dependencies [5362d38] - - @eth-optimism/core-utils@0.2.1 - -## 1.0.0 - -### Patch Changes - -- Updated dependencies [6cbc54d] - - @eth-optimism/core-utils@0.2.0 diff --git a/packages/smock/LICENSE b/packages/smock/LICENSE deleted file mode 100644 index 6a7da5218bb2..000000000000 --- a/packages/smock/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(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. diff --git a/packages/smock/README.md b/packages/smock/README.md index 5b5f6fe3c287..2569beac4f89 100644 --- a/packages/smock/README.md +++ b/packages/smock/README.md @@ -1,427 +1,7 @@ # @eth-optimism/smock -`smock` is a utility package that can generate mock Solidity contracts (for testing). `smock` hooks into a `ethereumjs-vm` instance so that mock contract functions can be written entirely in JavaScript. `smock` currently only supports [Hardhat](http://hardhat.org/), but will be extended to support other testing frameworks. +## NOTICE -Some nice benefits of hooking in at the VM level: -* Don't need to deploy any special contracts just for mocking! -* All of the calls are synchronous. -* Perform arbitrary javascript logic within your return value (return a function). -* It sounds cool. - -`smock` also contains `smoddit`, another utility that allows you to modify the internal storage of contracts. We've found this to be quite useful in cases where many interactions occur within a single contract (typically to save gas). - -## Installation - -You can easily install `smock` via `npm`: - -```sh -npm install @eth-optimism/smock -``` - -Or via `yarn`: - -```sh -yarn add @eth-optimism/smock -``` - -## Note on Using `smoddit` - -`smoddit` requires access to the internal storage layout of your smart contracts. The Solidity compiler exposes this via the `storageLayout` flag, which you need to enable at your hardhat config. - -Here's an example `hardhat.config.ts` that shows how to import the plugin: - -```typescript -// hardhat.config.ts -import { HardhatUserConfig } from 'hardhat/config' - -const config: HardhatUserConfig = { - ..., - solidity: { - version: '0.7.0', - settings: { - outputSelection: { - "*": { - "*": ["storageLayout"], - }, - }, - } - }, -} - -export default config -``` - -## API -### Functions -#### `smockit` -##### Import -```typescript -import { smockit } from '@eth-optimism/smock' -``` - -##### Signature -```typescript -const smockit = async ( - spec: ContractInterface | Contract | ContractFactory, - opts: { - provider?: any, - address?: string, - }, -): Promise -``` - -#### `smoddit` -##### Import -```typescript -import { smoddit } from '@eth-optimism/smock' -``` - -##### Signature -```typescript -const smoddit = async ( - name: string, - signer?: any -): Promise -``` - -### Types -#### `smockit` -##### `MockContract` -```typescript -interface MockContract extends ethers.Contract { - smocked: { - [functionName: string]: MockContractFunction - } - - // A wallet you can use to send transactions *from* a smocked contract - wallet: ethers.Signer -} -``` - -##### `MockContractFunction` -```typescript -interface MockContractFunction { - calls: string[] - will: { - return: { - (): void - with: (returnValue?: MockReturnValue) => void - } - revert: { - (): void - with: (revertValue?: string) => void - } - resolve: 'return' | 'revert' - } -} -``` - -##### `MockReturnValue` -```typescript -export type MockReturnValue = - | string - | Object - | any[] - | ((...params: any[]) => MockReturnValue) -``` - -#### `smoddit` -##### `ModifiableContractFactory` -```typescript -interface ModifiableContractFactory extends ethers.ContractFactory { - deploy: (...args: any[]) => Promise -} -``` - -##### `ModifiableContract` -```typescript -interface ModifiableContract extends ethers.Contract { - smodify: { - put: (storage: any) => Promise - } -} -``` - -## Examples (smockit) - -### Via `ethers.Contract` -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const MyContractFactory = await ethers.getContractFactory('MyContract') -const MyContract = await MyContractFactory.deploy(...) - -// Smockit! -const MyMockContract = await smockit(MyContract) - -MyMockContract.smocked.myFunction.will.return.with('Some return value!') - -console.log(await MyMockContract.myFunction()) // 'Some return value!' -``` - -### Asserting Call Count -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const MyContractFactory = await ethers.getContractFactory('MyContract') -const MyContract = await MyContractFactory.deploy(...) - -const MyOtherContractFactory = await ethers.getContractFactory('MyOtherContract') -const MyOtherContract = await MyOtherContract.deploy(...) - -// Smockit! -const MyMockContract = await smockit(MyContract) - -MyMockContract.smocked.myFunction.will.return.with('Some return value!') - -// Assuming that MyOtherContract.myOtherFunction calls MyContract.myFunction. -await MyOtherContract.myOtherFunction() - -console.log(MyMockContract.smocked.myFunction.calls.length) // 1 -``` - -### Asserting Call Data -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const MyContractFactory = await ethers.getContractFactory('MyContract') -const MyContract = await MyContractFactory.deploy(...) - -const MyOtherContractFactory = await ethers.getContractFactory('MyOtherContract') -const MyOtherContract = await MyOtherContract.deploy(...) - -// Smockit! -const MyMockContract = await smockit(MyContract) - -MyMockContract.smocked.myFunction.will.return.with('Some return value!') - -// Assuming that MyOtherContract.myOtherFunction calls MyContract.myFunction with 'Hello World!'. -await MyOtherContract.myOtherFunction() - -console.log(MyMockContract.smocked.myFunction.calls[0]) // 'Hello World!' -``` - -### Returning (w/o Data) -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const MyContractFactory = await ethers.getContractFactory('MyContract') -const MyContract = await MyContractFactory.deploy(...) - -// Smockit! -const MyMockContract = await smockit(MyContract) - -MyMockContract.smocked.myFunction.will.return() - -console.log(await MyMockContract.myFunction()) // [] -``` - -### Returning a Struct -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const MyContractFactory = await ethers.getContractFactory('MyContract') -const MyContract = await MyContractFactory.deploy(...) - -// Smockit! -const MyMockContract = await smockit(MyContract) - -MyMockContract.smocked.myFunction.will.return.with({ - valueA: 'Some value', - valueB: 1234, - valueC: true -}) - -console.log(await MyMockContract.myFunction()) // ['Some value', 1234, true] -``` - -### Returning a Multiple Arrays -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const MyContractFactory = await ethers.getContractFactory('MyContract') -const MyContract = await MyContractFactory.deploy(...) - -// Smockit! -const MyMockContract = await smockit(MyContract) - -MyMockContract.smocked.myFunction.will.return.with([ - [1234, 5678], - [4321, 8765] -]) - -console.log(await MyMockContract.myFunction()) // [ [1234, 5678], [4321, 8765] ] -``` - -### Returning a Function -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const MyContractFactory = await ethers.getContractFactory('MyContract') -const MyContract = await MyContractFactory.deploy(...) - -// Smockit! -const MyMockContract = await smockit(MyContract) - -MyMockContract.smocked.myFunction.will.return.with(() => { - return 'Some return value!' -}) - -console.log(await MyMockContract.myFunction()) // 'Some return value!' -``` - -### Returning a Function (w/ Arguments) -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const MyContractFactory = await ethers.getContractFactory('MyContract') -const MyContract = await MyContractFactory.deploy(...) - -// Smockit! -const MyMockContract = await smockit(MyContract) - -MyMockContract.smocked.myFunction.will.return.with((myFunctionArgument: string) => { - return myFunctionArgument -}) - -console.log(await MyMockContract.myFunction('Some return value!')) // 'Some return value!' -``` - -### Reverting (w/o Data) -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const MyContractFactory = await ethers.getContractFactory('MyContract') -const MyContract = await MyContractFactory.deploy(...) - -// Smockit! -const MyMockContract = await smockit(MyContract) - -MyMockContract.smocked.myFunction.will.revert() - -console.log(await MyMockContract.myFunction()) // Revert! -``` - -### Reverting (w/ Data) -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const MyContractFactory = await ethers.getContractFactory('MyContract') -const MyContract = await MyContractFactory.deploy(...) - -// Smockit! -const MyMockContract = await smockit(MyContract) - -MyMockContract.smocked.myFunction.will.revert.with('0x1234') - -console.log(await MyMockContract.myFunction('Some return value!')) // Revert! -``` - -### Sending transactions from a smocked contract -```typescript -import { ethers } from 'hardhat' -import { smockit } from '@eth-optimism/smock' - -const myContractFactory = await ethers.getContractFactory('MyContract') -const myContract = await myContractFactory.deploy(...) - -// Smockit! -const mock = await smockit('AnotherContract') - -await myContract.connect(mock.wallet).doSomeFunction() // msg.sender == mock.address -``` - -## Examples (smoddit) - -### Creating a Modifiable Contract -```typescript -import { ethers } from 'hardhat' -import { smoddit } from '@eth-optimism/smock' - -// Smoddit! -const MyModifiableContractFactory = await smoddit('MyContract') -const MyModifiableContract = await MyModifiableContractFactory.deploy(...) -``` - -### Modifying a `uint256` -```typescript -import { ethers } from 'hardhat' -import { smoddit } from '@eth-optimism/smock' - -// Smoddit! -const MyModifiableContractFactory = await smoddit('MyContract') -const MyModifiableContract = await MyModifiableContractFactory.deploy(...) - -await MyModifiableContract.smodify.put({ - myInternalUint256: 1234 -}) - -console.log(await MyMockContract.getMyInternalUint256()) // 1234 -``` - -### Modifying a Struct -```typescript -import { ethers } from 'hardhat' -import { smoddit } from '@eth-optimism/smock' - -// Smoddit! -const MyModifiableContractFactory = await smoddit('MyContract') -const MyModifiableContract = await MyModifiableContractFactory.deploy(...) - -await MyModifiableContract.smodify.put({ - myInternalStruct: { - valueA: 1234, - valueB: true - } -}) - -console.log(await MyMockContract.getMyInternalStruct()) // { valueA: 1234, valueB: true } -``` - -### Modifying a Mapping -```typescript -import { ethers } from 'hardhat' -import { smoddit } from '@eth-optimism/smock' - -// Smoddit! -const MyModifiableContractFactory = await smoddit('MyContract') -const MyModifiableContract = await MyModifiableContractFactory.deploy(...) - -await MyModifiableContract.smodify.put({ - myInternalMapping: { - 1234: 5678 - } -}) - -console.log(await MyMockContract.getMyInternalMappingValue(1234)) // 5678 -``` - -### Modifying a Nested Mapping -```typescript -import { ethers } from 'hardhat' -import { smoddit } from '@eth-optimism/smock' - -// Smoddit! -const MyModifiableContractFactory = await smoddit('MyContract') -const MyModifiableContract = await MyModifiableContractFactory.deploy(...) - -await MyModifiableContract.smodify.put({ - myInternalNestedMapping: { - 1234: { - 4321: 5678 - } - } -}) - -console.log(await MyMockContract.getMyInternalNestedMappingValue(1234, 4321)) // 5678 -``` +Smock v1 is being deprecated. +Please migrate to [Smock v2](https://github.com/defi-wonderland/smock). +You can find an archive of the Smock v1 codebase at [optimism@d337713c91](https://github.com/ethereum-optimism/optimism/tree/d337713c91c6634f546b8d6572392c0784ab8217/packages/smock). diff --git a/packages/smock/hardhat.config.ts b/packages/smock/hardhat.config.ts deleted file mode 100644 index 41e194d6c230..000000000000 --- a/packages/smock/hardhat.config.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { HardhatUserConfig } from 'hardhat/config' - -import '@nomiclabs/hardhat-ethers' -import '@nomiclabs/hardhat-waffle' - -const config: HardhatUserConfig = { - paths: { - sources: './test/contracts', - }, - solidity: { - version: '0.7.6', - settings: { - outputSelection: { - '*': { - '*': ['storageLayout'], - }, - }, - }, - }, -} - -export default config diff --git a/packages/smock/package.json b/packages/smock/package.json deleted file mode 100644 index 083129a869a8..000000000000 --- a/packages/smock/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "@eth-optimism/smock", - "files": [ - "dist/src/*" - ], - "version": "1.1.10", - "main": "dist/src/index", - "types": "dist/src/index", - "author": "Optimism PBC", - "license": "MIT", - "scripts": { - "build": "tsc -p tsconfig.build.json", - "test": "hardhat test --show-stack-traces", - "lint": "yarn lint:fix && yarn lint:check", - "pre-commit": "lint-staged", - "lint:fix": "yarn lint:check --fix", - "lint:check": "eslint .", - "clean": "rimraf ./artifacts ./cache ./dist ./tsconfig.build.tsbuildinfo" - }, - "peerDependencies": { - "@ethersproject/abi": "^5", - "@ethersproject/abstract-provider": "^5", - "@ethersproject/abstract-signer": "^5", - "@nomiclabs/ethereumjs-vm": "^4", - "@nomiclabs/hardhat-ethers": "^2", - "ethers": "^5", - "hardhat": "^2" - }, - "dependencies": { - "@eth-optimism/core-utils": "^0.5.1", - "bn.js": "^5.2.0" - }, - "devDependencies": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/abstract-provider": "^5.1.0", - "@ethersproject/abstract-signer": "^5.1.0", - "@nomiclabs/ethereumjs-vm": "^4.2.2", - "@nomiclabs/hardhat-ethers": "^2.0.2", - "@nomiclabs/hardhat-waffle": "^2.0.1", - "@types/bn.js": "^5.1.0", - "@types/chai": "^4.2.17", - "@types/glob": "^7.1.3", - "@types/lodash": "^4.14.161", - "@types/prettier": "^2.2.3", - "@typescript-eslint/eslint-plugin": "^4.26.0", - "@typescript-eslint/parser": "^4.26.0", - "chai": "^4.3.0", - "babel-eslint": "^10.1.0", - "eslint": "^7.27.0", - "eslint-plugin-prettier": "^3.4.0", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-ban": "^1.5.2", - "eslint-plugin-import": "^2.23.4", - "eslint-plugin-jsdoc": "^35.1.2", - "eslint-plugin-prefer-arrow": "^1.2.3", - "eslint-plugin-react": "^7.24.0", - "eslint-plugin-unicorn": "^32.0.1", - "ethereum-waffle": "^3.3.0", - "ethers": "^5.0.31", - "hardhat": "^2.4.0", - "lodash": "^4.17.20", - "prettier": "^2.2.1", - "lint-staged": "11.0.0", - "typescript": "^4.2.3" - } -} diff --git a/packages/smock/src/common/hardhat-common.ts b/packages/smock/src/common/hardhat-common.ts deleted file mode 100644 index cf4f96f0c8db..000000000000 --- a/packages/smock/src/common/hardhat-common.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* Imports: External */ -import { HardhatRuntimeEnvironment } from 'hardhat/types' -import { HardhatNetworkProvider } from 'hardhat/internal/hardhat-network/provider/provider' -import { fromHexString, toHexString } from '@eth-optimism/core-utils' - -/** - * Finds the "base" Ethereum provider of the current hardhat environment. - * - * Basically, hardhat uses a system of nested providers where each provider wraps the next and - * "provides" some extra features. When you're running on top of the "hardhat evm" the bottom of - * this series of providers is the "HardhatNetworkProvider": - * https://github.com/nomiclabs/hardhat/blob/master/packages/hardhat-core/src/internal/hardhat-network/provider/provider.ts - * This object has direct access to the node (provider._node), which in turn has direct access to - * the ethereumjs-vm instance (provider._node._vm). So it's quite useful to be able to find this - * object reliably! - * - * @param hre hardhat runtime environment to pull the base provider from. - * @return base hardhat network provider - */ -export const findBaseHardhatProvider = ( - runtime: HardhatRuntimeEnvironment -): HardhatNetworkProvider => { - // This function is pretty approximate. Haven't spent enough time figuring out if there's a more - // reliable way to get the base provider. I can imagine a future in which there's some circular - // references and this function ends up looping. So I'll just preempt this by capping the maximum - // search depth. - const maxLoopIterations = 1024 - let currentLoopIterations = 0 - - // Search by looking for the internal "_wrapped" variable. Base provider doesn't have this - // property (at least for now!). - let provider = runtime.network.provider - while ((provider as any)._wrapped !== undefined) { - provider = (provider as any)._wrapped - - // Just throw if we ever end up in (what seems to be) an infinite loop. - currentLoopIterations += 1 - if (currentLoopIterations > maxLoopIterations) { - throw new Error( - `[smock]: unable to find base hardhat provider. are you sure you're running locally?` - ) - } - } - - // TODO: Figure out a reliable way to do a type check here. Source for inspiration: - // https://github.com/nomiclabs/hardhat/blob/master/packages/hardhat-core/src/internal/hardhat-network/provider/provider.ts - return provider as any -} - -/** - * Converts a string into the fancy new address thing that ethereumjs-vm v5 expects while also - * maintaining backwards compatibility with ethereumjs-vm v4. - * - * @param address String address to convert into the fancy new address type. - * @returns Fancified address. - */ -export const toFancyAddress = (address: string): any => { - const fancyAddress = fromHexString(address) - ;(fancyAddress as any).buf = fromHexString(address) - ;(fancyAddress as any).toString = (encoding?: any) => { - if (encoding === undefined) { - return address.toLowerCase() - } else { - return fromHexString(address).toString(encoding) - } - } - return fancyAddress -} - -/** - * Same as toFancyAddress but in the opposite direction. - * - * @param fancyAddress Fancy address to turn into a string. - * @returns Way more boring address. - */ -export const fromFancyAddress = (fancyAddress: any): string => { - if (fancyAddress.buf) { - return toHexString(fancyAddress.buf) - } else { - return toHexString(fancyAddress) - } -} diff --git a/packages/smock/src/common/index.ts b/packages/smock/src/common/index.ts deleted file mode 100644 index 7ba5431003b1..000000000000 --- a/packages/smock/src/common/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './hardhat-common' diff --git a/packages/smock/src/index.ts b/packages/smock/src/index.ts deleted file mode 100644 index cd9c3218b87d..000000000000 --- a/packages/smock/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './smockit' -export * from './smoddit' diff --git a/packages/smock/src/smockit/binding.ts b/packages/smock/src/smockit/binding.ts deleted file mode 100644 index 782e1007bf3e..000000000000 --- a/packages/smock/src/smockit/binding.ts +++ /dev/null @@ -1,239 +0,0 @@ -/* Imports: External */ -import { HardhatNetworkProvider } from 'hardhat/internal/hardhat-network/provider/provider' -import { VmError } from '@nomiclabs/ethereumjs-vm/dist/exceptions' -import BN from 'bn.js' - -/* eslint-disable @typescript-eslint/no-var-requires */ -// Handle hardhat ^2.4.0 -let decodeRevertReason: (value: Buffer) => string -try { - decodeRevertReason = - require('hardhat/internal/hardhat-network/stack-traces/revert-reasons').decodeRevertReason -} catch (err) { - const { - ReturnData, - } = require('hardhat/internal/hardhat-network/provider/return-data') - decodeRevertReason = (value: Buffer) => { - const returnData = new ReturnData(value) - if (returnData.isErrorReturnData()) { - return returnData.decodeError() - } else { - return '' - } - } -} -// Handle hardhat ^2.2.0 -let TransactionExecutionError: any -try { - TransactionExecutionError = - require('hardhat/internal/hardhat-network/provider/errors').TransactionExecutionError -} catch (err) { - TransactionExecutionError = - require('hardhat/internal/core/providers/errors').TransactionExecutionError -} -/* eslint-enable @typescript-eslint/no-var-requires */ - -/* Imports: Internal */ -import { MockContract, SmockedVM } from './types' -import { fromFancyAddress, toFancyAddress } from '../common' - -/** - * Checks to see if smock has been initialized already. Basically just checking to see if we've - * attached smock state to the VM already. - * - * @param provider Base hardhat network provider to check. - * @return Whether or not the provider has already been modified to support smock. - */ -const isSmockInitialized = (provider: HardhatNetworkProvider): boolean => { - return (provider as any)._node._vm._smockState !== undefined -} - -/** - * Modifies a hardhat provider to be compatible with smock. - * - * @param provider Base hardhat network provider to modify. - */ -const initializeSmock = (provider: HardhatNetworkProvider): void => { - if (isSmockInitialized(provider)) { - return - } - - // Will need to reference these things. - const node = (provider as any)._node - const vm: SmockedVM = node._vm - - // Attach some extra state to the VM. - vm._smockState = { - mocks: {}, - calls: {}, - messages: [], - } - - // Wipe out our list of calls before each transaction. - vm.on('beforeTx', () => { - vm._smockState.calls = {} - }) - - // Watch for new EVM messages (call frames). - vm.on('beforeMessage', (message: any) => { - // Happens with contract creations. If the current message is a contract creation then it can't - // be a call to a smocked contract. - if (!message.to) { - return - } - - let target: string - if (message.delegatecall) { - target = fromFancyAddress(message._codeAddress) - } else { - target = fromFancyAddress(message.to) - } - - // Check if the target address is a smocked contract. - if (!(target in vm._smockState.mocks)) { - return - } - - // Initialize the array of calls to this smock if not done already. - if (!(target in vm._smockState.calls)) { - vm._smockState.calls[target] = [] - } - - // Record this message for later. - vm._smockState.calls[target].push(message.data) - vm._smockState.messages.push(message) - }) - - // Now *this* is a hack. - // Ethereumjs-vm passes `result` by *reference* into the `afterMessage` event. Mutating the - // `result` object here will actually mutate the result in the VM. Magic. - vm.on('afterMessage', async (result: any) => { - // We currently defer to contract creations, meaning we'll "unsmock" an address if a user - // later creates a contract at that address. Not sure how to handle this case. Very open to - // ideas. - if (result.createdAddress) { - const created = fromFancyAddress(result.createdAddress) - if (created in vm._smockState.mocks) { - delete vm._smockState.mocks[created] - } - } - - // Check if we have messages that need to be handled. - if (vm._smockState.messages.length === 0) { - return - } - - // Handle the last message that was pushed to the array of messages. This works because smock - // contracts never create new sub-calls (meaning this `afterMessage` event corresponds directly - // to a `beforeMessage` event emitted during a call to a smock contract). - const message = vm._smockState.messages.pop() - - let target: string - if (message.delegatecall) { - target = fromFancyAddress(message._codeAddress) - } else { - target = fromFancyAddress(message.to) - } - - // Not sure if this can ever actually happen? Just being safe. - if (!(target in vm._smockState.mocks)) { - return - } - - // Compute the mock return data. - const mock: MockContract = vm._smockState.mocks[target] - const { resolve, functionName, rawReturnValue, returnValue, gasUsed } = - await mock._smockit(message.data) - - // Set the mock return data, potentially set the `exceptionError` field if the user requested - // a revert. - result.gasUsed = new BN(gasUsed) - result.execResult.returnValue = returnValue - result.execResult.gasUsed = new BN(gasUsed) - result.execResult.exceptionError = - resolve === 'revert' ? new VmError('smocked revert' as any) : undefined - }) - - // Here we're fixing with hardhat's internal error management. Smock is a bit weird and messes - // with stack traces so we need to help hardhat out a bit when it comes to smock-specific - // errors. - const originalManagerErrorsFn = node._manageErrors.bind(node) - node._manageErrors = async ( - vmResult: any, - vmTrace: any, - vmTracerError?: any - ): Promise => { - if ( - vmResult.exceptionError && - vmResult.exceptionError.error === 'smocked revert' - ) { - return new TransactionExecutionError( - `VM Exception while processing transaction: revert ${decodeRevertReason( - vmResult.returnValue - )}` - ) - } - - return originalManagerErrorsFn(vmResult, vmTrace, vmTracerError) - } -} - -/** - * Attaches a smocked contract to a hardhat network provider. Will also modify the provider to be - * compatible with smock if not done already. - * - * @param mock Smocked contract to attach to a provider. - * @param provider Hardhat network provider to attach the contract to. - */ -export const bindSmock = async ( - mock: MockContract, - provider: HardhatNetworkProvider -): Promise => { - if (!isSmockInitialized(provider)) { - initializeSmock(provider) - } - - const vm: SmockedVM = (provider as any)._node._vm - const pStateManager = vm.pStateManager || vm.stateManager - - // Add mock to our list of mocks currently attached to the VM. - vm._smockState.mocks[mock.address.toLowerCase()] = mock - - // Set the contract code for our mock to 0x00 == STOP. Need some non-empty contract code because - // Solidity will sometimes throw if it's calling something without code (I forget the exact - // scenario that causes this throw). - await pStateManager.putContractCode( - toFancyAddress(mock.address), - Buffer.from('00', 'hex') - ) -} - -/** - * Detaches a smocked contract from a hardhat network provider. - * - * @param mock Smocked contract to detach to a provider, or an address. - * @param provider Hardhat network provider to detatch the contract from. - */ -export const unbindSmock = async ( - mock: MockContract | string, - provider: HardhatNetworkProvider -): Promise => { - if (!isSmockInitialized(provider)) { - initializeSmock(provider) - } - - const vm: SmockedVM = (provider as any)._node._vm - const pStateManager = vm.pStateManager || vm.stateManager - - // Add mock to our list of mocks currently attached to the VM. - const address = typeof mock === 'string' ? mock : mock.address.toLowerCase() - delete vm._smockState.mocks[address] - - // Set the contract code for our mock to 0x00 == STOP. Need some non-empty contract code because - // Solidity will sometimes throw if it's calling something without code (I forget the exact - // scenario that causes this throw). - await pStateManager.putContractCode( - toFancyAddress(address), - Buffer.from('', 'hex') - ) -} diff --git a/packages/smock/src/smockit/index.ts b/packages/smock/src/smockit/index.ts deleted file mode 100644 index 982826fd7d09..000000000000 --- a/packages/smock/src/smockit/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './smockit' -export * from './types' diff --git a/packages/smock/src/smockit/smockit.ts b/packages/smock/src/smockit/smockit.ts deleted file mode 100644 index 60196c81e78b..000000000000 --- a/packages/smock/src/smockit/smockit.ts +++ /dev/null @@ -1,334 +0,0 @@ -/* Imports: External */ -import hre from 'hardhat' -import { Contract, ContractFactory, ethers } from 'ethers' -import { toHexString, fromHexString } from '@eth-optimism/core-utils' - -/* Imports: Internal */ -import { - isArtifact, - isContract, - isContractFactory, - isInterface, - MockContract, - MockContractFunction, - MockReturnValue, - SmockedVM, - SmockOptions, - SmockSpec, -} from './types' -import { bindSmock, unbindSmock } from './binding' -import { makeRandomAddress } from '../utils' -import { findBaseHardhatProvider } from '../common' - -/** - * Generates an ethers Interface instance when given a smock spec. Meant for standardizing the - * various input types we might reasonably want to support. - * - * @param spec Smock specification object. Thing you want to base the interface on. - * @param hre Hardhat runtime environment. Used so we can - * @return Interface generated from the spec. - */ -const makeContractInterfaceFromSpec = async ( - spec: SmockSpec -): Promise => { - if (spec instanceof Contract) { - return spec.interface - } else if (spec instanceof ContractFactory) { - return spec.interface - } else if (spec instanceof ethers.utils.Interface) { - return spec - } else if (isInterface(spec)) { - return spec as any - } else if (isContractFactory(spec)) { - return (spec as any).interface - } else if (isContract(spec)) { - return (spec as any).interface - } else if (isArtifact(spec)) { - return new ethers.utils.Interface(spec.abi) - } else if (typeof spec === 'string') { - try { - return new ethers.utils.Interface(spec) - } catch (err) { - return (await (hre as any).ethers.getContractFactory(spec)).interface - } - } else { - return new ethers.utils.Interface(spec) - } -} - -/** - * Creates a mock contract function from a real contract function. - * - * @param contract Contract object to make a mock function for. - * @param functionName Name of the function to mock. - * @param vm Virtual machine reference, necessary for call assertions to work. - * @return Mock contract function. - */ -const smockifyFunction = ( - contract: Contract, - functionName: string, - vm: SmockedVM -): MockContractFunction => { - return { - reset: () => { - return - }, - get calls() { - return (vm._smockState.calls[contract.address.toLowerCase()] || []) - .map((calldataBuf: Buffer) => { - const sighash = toHexString(calldataBuf.slice(0, 4)) - const fragment = contract.interface.getFunction(sighash) - - let data: any = toHexString(calldataBuf) - try { - data = contract.interface.decodeFunctionData( - fragment.format(), - data - ) - } catch (e) { - console.error(e) - } - - return { - functionName: fragment.name, - functionSignature: fragment.format(), - data, - } - }) - .filter((functionResult: any) => { - return ( - functionResult.functionName === functionName || - functionResult.functionSignature === functionName - ) - }) - .map((functionResult: any) => { - return functionResult.data - }) - }, - will: { - get return() { - const fn: any = () => { - this.resolve = 'return' - this.returnValue = undefined - } - - fn.with = (returnValue?: MockReturnValue): void => { - this.resolve = 'return' - this.returnValue = returnValue - } - - return fn - }, - get revert() { - const fn: any = () => { - this.resolve = 'revert' - this.returnValue = undefined - } - - fn.with = (revertValue?: string): void => { - this.resolve = 'revert' - this.returnValue = revertValue - } - - return fn - }, - resolve: 'return', - }, - } -} - -/** - * Turns a specification into a mock contract. - * - * @param spec Smock contract specification. - * @param opts Optional additional settings. - */ -export const smockit = async ( - spec: SmockSpec, - opts: SmockOptions = {} -): Promise => { - // Only support native hardhat runtime, haven't bothered to figure it out for anything else. - if (hre.network.name !== 'hardhat') { - throw new Error( - `[smock]: smock is only compatible with the "hardhat" network, got: ${hre.network.name}` - ) - } - - // Find the provider object. See comments for `findBaseHardhatProvider` - const provider = findBaseHardhatProvider(hre) - - // Sometimes the VM hasn't been initialized by the time we get here, depending on what the user - // is doing with hardhat (e.g., sending a transaction before calling this function will - // initialize the vm). Initialize it here if it hasn't been already. - if ((provider as any)._node === undefined) { - await (provider as any)._init() - } - - // Generate the contract object that we're going to attach our fancy functions to. Doing it this - // way is nice because it "feels" more like a contract (as long as you're using ethers). - const contract = new ethers.Contract( - opts.address || makeRandomAddress(), - await makeContractInterfaceFromSpec(spec), - opts.provider || (hre as any).ethers.provider // TODO: Probably check that this exists. - ) as MockContract - - // We attach a wallet to the contract so that users can send transactions *from* a smock. - await hre.network.provider.request({ - method: 'hardhat_impersonateAccount', - params: [contract.address], - }) - - // Now we actually get the signer and attach it to the mock. - contract.wallet = await (hre as any).ethers.getSigner(contract.address) - - // Start by smocking the fallback. - contract.smocked = { - fallback: smockifyFunction( - contract, - 'fallback', - (provider as any)._node._vm - ), - } - - // Smock the rest of the contract functions. - for (const functionName of Object.keys(contract.functions)) { - contract.smocked[functionName] = smockifyFunction( - contract, - functionName, - (provider as any)._node._vm - ) - } - - // TODO: Make this less of a hack. - ;(contract as any)._smockit = async function (data: Buffer): Promise<{ - resolve: 'return' | 'revert' - functionName: string - rawReturnValue: any - returnValue: Buffer - gasUsed: number - }> { - let fn: any - try { - const sighash = toHexString(data.slice(0, 4)) - fn = this.interface.getFunction(sighash) - } catch (err) { - fn = null - } - - let params: any - let mockFn: any - if (fn !== null) { - params = this.interface.decodeFunctionData(fn, toHexString(data)) - mockFn = this.smocked[fn.name] || this.smocked[fn.format()] - } else { - params = toHexString(data) - mockFn = this.smocked.fallback - } - - const rawReturnValue = - mockFn.will?.returnValue instanceof Function - ? await mockFn.will.returnValue(...params) - : mockFn.will.returnValue - - let encodedReturnValue: string = '0x' - if (rawReturnValue !== undefined) { - if (mockFn.will?.resolve === 'revert') { - if (typeof rawReturnValue !== 'string') { - throw new Error( - `Smock: Tried to revert with a non-string (or non-bytes) type: ${typeof rawReturnValue}` - ) - } - - if (rawReturnValue.startsWith('0x')) { - encodedReturnValue = rawReturnValue - } else { - const errorface = new ethers.utils.Interface([ - { - inputs: [ - { - name: '_reason', - type: 'string', - }, - ], - name: 'Error', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - ]) - - encodedReturnValue = errorface.encodeFunctionData('Error', [ - rawReturnValue, - ]) - } - } else { - if (fn === null) { - encodedReturnValue = rawReturnValue - } else { - try { - encodedReturnValue = this.interface.encodeFunctionResult(fn, [ - rawReturnValue, - ]) - } catch (err) { - if (err.code === 'INVALID_ARGUMENT') { - try { - encodedReturnValue = this.interface.encodeFunctionResult( - fn, - rawReturnValue - ) - } catch { - if (typeof rawReturnValue !== 'string') { - throw new Error( - `Could not properly encode mock return value for ${fn.name}` - ) - } - - encodedReturnValue = rawReturnValue - } - } else { - throw err - } - } - } - } - } else { - if (fn === null) { - encodedReturnValue = '0x' - } else { - encodedReturnValue = '0x' + '00'.repeat(2048) - } - } - - return { - resolve: mockFn.will?.resolve, - functionName: fn ? fn.name : null, - rawReturnValue, - returnValue: fromHexString(encodedReturnValue), - gasUsed: mockFn.gasUsed || 0, - } - } - - await bindSmock(contract, provider) - - return contract -} - -/** - * Unbinds a mock contract (meaning the contract will no longer behave as a mock). - * - * @param mock Mock contract or address to unbind. - */ -export const unbind = async (mock: MockContract | string): Promise => { - // Only support native hardhat runtime, haven't bothered to figure it out for anything else. - if (hre.network.name !== 'hardhat') { - throw new Error( - `[smock]: smock is only compatible with the "hardhat" network, got: ${hre.network.name}` - ) - } - - // Find the provider object. See comments for `findBaseHardhatProvider` - const provider = findBaseHardhatProvider(hre) - - // Unbind the contract. - await unbindSmock(mock, provider) -} diff --git a/packages/smock/src/smockit/types.ts b/packages/smock/src/smockit/types.ts deleted file mode 100644 index 92d3fb5720c0..000000000000 --- a/packages/smock/src/smockit/types.ts +++ /dev/null @@ -1,136 +0,0 @@ -/* Imports: External */ -import { Artifact } from 'hardhat/types' -import { Contract, ContractFactory, ethers } from 'ethers' -import { Signer } from '@ethersproject/abstract-signer' -import { Provider } from '@ethersproject/abstract-provider' -import { JsonFragment, Fragment } from '@ethersproject/abi' - -export type SmockSpec = - | Artifact - | Contract - | ContractFactory - | ethers.utils.Interface - | string - | (JsonFragment | Fragment | string)[] - -export interface SmockOptions { - provider?: Provider - address?: string -} - -export type MockReturnValue = - | string - | Object - | any[] - | ((...params: any[]) => MockReturnValue) - -export interface MockContractFunction { - calls: any[] - - reset: () => void - - will: { - return: { - (): void - with: (returnValue?: MockReturnValue) => void - } - revert: { - (): void - with: ( - revertValue?: string | (() => string) | (() => Promise) - ) => void - } - resolve: 'return' | 'revert' - } -} - -export type MockContract = Contract & { - smocked: { - [name: string]: MockContractFunction - } - - wallet: Signer -} - -export interface SmockedVM { - _smockState: { - mocks: { - [address: string]: MockContract - } - calls: { - [address: string]: any[] - } - messages: any[] - } - - on: (event: string, callback: Function) => void - - stateManager?: { - putContractCode: (address: Buffer, code: Buffer) => Promise - } - - pStateManager?: { - putContractCode: (address: Buffer, code: Buffer) => Promise - } -} - -const isMockFunction = (obj: any): obj is MockContractFunction => { - return ( - obj && - obj.will && - obj.will.return && - obj.will.return.with && - obj.will.revert && - obj.will.revert.with - // TODO: obj.will.emit - ) -} - -export const isMockContract = (obj: any): obj is MockContract => { - return ( - obj && - obj.smocked && - obj.smocked.fallback && - Object.values(obj.smocked).every((smockFunction: any) => { - return isMockFunction(smockFunction) - }) - ) -} - -export const isInterface = (obj: any): boolean => { - return ( - obj && - obj.functions !== undefined && - obj.errors !== undefined && - obj.structs !== undefined && - obj.events !== undefined && - Array.isArray(obj.fragments) - ) -} - -export const isContract = (obj: any): boolean => { - return ( - obj && - obj.functions !== undefined && - obj.estimateGas !== undefined && - obj.callStatic !== undefined - ) -} - -export const isContractFactory = (obj: any): boolean => { - return obj && obj.interface !== undefined && obj.deploy !== undefined -} - -export const isArtifact = (obj: any): obj is Artifact => { - return ( - obj && - typeof obj._format === 'string' && - typeof obj.contractName === 'string' && - typeof obj.sourceName === 'string' && - Array.isArray(obj.abi) && - typeof obj.bytecode === 'string' && - typeof obj.deployedBytecode === 'string' && - obj.linkReferences && - obj.deployedLinkReferences - ) -} diff --git a/packages/smock/src/smoddit/index.ts b/packages/smock/src/smoddit/index.ts deleted file mode 100644 index fab117d1be05..000000000000 --- a/packages/smock/src/smoddit/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './smoddit' -export * from './types' diff --git a/packages/smock/src/smoddit/smoddit.ts b/packages/smock/src/smoddit/smoddit.ts deleted file mode 100644 index 8afc33e8d33d..000000000000 --- a/packages/smock/src/smoddit/smoddit.ts +++ /dev/null @@ -1,93 +0,0 @@ -/* External Imports */ -import hre from 'hardhat' -import { fromHexString } from '@eth-optimism/core-utils' - -/* Internal Imports */ -import { ModifiableContract, ModifiableContractFactory } from './types' -import { getStorageLayout, getStorageSlots } from './storage' -import { toHexString32 } from '../utils' -import { findBaseHardhatProvider, toFancyAddress } from '../common' - -/** - * Creates a modifiable contract factory. - * - * @param name Name of the contract to smoddify. - * @param signer Optional signer to attach to the factory. - * @returns Smoddified contract factory. - */ -export const smoddit = async ( - name: string, - signer?: any -): Promise => { - // Find the provider object. See comments for `findBaseHardhatProvider` - const provider = findBaseHardhatProvider(hre) - - // Sometimes the VM hasn't been initialized by the time we get here, depending on what the user - // is doing with hardhat (e.g., sending a transaction before calling this function will - // initialize the vm). Initialize it here if it hasn't been already. - if ((provider as any)._node === undefined) { - await (provider as any)._init() - } - - // Pull out a reference to the vm's state manager. - const vm: any = (provider as any)._node._vm - const pStateManager = vm.pStateManager || vm.stateManager - - const layout = await getStorageLayout(name) - const factory = (await (hre as any).ethers.getContractFactory( - name, - signer - )) as ModifiableContractFactory - - const originalDeployFn = factory.deploy.bind(factory) - factory.deploy = async (...args: any[]): Promise => { - const contract: ModifiableContract = await originalDeployFn(...args) - contract._smodded = {} - - const put = async (storage: any) => { - if (!storage) { - return - } - - const slots = getStorageSlots(layout, storage) - for (const slot of slots) { - await pStateManager.putContractStorage( - toFancyAddress(contract.address), - fromHexString(slot.hash.toLowerCase()), - fromHexString(slot.value) - ) - } - } - - const check = async (storage: any) => { - if (!storage) { - return true - } - - const slots = getStorageSlots(layout, storage) - for (const slot of slots) { - if ( - toHexString32( - await pStateManager.getContractStorage( - toFancyAddress(contract.address), - fromHexString(slot.hash.toLowerCase()) - ) - ) !== slot.value - ) { - return false - } - } - - return true - } - - contract.smodify = { - put, - check, - } - - return contract - } - - return factory -} diff --git a/packages/smock/src/smoddit/storage.ts b/packages/smock/src/smoddit/storage.ts deleted file mode 100644 index a1e6dd1ebe86..000000000000 --- a/packages/smock/src/smoddit/storage.ts +++ /dev/null @@ -1,185 +0,0 @@ -/* External Imports */ -import hre from 'hardhat' -import { Artifacts } from 'hardhat/internal/artifacts' -import { ethers } from 'ethers' -import { remove0x } from '@eth-optimism/core-utils' -import _ from 'lodash' - -/* Internal Imports */ -import { toHexString32 } from '../utils' - -interface InputSlot { - label: string - slot: number -} - -interface StorageSlot { - label: string - hash: string - value: string -} - -/** - * Reads the storage layout of a contract. - * - * @param name Name of the contract to get a storage layout for. - * @return Storage layout for the given contract name. - */ -export const getStorageLayout = async (name: string): Promise => { - const artifacts = new Artifacts(hre.config.paths.artifacts) - const { sourceName, contractName } = artifacts.readArtifactSync(name) - const buildInfo = await hre.artifacts.getBuildInfo( - `${sourceName}:${contractName}` - ) - const output = buildInfo.output.contracts[sourceName][contractName] - - if (!('storageLayout' in output)) { - throw new Error( - `Storage layout for ${name} not found. Did you forget to set the storage layout compiler option in your hardhat config? Read more: https://github.com/ethereum-optimism/smock#note-on-using-smoddit` - ) - } - - return (output as any).storageLayout -} - -/** - * Converts storage into a list of storage slots. - * - * @param storageLayout Contract storage layout. - * @param obj Storage object to convert. - * @returns List of storage slots. - */ -export const getStorageSlots = ( - storageLayout: any, - obj: any -): StorageSlot[] => { - const slots: StorageSlot[] = [] - const flat = flattenObject(obj) - - for (const key of Object.keys(flat)) { - const path = key.split('.') - const variableLabel = path[0] - - const variableDef = storageLayout.storage.find((vDef: any) => { - return vDef.label === variableLabel - }) - - if (!variableDef) { - throw new Error( - `Could not find a matching variable definition for ${variableLabel}` - ) - } - - const baseSlot = parseInt(variableDef.slot, 10) - const baseDepth = (variableDef.type.match(/t_mapping/g) || []).length - const slotLabel = - path.length > 1 + baseDepth ? path[path.length - 1] : 'default' - - const inputSlot = getInputSlots(storageLayout, variableDef.type).find( - (iSlot) => { - return iSlot.label === slotLabel - } - ) - - if (!inputSlot) { - throw new Error( - `Could not find a matching slot definition for ${slotLabel}` - ) - } - - let slotHash = toHexString32(baseSlot) - for (let i = 0; i < baseDepth; i++) { - slotHash = ethers.utils.keccak256( - toHexString32(path[i + 1]) + remove0x(slotHash) - ) - } - - slotHash = toHexString32( - ethers.BigNumber.from(slotHash).add(inputSlot.slot) - ) - - const slotValue = toHexString32( - `0x` + toHexString32(flat[key]).slice(2 + variableDef.offset * 2) - ) - - slots.push({ - label: key, - hash: slotHash, - value: slotValue, - }) - } - - return slots -} - -/** - * Flattens an object. - * - * @param obj Object to flatten. - * @param prefix Current object prefix (used recursively). - * @param res Current result (used recursively). - * @returns Flattened object. - */ -const flattenObject = ( - obj: any, - prefix: string = '', - res: any = {} -): Object => { - if (ethers.BigNumber.isBigNumber(obj)) { - res[prefix] = obj.toNumber() - return res - } else if (_.isString(obj) || _.isNumber(obj) || _.isBoolean(obj)) { - res[prefix] = obj - return res - } else if (_.isArray(obj)) { - for (let i = 0; i < obj.length; i++) { - const pre = _.isEmpty(prefix) ? `${i}` : `${prefix}.${i}` - flattenObject(obj[i], pre, res) - } - return res - } else if (_.isPlainObject(obj)) { - for (const key of Object.keys(obj)) { - const pre = _.isEmpty(prefix) ? key : `${prefix}.${key}` - flattenObject(obj[key], pre, res) - } - return res - } else { - throw new Error('Cannot flatten unsupported object type.') - } -} - -/** - * Gets the slot positions for a provided variable type. - * - * @param storageLayout Contract's storage layout. - * @param inputTypeName Variable type name. - * @returns Slot positions. - */ -const getInputSlots = ( - storageLayout: any, - inputTypeName: string -): InputSlot[] => { - const inputType = storageLayout.types[inputTypeName] - - if (inputType.encoding === 'mapping') { - return getInputSlots(storageLayout, inputType.value) - } else if (inputType.encoding === 'inplace') { - if (inputType.members) { - return inputType.members.map((member: any) => { - return { - label: member.label, - slot: member.slot, - } - }) - } else { - return [ - { - label: 'default', - slot: 0, - }, - ] - } - } else { - throw new Error(`Encoding type not supported: ${inputType.encoding}`) - } -} diff --git a/packages/smock/src/smoddit/types.ts b/packages/smock/src/smoddit/types.ts deleted file mode 100644 index 990c0fa6bb4a..000000000000 --- a/packages/smock/src/smoddit/types.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* External Imports */ -import { Contract, ContractFactory } from 'ethers' - -export interface Smodify { - put: (storage: any) => Promise - check: (storage: any) => Promise -} - -export interface Smodded { - [hash: string]: string -} - -export interface ModifiableContract extends Contract { - smodify: Smodify - _smodded: Smodded -} - -export interface ModifiableContractFactory extends ContractFactory { - deploy: (...args: any[]) => Promise -} diff --git a/packages/smock/src/utils/address-utils.ts b/packages/smock/src/utils/address-utils.ts deleted file mode 100644 index f1b92184be99..000000000000 --- a/packages/smock/src/utils/address-utils.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ethers } from 'ethers' - -export const makeRandomAddress = (): string => { - return ethers.utils.getAddress( - '0x' + - [...Array(40)] - .map(() => { - return Math.floor(Math.random() * 16).toString(16) - }) - .join('') - ) -} diff --git a/packages/smock/src/utils/hex-utils.ts b/packages/smock/src/utils/hex-utils.ts deleted file mode 100644 index d5309c4fa013..000000000000 --- a/packages/smock/src/utils/hex-utils.ts +++ /dev/null @@ -1,28 +0,0 @@ -/* External Imports */ -import { BigNumber } from 'ethers' -import { remove0x } from '@eth-optimism/core-utils' - -export const toHexString32 = ( - value: string | number | BigNumber | boolean -): string => { - if (typeof value === 'string' && value.startsWith('0x')) { - // Known bug here is that bytes20 and address are indistinguishable but have to be treated - // differently. Address gets padded on the right, bytes20 gets padded on the left. Address is - // way more common so I'm going with the strategy of treating all bytes20 like addresses. - // Sorry to anyone who wants to smodify bytes20 values :-/ requires a bit of rewrite to fix. - if (value.length === 42) { - return '0x' + remove0x(value).padStart(64, '0').toLowerCase() - } else { - return '0x' + remove0x(value).padEnd(64, '0').toLowerCase() - } - } else if (typeof value === 'boolean') { - return '0x' + `${value ? 1 : 0}`.padStart(64, '0') - } else { - return ( - '0x' + - remove0x(BigNumber.from(value).toHexString()) - .padStart(64, '0') - .toLowerCase() - ) - } -} diff --git a/packages/smock/src/utils/index.ts b/packages/smock/src/utils/index.ts deleted file mode 100644 index 81cc11ef60c2..000000000000 --- a/packages/smock/src/utils/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './hex-utils' -export * from './address-utils' diff --git a/packages/smock/test/contracts/SimpleStorageGetter.sol b/packages/smock/test/contracts/SimpleStorageGetter.sol deleted file mode 100644 index 5e5564807d56..000000000000 --- a/packages/smock/test/contracts/SimpleStorageGetter.sol +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; -pragma experimental ABIEncoderV2; - -contract SimpleStorageGetter { - struct SimpleStruct { - uint256 valueA; - bool valueB; - } - - address internal _address; - uint256 internal _constructorUint256; - uint256 internal _uint256; - bool internal _bool; - SimpleStruct internal _SimpleStruct; - mapping (uint256 => uint256) _uint256Map; - mapping (uint256 => mapping (uint256 => uint256)) _uint256NestedMap; - mapping (bytes5 => bool) _bytes5ToBoolMap; - mapping (address => bool) _addressToBoolMap; - mapping (address => address) _addressToAddressMap; - - // Testing storage slot packing. - bool internal _packedA; - address internal _packedB; - - // Regression for #1275. - uint256 internal __packingSpacerUnused1; // Spacer to avoid packing with the above two. - bool public booleanOne = true; - bool public booleanTwo = true; - - constructor( - uint256 _inA - ) { - _constructorUint256 = _inA; - } - - function getConstructorUint256() - public - view - returns ( - uint256 _out - ) - { - return _constructorUint256; - } - - function getUint256() - public - view - returns ( - uint256 _out - ) - { - return _uint256; - } - - function setUint256( - uint256 _in - ) - public - { - _uint256 = _in; - } - - function getBool() - public - view - returns ( - bool _out - ) - { - return _bool; - } - - function getAddress() - public - view - returns ( - address _out - ) - { - return _address; - } - - function getSimpleStruct() - public - view - returns ( - SimpleStruct memory _out - ) - { - return _SimpleStruct; - } - - function getUint256MapValue( - uint256 _key - ) - public - view - returns ( - uint256 _out - ) - { - return _uint256Map[_key]; - } - - function getNestedUint256MapValue( - uint256 _keyA, - uint256 _keyB - ) - public - view - returns ( - uint256 _out - ) - { - return _uint256NestedMap[_keyA][_keyB]; - } - - function getBytes5ToBoolMapValue( - bytes5 _key - ) - public - view - returns ( - bool _out - ) - { - return _bytes5ToBoolMap[_key]; - } - - function getAddressToBoolMapValue( - address _key - ) - public - view - returns ( - bool _out - ) - { - return _addressToBoolMap[_key]; - } - - function getAddressToAddressMapValue( - address _key - ) - public - view - returns ( - address _out - ) - { - return _addressToAddressMap[_key]; - } - - function getPackedAddress() - public - view - returns ( - address - ) - { - return _packedB; - } -} diff --git a/packages/smock/test/contracts/TestHelpers_BasicReturnContract.sol b/packages/smock/test/contracts/TestHelpers_BasicReturnContract.sol deleted file mode 100644 index 29567da21471..000000000000 --- a/packages/smock/test/contracts/TestHelpers_BasicReturnContract.sol +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; -pragma experimental ABIEncoderV2; - -contract TestHelpers_BasicReturnContract { - fallback() - external - {} - - function empty() - public - {} - - function getBoolean() - public - returns ( - bool _out1 - ) - {} - - function getUint256() - public - returns ( - uint256 _out1 - ) - {} - - function getBytes32() - public - returns ( - bytes32 _out1 - ) - {} - - function getBytes() - public - returns ( - bytes memory _out1 - ) - {} - - function getString() - public - returns ( - string memory _out1 - ) - {} - - function getInputtedBoolean( - bool _in1 - ) - public - returns ( - bool _out1 - ) - {} - - function getInputtedUint256( - uint256 _in1 - ) - public - returns ( - uint256 _out1 - ) - {} - - function getInputtedBytes32( - bytes32 _in1 - ) - public - returns ( - bytes32 _out1 - ) - {} - - struct StructFixedSize { - bool valBoolean; - uint256 valUint256; - bytes32 valBytes32; - } - - function getStructFixedSize() - public - returns ( - StructFixedSize memory _out1 - ) - {} - - struct StructDynamicSize { - bytes valBytes; - string valString; - } - - function getStructDynamicSize() - public - returns ( - StructDynamicSize memory _out1 - ) - {} - - struct StructMixedSize { - bool valBoolean; - uint256 valUint256; - bytes32 valBytes32; - bytes valBytes; - string valString; - } - - function getStructMixedSize() - public - returns ( - StructMixedSize memory _out1 - ) - {} - - struct StructNested { - StructFixedSize valStructFixedSize; - StructDynamicSize valStructDynamicSize; - } - - function getStructNested() - public - returns ( - StructNested memory _out1 - ) - {} - - function getArrayUint256() - public - returns ( - uint256[] memory _out - ) - {} - - function getMultipleUint256Arrays() - public - returns ( - uint256[] memory, - uint256[] memory - ) - {} - - function overloadedFunction( - uint256 _paramA, - uint256 _paramB - ) - public - returns ( - uint256 - ) - {} - - function overloadedFunction( - uint256 - ) - public - returns ( - uint256 - ) - {} -} diff --git a/packages/smock/test/contracts/TestHelpers_EmptyContract.sol b/packages/smock/test/contracts/TestHelpers_EmptyContract.sol deleted file mode 100644 index 009bb51c9493..000000000000 --- a/packages/smock/test/contracts/TestHelpers_EmptyContract.sol +++ /dev/null @@ -1,4 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -contract TestHelpers_EmptyContract {} diff --git a/packages/smock/test/contracts/TestHelpers_MockCaller.sol b/packages/smock/test/contracts/TestHelpers_MockCaller.sol deleted file mode 100644 index 818f3d77087a..000000000000 --- a/packages/smock/test/contracts/TestHelpers_MockCaller.sol +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -contract TestHelpers_MockCaller { - function callMock(address _target, bytes memory _data) public { - _target.call(_data); - } -} diff --git a/packages/smock/test/contracts/TestHelpers_SenderAssertions.sol b/packages/smock/test/contracts/TestHelpers_SenderAssertions.sol deleted file mode 100644 index 04ec487f18bc..000000000000 --- a/packages/smock/test/contracts/TestHelpers_SenderAssertions.sol +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; - -contract TestHelpers_SenderAssertions { - function getSender() - public - view - returns ( - address - ) - { - return msg.sender; - } -} diff --git a/packages/smock/test/smockit/call-assertions.spec.ts b/packages/smock/test/smockit/call-assertions.spec.ts deleted file mode 100644 index f4c920410669..000000000000 --- a/packages/smock/test/smockit/call-assertions.spec.ts +++ /dev/null @@ -1,72 +0,0 @@ -/* Imports: External */ -import hre from 'hardhat' -import { expect } from 'chai' -import { Contract } from 'ethers' - -/* Imports: Internal */ -import { MockContract, smockit } from '../../src' - -describe('[smock]: call assertion tests', () => { - const ethers = (hre as any).ethers - - let mock: MockContract - beforeEach(async () => { - mock = await smockit('TestHelpers_BasicReturnContract') - }) - - let mockCaller: Contract - before(async () => { - const mockCallerFactory = await ethers.getContractFactory( - 'TestHelpers_MockCaller' - ) - mockCaller = await mockCallerFactory.deploy() - }) - - describe('call assertions for functions', () => { - it('should be able to make assertions about a non-overloaded function', async () => { - mock.smocked.getInputtedUint256.will.return.with(0) - - const expected1 = ethers.BigNumber.from(1234) - await mockCaller.callMock( - mock.address, - mock.interface.encodeFunctionData('getInputtedUint256(uint256)', [ - expected1, - ]) - ) - - expect(mock.smocked.getInputtedUint256.calls[0]).to.deep.equal([ - expected1, - ]) - }) - - it('should be able to make assertions about both versions of an overloaded function', async () => { - mock.smocked['overloadedFunction(uint256)'].will.return.with(0) - mock.smocked['overloadedFunction(uint256,uint256)'].will.return.with(0) - - const expected1 = ethers.BigNumber.from(1234) - await mockCaller.callMock( - mock.address, - mock.interface.encodeFunctionData('overloadedFunction(uint256)', [ - expected1, - ]) - ) - - expect( - mock.smocked['overloadedFunction(uint256)'].calls[0] - ).to.deep.equal([expected1]) - - const expected2 = ethers.BigNumber.from(5678) - await mockCaller.callMock( - mock.address, - mock.interface.encodeFunctionData( - 'overloadedFunction(uint256,uint256)', - [expected2, expected2] - ) - ) - - expect( - mock.smocked['overloadedFunction(uint256,uint256)'].calls[0] - ).to.deep.equal([expected2, expected2]) - }) - }) -}) diff --git a/packages/smock/test/smockit/function-manipulation.spec.ts b/packages/smock/test/smockit/function-manipulation.spec.ts deleted file mode 100644 index 3d0379614a83..000000000000 --- a/packages/smock/test/smockit/function-manipulation.spec.ts +++ /dev/null @@ -1,710 +0,0 @@ -/* Imports: External */ -import hre from 'hardhat' -import { expect } from 'chai' -import { toPlainObject } from 'lodash' -import { BigNumber } from 'ethers' - -/* Imports: Internal */ -import { MockContract, smockit } from '../../src' - -describe('[smock]: function manipulation tests', () => { - const ethers = (hre as any).ethers - - let mock: MockContract - beforeEach(async () => { - mock = await smockit('TestHelpers_BasicReturnContract') - }) - - describe('manipulating fallback functions', () => { - it('should return with no data by default', async () => { - const expected = '0x' - - expect( - await ethers.provider.call({ - to: mock.address, - }) - ).to.equal(expected) - }) - - it('should be able to make a fallback function return without any data', async () => { - const expected = '0x' - mock.smocked.fallback.will.return() - - expect( - await ethers.provider.call({ - to: mock.address, - }) - ).to.equal(expected) - }) - - it('should be able to make a fallback function return with data', async () => { - const expected = '0x1234123412341234' - mock.smocked.fallback.will.return.with(expected) - - expect( - await ethers.provider.call({ - to: mock.address, - }) - ).to.equal(expected) - }) - - it('should be able to make a fallback function revert without any data', async () => { - mock.smocked.fallback.will.revert() - - await expect( - ethers.provider.call({ - to: mock.address, - }) - ).to.be.reverted - }) - - it('should be able to make a fallback function revert with a string', async () => { - const expected = 'this is a revert message' - - mock.smocked.fallback.will.revert.with(expected) - - await expect( - ethers.provider.call({ - to: mock.address, - }) - ).to.be.revertedWith(expected) - }) - - it('should be able to make a fallback function emit an event', async () => { - // TODO - }) - - it('should be able to change behaviors', async () => { - mock.smocked.fallback.will.revert() - - await expect( - ethers.provider.call({ - to: mock.address, - }) - ).to.be.reverted - - const expected = '0x' - mock.smocked.fallback.will.return() - - expect( - await ethers.provider.call({ - to: mock.address, - }) - ).to.equal(expected) - }) - - describe.skip('resetting the fallback function', () => { - it('should go back to default behavior when reset', async () => { - mock.smocked.fallback.will.revert() - - await expect( - ethers.provider.call({ - to: mock.address, - }) - ).to.be.reverted - - const expected = '0x' - mock.smocked.fallback.reset() - - expect( - await ethers.provider.call({ - to: mock.address, - }) - ).to.equal(expected) - }) - }) - }) - - describe('manipulating functions', () => { - it('should be able to make a function return without any data', async () => { - const expected = [] - mock.smocked.empty.will.return() - - expect(await mock.callStatic.empty()).to.deep.equal(expected) - }) - - it('should be able to make a function revert without any data', async () => { - mock.smocked.empty.will.revert() - - await expect(mock.callStatic.empty()).to.be.reverted - }) - - it('should be able to make a function emit an event', async () => { - // TODO - }) - - describe('overloaded functions', () => { - it('should be able to modify both versions of an overloaded function', async () => { - const expected1 = 1234 - const expected2 = 5678 - mock.smocked['overloadedFunction(uint256)'].will.return.with(expected1) - mock.smocked['overloadedFunction(uint256,uint256)'].will.return.with( - expected2 - ) - expect( - await mock.callStatic['overloadedFunction(uint256)'](0) - ).to.equal(expected1) - expect( - await mock.callStatic['overloadedFunction(uint256,uint256)'](0, 0) - ).to.equal(expected2) - }) - }) - - describe('returning with data', () => { - describe('fixed data types', () => { - describe('default behaviors', () => { - it('should return false for a boolean', async () => { - const expected = false - - expect(await mock.callStatic.getBoolean()).to.equal(expected) - }) - - it('should return zero for a uint256', async () => { - const expected = 0 - - expect(await mock.callStatic.getUint256()).to.equal(expected) - }) - - it('should return 32 zero bytes for a bytes32', async () => { - const expected = - '0x0000000000000000000000000000000000000000000000000000000000000000' - - expect(await mock.callStatic.getBytes32()).to.equal(expected) - }) - }) - - describe('from a specified value', () => { - it('should be able to return a boolean', async () => { - const expected = true - mock.smocked.getBoolean.will.return.with(expected) - - expect(await mock.callStatic.getBoolean()).to.equal(expected) - }) - - it('should be able to return a uint256', async () => { - const expected = 1234 - mock.smocked.getUint256.will.return.with(expected) - - expect(await mock.callStatic.getUint256()).to.equal(expected) - }) - - it('should be able to return a bytes32', async () => { - const expected = - '0x1234123412341234123412341234123412341234123412341234123412341234' - mock.smocked.getBytes32.will.return.with(expected) - - expect(await mock.callStatic.getBytes32()).to.equal(expected) - }) - }) - - describe('from a function', () => { - describe('without input arguments', () => { - it('should be able to return a boolean', async () => { - const expected = true - mock.smocked.getBoolean.will.return.with(() => { - return expected - }) - - expect(await mock.callStatic.getBoolean()).to.equal(expected) - }) - - it('should be able to return a uint256', async () => { - const expected = 1234 - mock.smocked.getUint256.will.return.with(() => { - return expected - }) - - expect(await mock.callStatic.getUint256()).to.equal(expected) - }) - - it('should be able to return a bytes32', async () => { - const expected = - '0x1234123412341234123412341234123412341234123412341234123412341234' - mock.smocked.getBytes32.will.return.with(() => { - return expected - }) - - expect(await mock.callStatic.getBytes32()).to.equal(expected) - }) - }) - - describe('with input arguments', () => { - it('should be able to return a boolean', async () => { - const expected = true - mock.smocked.getInputtedBoolean.will.return.with( - (arg1: boolean) => { - return arg1 - } - ) - - expect( - await mock.callStatic.getInputtedBoolean(expected) - ).to.equal(expected) - }) - - it('should be able to return a uint256', async () => { - const expected = 1234 - mock.smocked.getInputtedUint256.will.return.with( - (arg1: number) => { - return arg1 - } - ) - - expect( - await mock.callStatic.getInputtedUint256(expected) - ).to.equal(expected) - }) - - it('should be able to return a bytes32', async () => { - const expected = - '0x1234123412341234123412341234123412341234123412341234123412341234' - mock.smocked.getInputtedBytes32.will.return.with( - (arg1: string) => { - return arg1 - } - ) - - expect( - await mock.callStatic.getInputtedBytes32(expected) - ).to.equal(expected) - }) - }) - }) - - describe('from an asynchronous function', () => { - describe('without input arguments', () => { - it('should be able to return a boolean', async () => { - const expected = async () => { - return true - } - mock.smocked.getBoolean.will.return.with(async () => { - return expected() - }) - - expect(await mock.callStatic.getBoolean()).to.equal( - await expected() - ) - }) - - it('should be able to return a uint256', async () => { - const expected = async () => { - return 1234 - } - mock.smocked.getUint256.will.return.with(async () => { - return expected() - }) - - expect(await mock.callStatic.getUint256()).to.equal( - await expected() - ) - }) - - it('should be able to return a bytes32', async () => { - const expected = async () => { - return '0x1234123412341234123412341234123412341234123412341234123412341234' - } - mock.smocked.getBytes32.will.return.with(async () => { - return expected() - }) - - expect(await mock.callStatic.getBytes32()).to.equal( - await expected() - ) - }) - }) - }) - - describe.skip('resetting function behavior', () => { - describe('for a boolean', () => { - it('should return false after resetting', async () => { - const expected1 = true - mock.smocked.getBoolean.will.return.with(expected1) - - expect(await mock.callStatic.getBoolean()).to.equal(expected1) - - const expected2 = false - mock.smocked.getBoolean.reset() - - expect(await mock.callStatic.getBoolean()).to.equal(expected2) - }) - - it('should be able to reset and change behaviors', async () => { - const expected1 = true - mock.smocked.getBoolean.will.return.with(expected1) - - expect(await mock.callStatic.getBoolean()).to.equal(expected1) - - const expected2 = false - mock.smocked.getBoolean.reset() - - expect(await mock.callStatic.getBoolean()).to.equal(expected2) - - const expected3 = true - mock.smocked.getBoolean.will.return.with(expected3) - - expect(await mock.callStatic.getBoolean()).to.equal(expected3) - }) - }) - - describe('for a uint256', () => { - it('should return zero after resetting', async () => { - const expected1 = 1234 - mock.smocked.getUint256.will.return.with(expected1) - - expect(await mock.callStatic.getUint256()).to.equal(expected1) - - const expected2 = 0 - mock.smocked.getUint256.reset() - - expect(await mock.callStatic.getUint256()).to.equal(expected2) - }) - - it('should be able to reset and change behaviors', async () => { - const expected1 = 1234 - mock.smocked.getUint256.will.return.with(expected1) - - expect(await mock.callStatic.getUint256()).to.equal(expected1) - - const expected2 = 0 - mock.smocked.getUint256.reset() - - expect(await mock.callStatic.getUint256()).to.equal(expected2) - - const expected3 = 4321 - mock.smocked.getUint256.will.return.with(expected3) - - expect(await mock.callStatic.getUint256()).to.equal(expected3) - }) - }) - - describe('for a bytes32', () => { - it('should return 32 zero bytes after resetting', async () => { - const expected1 = - '0x1234123412341234123412341234123412341234123412341234123412341234' - mock.smocked.getBytes32.will.return.with(expected1) - - expect(await mock.callStatic.getBytes32()).to.equal(expected1) - - const expected2 = - '0x0000000000000000000000000000000000000000000000000000000000000000' - mock.smocked.getBytes32.reset() - - expect(await mock.callStatic.getBytes32()).to.equal(expected2) - }) - - it('should be able to reset and change behaviors', async () => { - const expected1 = - '0x1234123412341234123412341234123412341234123412341234123412341234' - mock.smocked.getBytes32.will.return.with(expected1) - - expect(await mock.callStatic.getBytes32()).to.equal(expected1) - - const expected2 = - '0x0000000000000000000000000000000000000000000000000000000000000000' - mock.smocked.getBytes32.reset() - - expect(await mock.callStatic.getBytes32()).to.equal(expected2) - - const expected3 = - '0x4321432143214321432143214321432143214321432143214321432143214321' - mock.smocked.getBytes32.will.return.with(expected3) - - expect(await mock.callStatic.getBytes32()).to.equal(expected3) - }) - }) - }) - }) - - describe('dynamic data types', () => { - describe('from a specified value', () => { - it('should be able to return a bytes value', async () => { - const expected = - '0x56785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678' - mock.smocked.getBytes.will.return.with(expected) - - expect(await mock.callStatic.getBytes()).to.equal(expected) - }) - - it('should be able to return a string value', async () => { - const expected = 'this is an expected return string' - mock.smocked.getString.will.return.with(expected) - - expect(await mock.callStatic.getString()).to.equal(expected) - }) - - it('should be able to return a struct with fixed size values', async () => { - const expected = { - valBoolean: true, - valUint256: BigNumber.from(1234), - valBytes32: - '0x1234123412341234123412341234123412341234123412341234123412341234', - } - mock.smocked.getStructFixedSize.will.return.with(expected) - - const result = toPlainObject( - await mock.callStatic.getStructFixedSize() - ) - expect(result.valBoolean).to.equal(expected.valBoolean) - expect(result.valUint256).to.deep.equal(expected.valUint256) - expect(result.valBytes32).to.equal(expected.valBytes32) - }) - - it('should be able to return a struct with dynamic size values', async () => { - const expected = { - valBytes: - '0x56785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678', - valString: 'this is an expected return string', - } - mock.smocked.getStructDynamicSize.will.return.with(expected) - - const result = toPlainObject( - await mock.callStatic.getStructDynamicSize() - ) - expect(result.valBytes).to.equal(expected.valBytes) - expect(result.valString).to.equal(expected.valString) - }) - - it('should be able to return a struct with both fixed and dynamic size values', async () => { - const expected = { - valBoolean: true, - valUint256: BigNumber.from(1234), - valBytes32: - '0x1234123412341234123412341234123412341234123412341234123412341234', - valBytes: - '0x56785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678', - valString: 'this is an expected return string', - } - mock.smocked.getStructMixedSize.will.return.with(expected) - - const result = toPlainObject( - await mock.callStatic.getStructMixedSize() - ) - expect(result.valBoolean).to.equal(expected.valBoolean) - expect(result.valUint256).to.deep.equal(expected.valUint256) - expect(result.valBytes32).to.equal(expected.valBytes32) - expect(result.valBytes).to.equal(expected.valBytes) - expect(result.valString).to.equal(expected.valString) - }) - - it('should be able to return a nested struct', async () => { - const expected = { - valStructFixedSize: { - valBoolean: true, - valUint256: BigNumber.from(1234), - valBytes32: - '0x1234123412341234123412341234123412341234123412341234123412341234', - }, - valStructDynamicSize: { - valBytes: - '0x56785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678567856785678', - valString: 'this is an expected return string', - }, - } - mock.smocked.getStructNested.will.return.with(expected) - - const result = toPlainObject( - await mock.callStatic.getStructNested() - ) - expect(result.valStructFixedSize[0]).to.deep.equal( - expected.valStructFixedSize.valBoolean - ) - expect(result.valStructFixedSize[1]).to.deep.equal( - expected.valStructFixedSize.valUint256 - ) - expect(result.valStructFixedSize[2]).to.deep.equal( - expected.valStructFixedSize.valBytes32 - ) - expect(result.valStructDynamicSize[0]).to.deep.equal( - expected.valStructDynamicSize.valBytes - ) - expect(result.valStructDynamicSize[1]).to.deep.equal( - expected.valStructDynamicSize.valString - ) - }) - - it('should be able to return an array of uint256 values', async () => { - const expected = [1234, 2345, 3456, 4567, 5678, 6789].map((n) => { - return BigNumber.from(n) - }) - mock.smocked.getArrayUint256.will.return.with(expected) - - const result = await mock.callStatic.getArrayUint256() - for (let i = 0; i < result.length; i++) { - expect(result[i]).to.deep.equal(expected[i]) - } - }) - - it('should be able to return multiple arrays of uint256 values', async () => { - const expected = [ - [1234, 2345, 3456, 4567, 5678, 6789].map((n) => { - return BigNumber.from(n) - }), - [1234, 2345, 3456, 4567, 5678, 6789].map((n) => { - return BigNumber.from(n) - }), - ] - mock.smocked.getMultipleUint256Arrays.will.return.with(expected) - - const result = await mock.callStatic.getMultipleUint256Arrays() - for (let i = 0; i < result.length; i++) { - for (let j = 0; j < result[i].length; j++) { - expect(result[i][j]).to.deep.equal(expected[i][j]) - } - } - }) - }) - }) - }) - - describe('reverting with data', () => { - describe('from a specified value', () => { - it('should be able to revert with a string value', async () => { - const expected = 'this is a revert string' - mock.smocked.getUint256.will.revert.with(expected) - - await expect(mock.callStatic.getUint256()).to.be.revertedWith( - expected - ) - }) - }) - - describe('from a function', () => { - it('should be able to revert with a string value', async () => { - const expected = 'this is a revert string' - mock.smocked.getUint256.will.revert.with(() => { - return expected - }) - - await expect(mock.callStatic.getUint256()).to.be.revertedWith( - expected - ) - }) - }) - - describe('from an asynchronous function', () => { - it('should be able to revert with a string value', async () => { - const expected = async () => { - return 'this is a revert string' - } - mock.smocked.getUint256.will.revert.with(async () => { - return expected() - }) - - await expect(mock.callStatic.getUint256()).to.be.revertedWith( - await expected() - ) - }) - }) - - describe.skip('resetting function behavior', async () => { - describe('for a boolean', () => { - it('should return false after resetting', async () => { - const expected1 = 'this is a revert string' - mock.smocked.getBoolean.will.revert.with(expected1) - - await expect(mock.callStatic.getBoolean()).to.be.revertedWith( - expected1 - ) - - const expected2 = false - mock.smocked.getBoolean.reset() - - expect(await mock.callStatic.getBoolean()).to.equal(expected2) - }) - - it('should be able to reset and change behaviors', async () => { - const expected1 = 'this is a revert string' - mock.smocked.getBoolean.will.revert.with(expected1) - - await expect(mock.callStatic.getBoolean()).to.be.revertedWith( - expected1 - ) - - const expected2 = false - mock.smocked.getBoolean.reset() - - expect(await mock.callStatic.getBoolean()).to.equal(expected2) - - const expected3 = true - mock.smocked.getBoolean.will.return.with(expected3) - - expect(await mock.callStatic.getBoolean()).to.equal(expected3) - }) - }) - - describe('for a uint256', () => { - it('should return zero after resetting', async () => { - const expected1 = 'this is a revert string' - mock.smocked.getUint256.will.revert.with(expected1) - - await expect(mock.callStatic.getUint256()).to.be.revertedWith( - expected1 - ) - - const expected2 = 0 - mock.smocked.getUint256.reset() - - expect(await mock.callStatic.getUint256()).to.equal(expected2) - }) - - it('should be able to reset and change behaviors', async () => { - const expected1 = 'this is a revert string' - mock.smocked.getUint256.will.revert.with(expected1) - - await expect(mock.callStatic.getUint256()).to.be.revertedWith( - expected1 - ) - - const expected2 = 0 - mock.smocked.getUint256.reset() - - expect(await mock.callStatic.getUint256()).to.equal(expected2) - - const expected3 = 1234 - mock.smocked.getUint256.will.return.with(expected3) - - expect(await mock.callStatic.getUint256()).to.equal(expected3) - }) - }) - - describe('for a bytes32', () => { - it('should return 32 zero bytes after resetting', async () => { - const expected1 = 'this is a revert string' - mock.smocked.getBytes32.will.revert.with(expected1) - - await expect(mock.callStatic.getBytes32()).to.be.revertedWith( - expected1 - ) - - const expected2 = - '0x0000000000000000000000000000000000000000000000000000000000000000' - mock.smocked.getBytes32.reset() - - expect(await mock.callStatic.getBytes32()).to.equal(expected2) - }) - - it('should be able to reset and change behaviors', async () => { - const expected1 = 'this is a revert string' - mock.smocked.getBytes32.will.revert.with(expected1) - - await expect(mock.callStatic.getBytes32()).to.be.revertedWith( - expected1 - ) - - const expected2 = - '0x0000000000000000000000000000000000000000000000000000000000000000' - mock.smocked.getBytes32.reset() - - expect(await mock.callStatic.getBytes32()).to.equal(expected2) - - const expected3 = - '0x4321432143214321432143214321432143214321432143214321432143214321' - mock.smocked.getBytes32.will.return.with(expected3) - - expect(await mock.callStatic.getBytes32()).to.equal(expected3) - }) - }) - }) - }) - }) -}) diff --git a/packages/smock/test/smockit/sending-from-mocks.spec.ts b/packages/smock/test/smockit/sending-from-mocks.spec.ts deleted file mode 100644 index cdc4cd13e53f..000000000000 --- a/packages/smock/test/smockit/sending-from-mocks.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* Imports: External */ -import hre from 'hardhat' -import { expect } from 'chai' -import { Contract } from 'ethers' - -/* Imports: Internal */ -import { smockit } from '../../src' - -describe('[smock]: sending transactions from smock contracts', () => { - const ethers = (hre as any).ethers - - let TestHelpers_SenderAssertions: Contract - before(async () => { - TestHelpers_SenderAssertions = await ( - await ethers.getContractFactory('TestHelpers_SenderAssertions') - ).deploy() - }) - - it('should attach a signer for a mock with a random address', async () => { - const mock = await smockit('TestHelpers_BasicReturnContract') - - expect( - await TestHelpers_SenderAssertions.connect(mock.wallet).getSender() - ).to.equal(mock.address) - }) - - it('should attach a signer for a mock with a fixed address', async () => { - const mock = await smockit('TestHelpers_BasicReturnContract', { - address: '0x1234123412341234123412341234123412341234', - }) - - expect( - await TestHelpers_SenderAssertions.connect(mock.wallet).getSender() - ).to.equal(mock.address) - }) -}) diff --git a/packages/smock/test/smockit/smock-initialization.spec.ts b/packages/smock/test/smockit/smock-initialization.spec.ts deleted file mode 100644 index 4b8a48410f91..000000000000 --- a/packages/smock/test/smockit/smock-initialization.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -/* Imports: External */ -import hre from 'hardhat' -import { expect } from 'chai' - -/* Imports: Internal */ -import { smockit, isMockContract } from '../../src' - -describe('[smock]: initialization tests', () => { - const ethers = (hre as any).ethers - - describe('initialization: ethers objects', () => { - it('should be able to create a SmockContract from an ethers ContractFactory', async () => { - const spec = await ethers.getContractFactory('TestHelpers_EmptyContract') - const mock = await smockit(spec) - - expect(isMockContract(mock)).to.be.true - }) - - it('should be able to create a SmockContract from an ethers Contract', async () => { - const factory = await ethers.getContractFactory( - 'TestHelpers_EmptyContract' - ) - - const spec = await factory.deploy() - const mock = await smockit(spec) - - expect(isMockContract(mock)).to.be.true - }) - - it('should be able to create a SmockContract from an ethers Interface', async () => { - const factory = await ethers.getContractFactory( - 'TestHelpers_EmptyContract' - ) - - const spec = factory.interface - const mock = await smockit(spec) - - expect(isMockContract(mock)).to.be.true - }) - }) - - describe('initialization: other', () => { - it('should be able to create a SmockContract from a contract name', async () => { - const spec = 'TestHelpers_EmptyContract' - const mock = await smockit(spec) - - expect(isMockContract(mock)).to.be.true - }) - - it('should be able to create a SmockContract from a JSON contract artifact object', async () => { - const artifact = await hre.artifacts.readArtifact( - 'TestHelpers_BasicReturnContract' - ) - const spec = artifact - const mock = await smockit(spec) - - expect(isMockContract(mock)).to.be.true - }) - - it('should be able to create a SmockContract from a JSON contract ABI object', async () => { - const artifact = await hre.artifacts.readArtifact( - 'TestHelpers_BasicReturnContract' - ) - const spec = artifact.abi - const mock = await smockit(spec) - - expect(isMockContract(mock)).to.be.true - }) - - it('should be able to create a SmockContract from a JSON contract ABI string', async () => { - const artifact = await hre.artifacts.readArtifact( - 'TestHelpers_BasicReturnContract' - ) - const spec = JSON.stringify(artifact.abi) - const mock = await smockit(spec) - - expect(isMockContract(mock)).to.be.true - }) - }) -}) diff --git a/packages/smock/test/smoddit/smoddit.spec.ts b/packages/smock/test/smoddit/smoddit.spec.ts deleted file mode 100644 index c90946a36bf9..000000000000 --- a/packages/smock/test/smoddit/smoddit.spec.ts +++ /dev/null @@ -1,184 +0,0 @@ -/* Imports: External */ -import { expect } from 'chai' -import { BigNumber } from 'ethers' -import _ from 'lodash' - -/* Imports: Internal */ -import { - ModifiableContractFactory, - ModifiableContract, - smoddit, -} from '../../src/smoddit' - -describe('smoddit', () => { - describe('via contract factory', () => { - describe('for functions with a single fixed return value', () => { - let SmodFactory: ModifiableContractFactory - before(async () => { - SmodFactory = await smoddit('SimpleStorageGetter') - }) - - let smod: ModifiableContract - beforeEach(async () => { - smod = await SmodFactory.deploy(4321) - }) - - it('should be able to return a uint256', async () => { - const ret = 1234 - - await smod.smodify.put({ - _uint256: ret, - }) - - expect(await smod.getUint256()).to.equal(ret) - }) - - it('should be able to return a boolean', async () => { - const ret = true - - await smod.smodify.put({ - _bool: ret, - }) - - expect(await smod.getBool()).to.equal(ret) - }) - - it('should be able to return an address', async () => { - const ret = '0x558ba9b8d78713fbf768c1f8a584485B4003f43F' - - await smod.smodify.put({ - _address: ret, - }) - - expect(await smod.getAddress()).to.equal(ret) - }) - - it('should be able to return an address in a packed storage slot', async () => { - const ret = '0x558ba9b8d78713fbf768c1f8a584485B4003f43F' - - await smod.smodify.put({ - _packedB: ret, - }) - - expect(await smod.getPackedAddress()).to.equal(ret) - }) - - it('should be able to return a simple struct', async () => { - const ret = { - valueA: BigNumber.from(1234), - valueB: true, - } - - await smod.smodify.put({ - _SimpleStruct: ret, - }) - - const result = _.toPlainObject(await smod.getSimpleStruct()) - expect(result.valueA).to.deep.equal(ret.valueA) - expect(result.valueB).to.deep.equal(ret.valueB) - }) - - it('should be able to return a simple uint256 => uint256 mapping value', async () => { - const retKey = 1234 - const retVal = 5678 - - await smod.smodify.put({ - _uint256Map: { - [retKey]: retVal, - }, - }) - - expect(await smod.getUint256MapValue(retKey)).to.equal(retVal) - }) - - it('should be able to return a nested uint256 => uint256 mapping value', async () => { - const retKeyA = 1234 - const retKeyB = 4321 - const retVal = 5678 - - await smod.smodify.put({ - _uint256NestedMap: { - [retKeyA]: { - [retKeyB]: retVal, - }, - }, - }) - - expect(await smod.getNestedUint256MapValue(retKeyA, retKeyB)).to.equal( - retVal - ) - }) - - it('should not return the set value if the value has been changed by the contract', async () => { - const ret = 1234 - - await smod.smodify.put({ - _uint256: ret, - }) - - await smod.setUint256(4321) - - expect(await smod.getUint256()).to.equal(4321) - }) - - it('should return the set value if it was set in the constructor', async () => { - const ret = 1234 - - await smod.smodify.put({ - _constructorUint256: ret, - }) - - expect(await smod.getConstructorUint256()).to.equal(1234) - }) - - it('should be able to set values in a bytes5 => bool mapping', async () => { - const key = '0x0000005678' - const val = true - - await smod.smodify.put({ - _bytes5ToBoolMap: { - [key]: val, - }, - }) - - expect(await smod.getBytes5ToBoolMapValue(key)).to.equal(val) - }) - - it('should be able to set values in a address => bool mapping', async () => { - const key = '0x558ba9b8d78713fbf768c1f8a584485B4003f43F' - const val = true - - await smod.smodify.put({ - _addressToBoolMap: { - [key]: val, - }, - }) - - expect(await smod.getAddressToBoolMapValue(key)).to.equal(val) - }) - - it('should be able to set values in a address => address mapping', async () => { - const key = '0x558ba9b8d78713fbf768c1f8a584485B4003f43F' - const val = '0x063bE0Af9711a170BE4b07028b320C90705fec7C' - - await smod.smodify.put({ - _addressToAddressMap: { - [key]: val, - }, - }) - - expect(await smod.getAddressToAddressMapValue(key)).to.equal(val) - }) - - it('should be able to pack two booleans', async () => { - const ret = true - - expect(await smod.booleanTwo()).to.equal(ret) - await smod.smodify.put({ - booleanTwo: ret, - }) - expect(await smod.booleanTwo()).to.equal(ret) - }) - }) - }) -}) diff --git a/packages/smock/tsconfig.build.json b/packages/smock/tsconfig.build.json deleted file mode 100644 index c711297477dc..000000000000 --- a/packages/smock/tsconfig.build.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "../../tsconfig.build.json", - - "compilerOptions": { - "outDir": "./dist" - }, - - "include": [ - "src/**/*" - ], - "files": [ - "./hardhat.config.ts" - ] -} diff --git a/packages/smock/tsconfig.json b/packages/smock/tsconfig.json deleted file mode 100644 index 4082f16a5d91..000000000000 --- a/packages/smock/tsconfig.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../../tsconfig.json" -} diff --git a/yarn.lock b/yarn.lock index 4de4d6f25591..d306ea62812e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -500,6 +500,14 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@eth-optimism/smock@^1.1.10", "@eth-optimism/smock@^1.1.9": + version "1.1.10" + resolved "https://registry.yarnpkg.com/@eth-optimism/smock/-/smock-1.1.10.tgz#98a6eefc994ccf707f52ab06849468f3cc57bdb7" + integrity sha512-XPx1x9odF/noTBHzIhRgL9ihhr769WgUhf9dOm6X7bjSWRAVsII3IqbdB4ssPycaoSuNSmv8HG1xTLgfgcyOYw== + dependencies: + "@eth-optimism/core-utils" "^0.5.1" + bn.js "^5.2.0" + "@eth-optimism/solc@^0.6.12-alpha.1": version "0.6.12-alpha.1" resolved "https://registry.yarnpkg.com/@eth-optimism/solc/-/solc-0.6.12-alpha.1.tgz#041876f83b34c6afe2f19dfe9626568df6ed8590" @@ -1876,7 +1884,7 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nomiclabs/ethereumjs-vm@^4.2.2": +"@nomiclabs/ethereumjs-vm@^4": version "4.2.2" resolved "https://registry.yarnpkg.com/@nomiclabs/ethereumjs-vm/-/ethereumjs-vm-4.2.2.tgz#2f8817113ca0fb6c44c1b870d0a809f0e026a6cc" integrity sha512-8WmX94mMcJaZ7/m7yBbyuS6B+wuOul+eF+RY9fBpGhNaUpyMR/vFIcDojqcWQ4Yafe1tMKY5LDu2yfT4NZgV4Q== @@ -8006,7 +8014,7 @@ hardhat-gas-reporter@^1.0.4: eth-gas-reporter "^0.2.20" sha1 "^1.1.1" -hardhat@^2.2.1, hardhat@^2.3.0, hardhat@^2.4.0: +hardhat@^2.2.1, hardhat@^2.3.0: version "2.4.1" resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.4.1.tgz#2cd1e86ee6ca3a6a473eeb0f55bd3124c8c59250" integrity sha512-vwllrFypukeE/Q+4ZfWj7j7nUo4ncUhRpsAYUM0Ruuuk6pQlKmRa0A6c0kxRSvvVgQsMud6j+/weYhbMX1wPmQ==