Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
a0fe4354
Unverified
Commit
a0fe4354
authored
Aug 22, 2021
by
Kelvin Fichter
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: deprecate smock v1
parent
8c3e8e11
Changes
45
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
45 changed files
with
20 additions
and
3367 deletions
+20
-3367
CODEOWNERS
.github/CODEOWNERS
+0
-1
labeler.yml
.github/labeler.yml
+0
-4
settings.json
.vscode/settings.json
+0
-1
CONTRIBUTING.md
CONTRIBUTING.md
+0
-1
README.md
README.md
+0
-1
Dockerfile.monorepo
ops/docker/Dockerfile.monorepo
+0
-1
package.json
packages/message-relayer/package.json
+6
-5
.eslintrc.js
packages/smock/.eslintrc.js
+0
-3
lint-build-test.yml
packages/smock/.github/workflows/lint-build-test.yml
+0
-50
version-to-release.yml
packages/smock/.github/workflows/version-to-release.yml
+0
-53
.gitignore
packages/smock/.gitignore
+0
-6
.lintstagedrc.yml
packages/smock/.lintstagedrc.yml
+0
-2
.prettierrc.js
packages/smock/.prettierrc.js
+0
-3
CHANGELOG.md
packages/smock/CHANGELOG.md
+0
-111
LICENSE
packages/smock/LICENSE
+0
-22
README.md
packages/smock/README.md
+4
-424
hardhat.config.ts
packages/smock/hardhat.config.ts
+0
-22
package.json
packages/smock/package.json
+0
-66
hardhat-common.ts
packages/smock/src/common/hardhat-common.ts
+0
-82
index.ts
packages/smock/src/common/index.ts
+0
-1
index.ts
packages/smock/src/index.ts
+0
-2
binding.ts
packages/smock/src/smockit/binding.ts
+0
-239
index.ts
packages/smock/src/smockit/index.ts
+0
-2
smockit.ts
packages/smock/src/smockit/smockit.ts
+0
-334
types.ts
packages/smock/src/smockit/types.ts
+0
-136
index.ts
packages/smock/src/smoddit/index.ts
+0
-2
smoddit.ts
packages/smock/src/smoddit/smoddit.ts
+0
-93
storage.ts
packages/smock/src/smoddit/storage.ts
+0
-185
types.ts
packages/smock/src/smoddit/types.ts
+0
-20
address-utils.ts
packages/smock/src/utils/address-utils.ts
+0
-12
hex-utils.ts
packages/smock/src/utils/hex-utils.ts
+0
-28
index.ts
packages/smock/src/utils/index.ts
+0
-2
SimpleStorageGetter.sol
packages/smock/test/contracts/SimpleStorageGetter.sol
+0
-165
TestHelpers_BasicReturnContract.sol
.../smock/test/contracts/TestHelpers_BasicReturnContract.sol
+0
-161
TestHelpers_EmptyContract.sol
packages/smock/test/contracts/TestHelpers_EmptyContract.sol
+0
-4
TestHelpers_MockCaller.sol
packages/smock/test/contracts/TestHelpers_MockCaller.sol
+0
-8
TestHelpers_SenderAssertions.sol
...ges/smock/test/contracts/TestHelpers_SenderAssertions.sol
+0
-14
call-assertions.spec.ts
packages/smock/test/smockit/call-assertions.spec.ts
+0
-72
function-manipulation.spec.ts
packages/smock/test/smockit/function-manipulation.spec.ts
+0
-710
sending-from-mocks.spec.ts
packages/smock/test/smockit/sending-from-mocks.spec.ts
+0
-36
smock-initialization.spec.ts
packages/smock/test/smockit/smock-initialization.spec.ts
+0
-80
smoddit.spec.ts
packages/smock/test/smoddit/smoddit.spec.ts
+0
-184
tsconfig.build.json
packages/smock/tsconfig.build.json
+0
-14
tsconfig.json
packages/smock/tsconfig.json
+0
-3
yarn.lock
yarn.lock
+10
-2
No files found.
.github/CODEOWNERS
View file @
a0fe4354
...
...
@@ -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
...
...
.github/labeler.yml
View file @
a0fe4354
...
...
@@ -42,7 +42,3 @@ M-hardhat-ovm:
M-ops
:
-
any
:
[
'
ops/**/*'
]
M-smock
:
-
any
:
[
'
packages/smock/**/*'
]
.vscode/settings.json
View file @
a0fe4354
...
...
@@ -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
},
...
...
CONTRIBUTING.md
View file @
a0fe4354
...
...
@@ -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
...
...
README.md
View file @
a0fe4354
...
...
@@ -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
...
...
ops/docker/Dockerfile.monorepo
View file @
a0fe4354
...
...
@@ -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
...
...
packages/message-relayer/package.json
View file @
a0fe4354
...
...
@@ -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
}
packages/smock/.eslintrc.js
deleted
100644 → 0
View file @
8c3e8e11
module
.
exports
=
{
extends
:
'
../../.eslintrc.js
'
,
}
packages/smock/.github/workflows/lint-build-test.yml
deleted
100644 → 0
View file @
8c3e8e11
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
packages/smock/.github/workflows/version-to-release.yml
deleted
100644 → 0
View file @
8c3e8e11
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 }}
packages/smock/.gitignore
deleted
100644 → 0
View file @
8c3e8e11
node_modules/
cache/
artifacts/
build/
.DS_Store
temp/
\ No newline at end of file
packages/smock/.lintstagedrc.yml
deleted
100644 → 0
View file @
8c3e8e11
"
*.{ts,js}"
:
-
eslint
packages/smock/.prettierrc.js
deleted
100644 → 0
View file @
8c3e8e11
module
.
exports
=
{
...
require
(
'
../../.prettierrc.js
'
),
};
\ No newline at end of file
packages/smock/CHANGELOG.md
deleted
100644 → 0
View file @
8c3e8e11
# @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
packages/smock/LICENSE
deleted
100644 → 0
View file @
8c3e8e11
(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.
packages/smock/README.md
View file @
a0fe4354
This diff is collapsed.
Click to expand it.
packages/smock/hardhat.config.ts
deleted
100644 → 0
View file @
8c3e8e11
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
packages/smock/package.json
deleted
100644 → 0
View file @
8c3e8e11
{
"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"
}
}
packages/smock/src/common/hardhat-common.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
)
}
}
packages/smock/src/common/index.ts
deleted
100644 → 0
View file @
8c3e8e11
export
*
from
'
./hardhat-common
'
packages/smock/src/index.ts
deleted
100644 → 0
View file @
8c3e8e11
export
*
from
'
./smockit
'
export
*
from
'
./smoddit
'
packages/smock/src/smockit/binding.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
<
any
>
=>
{
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
<
void
>
=>
{
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
<
void
>
=>
{
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
'
)
)
}
packages/smock/src/smockit/index.ts
deleted
100644 → 0
View file @
8c3e8e11
export
*
from
'
./smockit
'
export
*
from
'
./types
'
packages/smock/src/smockit/smockit.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
<
ethers
.
utils
.
Interface
>
=>
{
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
<
MockContract
>
=>
{
// 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
<
void
>
=>
{
// 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
)
}
packages/smock/src/smockit/types.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
<
string
>
)
)
=>
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
<
void
>
}
pStateManager
?:
{
putContractCode
:
(
address
:
Buffer
,
code
:
Buffer
)
=>
Promise
<
void
>
}
}
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
)
}
packages/smock/src/smoddit/index.ts
deleted
100644 → 0
View file @
8c3e8e11
export
*
from
'
./smoddit
'
export
*
from
'
./types
'
packages/smock/src/smoddit/smoddit.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
<
ModifiableContractFactory
>
=>
{
// 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
<
ModifiableContract
>
=>
{
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
}
packages/smock/src/smoddit/storage.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
<
any
>
=>
{
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
}
`
)
}
}
packages/smock/src/smoddit/types.ts
deleted
100644 → 0
View file @
8c3e8e11
/* External Imports */
import
{
Contract
,
ContractFactory
}
from
'
ethers
'
export
interface
Smodify
{
put
:
(
storage
:
any
)
=>
Promise
<
void
>
check
:
(
storage
:
any
)
=>
Promise
<
boolean
>
}
export
interface
Smodded
{
[
hash
:
string
]:
string
}
export
interface
ModifiableContract
extends
Contract
{
smodify
:
Smodify
_smodded
:
Smodded
}
export
interface
ModifiableContractFactory
extends
ContractFactory
{
deploy
:
(...
args
:
any
[])
=>
Promise
<
ModifiableContract
>
}
packages/smock/src/utils/address-utils.ts
deleted
100644 → 0
View file @
8c3e8e11
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
(
''
)
)
}
packages/smock/src/utils/hex-utils.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
()
)
}
}
packages/smock/src/utils/index.ts
deleted
100644 → 0
View file @
8c3e8e11
export
*
from
'
./hex-utils
'
export
*
from
'
./address-utils
'
packages/smock/test/contracts/SimpleStorageGetter.sol
deleted
100644 → 0
View file @
8c3e8e11
// 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;
}
}
packages/smock/test/contracts/TestHelpers_BasicReturnContract.sol
deleted
100644 → 0
View file @
8c3e8e11
// 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
)
{}
}
packages/smock/test/contracts/TestHelpers_EmptyContract.sol
deleted
100644 → 0
View file @
8c3e8e11
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
contract TestHelpers_EmptyContract {}
packages/smock/test/contracts/TestHelpers_MockCaller.sol
deleted
100644 → 0
View file @
8c3e8e11
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
contract TestHelpers_MockCaller {
function callMock(address _target, bytes memory _data) public {
_target.call(_data);
}
}
packages/smock/test/contracts/TestHelpers_SenderAssertions.sol
deleted
100644 → 0
View file @
8c3e8e11
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.0;
contract TestHelpers_SenderAssertions {
function getSender()
public
view
returns (
address
)
{
return msg.sender;
}
}
packages/smock/test/smockit/call-assertions.spec.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
])
})
})
})
packages/smock/test/smockit/function-manipulation.spec.ts
deleted
100644 → 0
View file @
8c3e8e11
This diff is collapsed.
Click to expand it.
packages/smock/test/smockit/sending-from-mocks.spec.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
)
})
})
packages/smock/test/smockit/smock-initialization.spec.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
})
})
})
packages/smock/test/smoddit/smoddit.spec.ts
deleted
100644 → 0
View file @
8c3e8e11
/* 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
)
})
})
})
})
packages/smock/tsconfig.build.json
deleted
100644 → 0
View file @
8c3e8e11
{
"extends"
:
"../../tsconfig.build.json"
,
"compilerOptions"
:
{
"outDir"
:
"./dist"
},
"include"
:
[
"src/**/*"
],
"files"
:
[
"./hardhat.config.ts"
]
}
packages/smock/tsconfig.json
deleted
100644 → 0
View file @
8c3e8e11
{
"extends"
:
"../../tsconfig.json"
}
yarn.lock
View file @
a0fe4354
...
...
@@ -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==
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment