mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-11-08 19:57:11 +00:00
lint
This commit is contained in:
1 parent
f6a412eef4
commit
f44b2485bd
61 files changed
+2867
-645
No files matched your search
@@ -5,7 +5,6 @@ inputs:
|
|||||||
required: false
|
required: false
|
||||||
default: "3.1.64"
|
default: "3.1.64"
|
||||||
|
|
||||||
|
|
||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -37,7 +37,15 @@ jobs:
|
|||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
target: [x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl, wasm32-unknown-emscripten, aarch64-apple-darwin, x86_64-apple-darwin, x86_64-pc-windows-msvc]
|
target:
|
||||||
|
[
|
||||||
|
x86_64-unknown-linux-gnu,
|
||||||
|
x86_64-unknown-linux-musl,
|
||||||
|
wasm32-unknown-emscripten,
|
||||||
|
aarch64-apple-darwin,
|
||||||
|
x86_64-apple-darwin,
|
||||||
|
x86_64-pc-windows-msvc,
|
||||||
|
]
|
||||||
include:
|
include:
|
||||||
- target: x86_64-unknown-linux-gnu
|
- target: x86_64-unknown-linux-gnu
|
||||||
builder-arg: gnu
|
builder-arg: gnu
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ on:
|
|||||||
branches: ["main"]
|
branches: ["main"]
|
||||||
types: [opened, synchronize]
|
types: [opened, synchronize]
|
||||||
paths:
|
paths:
|
||||||
- 'LLVM.lock'
|
- "LLVM.lock"
|
||||||
- 'crates/llvm-builder/**'
|
- "crates/llvm-builder/**"
|
||||||
- '.github/workflows/test-llvm-builder.yml'
|
- ".github/workflows/test-llvm-builder.yml"
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/target
|
/target
|
||||||
|
/js/resolc/dist
|
||||||
target-llvm
|
target-llvm
|
||||||
*.dot
|
*.dot
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|||||||
+28
-2
@@ -19,13 +19,16 @@ This is a development pre-release.
|
|||||||
Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
|
Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- The `revive-runner` helper utility binary which helps to run contracts locally without a blockchain node.
|
- The `revive-runner` helper utility binary which helps to run contracts locally without a blockchain node.
|
||||||
- Allow configuration of the EVM heap memory size and stack size via CLI flags and JSON input settings.
|
- Allow configuration of the EVM heap memory size and stack size via CLI flags and JSON input settings.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- The default PVM stack memory size was increased from 16kb to 32kb.
|
- The default PVM stack memory size was increased from 16kb to 32kb.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Constructors avoid storing zero sized immutable data on exit.
|
- Constructors avoid storing zero sized immutable data on exit.
|
||||||
|
|
||||||
## v0.1.0-dev.13
|
## v0.1.0-dev.13
|
||||||
@@ -35,16 +38,19 @@ This is a development pre-release.
|
|||||||
Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
|
Supported `polkadot-sdk` rev:`c29e72a8628835e34deb6aa7db9a78a2e4eabcee`
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for solc v0.8.29
|
- Support for solc v0.8.29
|
||||||
- Decouples the solc JSON-input-output type definitions from the Solidity fronted and expose them via a dedicated crate.
|
- Decouples the solc JSON-input-output type definitions from the Solidity fronted and expose them via a dedicated crate.
|
||||||
- `--supported-solc-versions` for `resolc` binary to return a `semver` range of supported `solc` versions.
|
- `--supported-solc-versions` for `resolc` binary to return a `semver` range of supported `solc` versions.
|
||||||
- Support for passing LLVM command line options via the prcoess input or providing one or more `--llvm-arg='..'` resolc CLI flag. This allows more fine-grained control over the LLVM backend configuration.
|
- Support for passing LLVM command line options via the prcoess input or providing one or more `--llvm-arg='..'` resolc CLI flag. This allows more fine-grained control over the LLVM backend configuration.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Storage keys and values are big endian. This was a pre-mature optimization because for the contract itself it this is a no-op and thus not observable. However we should consider the storage layout as part of the contract ABI. The endianness of transient storage values are still kept as-is.
|
- Storage keys and values are big endian. This was a pre-mature optimization because for the contract itself it this is a no-op and thus not observable. However we should consider the storage layout as part of the contract ABI. The endianness of transient storage values are still kept as-is.
|
||||||
- Running `resolc` using webkit is no longer supported.
|
- Running `resolc` using webkit is no longer supported.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- A missing byte swap for the create2 salt value.
|
- A missing byte swap for the create2 salt value.
|
||||||
|
|
||||||
## v0.1.0-dev.12
|
## v0.1.0-dev.12
|
||||||
@@ -54,10 +60,12 @@ This is a development pre-release.
|
|||||||
Supported `polkadot-sdk` rev: `21f6f0705e53c15aa2b8a5706b208200447774a9`
|
Supported `polkadot-sdk` rev: `21f6f0705e53c15aa2b8a5706b208200447774a9`
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Per file output selection for `--standard-json` mode.
|
- Per file output selection for `--standard-json` mode.
|
||||||
- The `ir` output selection option for `--standard-json` mode.
|
- The `ir` output selection option for `--standard-json` mode.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Improved code size: Large contracts compile to smaller code blobs when enabling aggressive size optimizations (`-Oz`).
|
- Improved code size: Large contracts compile to smaller code blobs when enabling aggressive size optimizations (`-Oz`).
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
@@ -73,6 +81,7 @@ Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50`
|
|||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- A bug causing incorrect loads from the emulated EVM linear memory.
|
- A bug causing incorrect loads from the emulated EVM linear memory.
|
||||||
- A missing integer truncate after switching to 64bit.
|
- A missing integer truncate after switching to 64bit.
|
||||||
|
|
||||||
@@ -83,10 +92,12 @@ This is a development pre-release.
|
|||||||
Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50`
|
Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50`
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for the `coinbase` opcode.
|
- Support for the `coinbase` opcode.
|
||||||
- The resolc web JS version.
|
- The resolc web JS version.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Missing the `--overwrite` flag emits an error instead of a warning.
|
- Missing the `--overwrite` flag emits an error instead of a warning.
|
||||||
- The `resolc` executable prints the help by default.
|
- The `resolc` executable prints the help by default.
|
||||||
- Removed support for legacy EVM assembly (EVMLA) translation.
|
- Removed support for legacy EVM assembly (EVMLA) translation.
|
||||||
@@ -96,6 +107,7 @@ Supported `polkadot-sdk` rev: `274a781e8ca1a9432c7ec87593bd93214abbff50`
|
|||||||
If detected, the re-entrant call flag is not set and 0 deposit limit is endowed.
|
If detected, the re-entrant call flag is not set and 0 deposit limit is endowed.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Solidity: Add the solc `--libraries` files to sources.
|
- Solidity: Add the solc `--libraries` files to sources.
|
||||||
- A data race in tests.
|
- A data race in tests.
|
||||||
- Fix `broken pipe` errors.
|
- Fix `broken pipe` errors.
|
||||||
@@ -109,9 +121,11 @@ This is a development pre-release.
|
|||||||
### Added
|
### Added
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Syscalls with more than 6 arguments now pack them into registers.
|
- Syscalls with more than 6 arguments now pack them into registers.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Remove reloading of the resolc.js file (fix issue with relative path in web worker)
|
- Remove reloading of the resolc.js file (fix issue with relative path in web worker)
|
||||||
|
|
||||||
## v0.1.0-dev.8
|
## v0.1.0-dev.8
|
||||||
@@ -119,15 +133,18 @@ This is a development pre-release.
|
|||||||
This is a development pre-release.
|
This is a development pre-release.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- The `revive-llvm-builder` crate with the `revive-llvm` helper utility for streamlined management of the LLVM framework dependency.
|
- The `revive-llvm-builder` crate with the `revive-llvm` helper utility for streamlined management of the LLVM framework dependency.
|
||||||
- Initial support for running `resolc` in the browser.
|
- Initial support for running `resolc` in the browser.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Suported contracts runtime is polkadot-sdk git version `d62a90c8c729acd98c7e9a5cab9803b8b211ffc5`.
|
- Suported contracts runtime is polkadot-sdk git version `d62a90c8c729acd98c7e9a5cab9803b8b211ffc5`.
|
||||||
- The minimum supported Rust version is `1.81.0`.
|
- The minimum supported Rust version is `1.81.0`.
|
||||||
- Error out early instead of invoking `solc` with invalid base or include path flags.
|
- Error out early instead of invoking `solc` with invalid base or include path flags.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Decouple the LLVM target dependency from the LLVM host dependency.
|
- Decouple the LLVM target dependency from the LLVM host dependency.
|
||||||
- Do not error out if no files and no errors were produced. This aligns resolc closer to solc.
|
- Do not error out if no files and no errors were produced. This aligns resolc closer to solc.
|
||||||
- Fixes input normalization in the Wasm version.
|
- Fixes input normalization in the Wasm version.
|
||||||
@@ -137,17 +154,20 @@ This is a development pre-release.
|
|||||||
This is a development pre-release.
|
This is a development pre-release.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Implement the `GASPRICE` opcode.
|
- Implement the `GASPRICE` opcode.
|
||||||
- Implement the `BASEFEE` opcode.
|
- Implement the `BASEFEE` opcode.
|
||||||
- Implement the `GASLIMIT` opcode.
|
- Implement the `GASLIMIT` opcode.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- The `GAS` opcode now returns the remaining `ref_time`.
|
- The `GAS` opcode now returns the remaining `ref_time`.
|
||||||
- Contracts can now be supplied call data input of arbitrary size.
|
- Contracts can now be supplied call data input of arbitrary size.
|
||||||
- Some syscalls now return the value in a register, slightly improving emitted contract code.
|
- Some syscalls now return the value in a register, slightly improving emitted contract code.
|
||||||
- Calls forward maximum weight limits instead of 0, anticipating a change in polkadot-sdk where weight limits of 0 no longer interprets as uncapped limit.
|
- Calls forward maximum weight limits instead of 0, anticipating a change in polkadot-sdk where weight limits of 0 no longer interprets as uncapped limit.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- A linker bug which was preventing certain contracts from linking with the PVM linker.
|
- A linker bug which was preventing certain contracts from linking with the PVM linker.
|
||||||
- JS: Fix encoding conversion from JS string (UTF-16) to UTF-8.
|
- JS: Fix encoding conversion from JS string (UTF-16) to UTF-8.
|
||||||
- The git commit hash slug is always displayed in the version string.
|
- The git commit hash slug is always displayed in the version string.
|
||||||
@@ -157,6 +177,7 @@ This is a development pre-release.
|
|||||||
This is a development pre-release.
|
This is a development pre-release.
|
||||||
|
|
||||||
# Added
|
# Added
|
||||||
|
|
||||||
- Implement the `BLOCKHASH` opcode.
|
- Implement the `BLOCKHASH` opcode.
|
||||||
- Implement delegate calls.
|
- Implement delegate calls.
|
||||||
- Implement the `GASPRICE` opcode. Currently hard-coded to return `1`.
|
- Implement the `GASPRICE` opcode. Currently hard-coded to return `1`.
|
||||||
@@ -164,21 +185,24 @@ This is a development pre-release.
|
|||||||
- Initial support for emitting debug info (opt in via the `-g` flag)
|
- Initial support for emitting debug info (opt in via the `-g` flag)
|
||||||
|
|
||||||
# Changed
|
# Changed
|
||||||
|
|
||||||
- resolc now emits 64bit PolkaVM blobs, reducing contract code size and execution time.
|
- resolc now emits 64bit PolkaVM blobs, reducing contract code size and execution time.
|
||||||
- The RISC-V bit-manipulation target feature (`zbb`) is enabled.
|
- The RISC-V bit-manipulation target feature (`zbb`) is enabled.
|
||||||
|
|
||||||
# Fixed
|
# Fixed
|
||||||
- Compilation to Wasm (for usage in node and web browsers)
|
|
||||||
|
|
||||||
|
- Compilation to Wasm (for usage in node and web browsers)
|
||||||
|
|
||||||
## v0.1.0-dev.5
|
## v0.1.0-dev.5
|
||||||
|
|
||||||
This is development pre-release.
|
This is development pre-release.
|
||||||
|
|
||||||
# Added
|
# Added
|
||||||
|
|
||||||
- Implement the `CODESIZE` and `EXTCODESIZE` opcodes.
|
- Implement the `CODESIZE` and `EXTCODESIZE` opcodes.
|
||||||
|
|
||||||
# Changed
|
# Changed
|
||||||
|
|
||||||
- Include the full revive version in the contract metadata.
|
- Include the full revive version in the contract metadata.
|
||||||
|
|
||||||
# Fixed
|
# Fixed
|
||||||
@@ -188,9 +212,11 @@ This is development pre-release.
|
|||||||
This is development pre-release.
|
This is development pre-release.
|
||||||
|
|
||||||
# Added
|
# Added
|
||||||
|
|
||||||
- Support the `ORIGIN` opcode.
|
- Support the `ORIGIN` opcode.
|
||||||
|
|
||||||
# Changed
|
# Changed
|
||||||
|
|
||||||
- Update polkavm to `v0.14.0`.
|
- Update polkavm to `v0.14.0`.
|
||||||
- Enable the `a`, `fast-unaligned-access` and `xtheadcondmov` LLVM target features, decreasing the code size for some contracts.
|
- Enable the `a`, `fast-unaligned-access` and `xtheadcondmov` LLVM target features, decreasing the code size for some contracts.
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ This is experimental software in active development and not ready just yet for p
|
|||||||
Discussion around the development is hosted on the [Polkadot Forum](https://forum.polkadot.network/t/contracts-update-solidity-on-polkavm/6949#a-new-solidity-compiler-1).
|
Discussion around the development is hosted on the [Polkadot Forum](https://forum.polkadot.network/t/contracts-update-solidity-on-polkavm/6949#a-new-solidity-compiler-1).
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Please consult [the documentation](https://contracts.polkadot.io/revive_compiler/installation) for installation instructions.
|
Please consult [the documentation](https://contracts.polkadot.io/revive_compiler/installation) for installation instructions.
|
||||||
|
|
||||||
## Building from source
|
## Building from source
|
||||||
@@ -30,11 +31,13 @@ Building revive requires a [stable Rust installation](https://rustup.rs/) and a
|
|||||||
Download the [latest LLVM build](https://github.com/paritytech/revive/releases?q=LLVM+binaries+release&expanded=true) from our releases.
|
Download the [latest LLVM build](https://github.com/paritytech/revive/releases?q=LLVM+binaries+release&expanded=true) from our releases.
|
||||||
|
|
||||||
> **MacOS** users need to clear the `downloaded` attribute from all binaries after extracting the archive:
|
> **MacOS** users need to clear the `downloaded` attribute from all binaries after extracting the archive:
|
||||||
|
>
|
||||||
> ```sh
|
> ```sh
|
||||||
> xattr -rc </path/to/the/extracted/archive>/target-llvm/gnu/target-final/bin/*
|
> xattr -rc </path/to/the/extracted/archive>/target-llvm/gnu/target-final/bin/*
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
After extracting the archive, point `$LLVM_SYS_181_PREFIX` to it:
|
After extracting the archive, point `$LLVM_SYS_181_PREFIX` to it:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
export LLVM_SYS_181_PREFIX=</path/to/the/extracted/archive>/target-llvm/gnu/target-final
|
export LLVM_SYS_181_PREFIX=</path/to/the/extracted/archive>/target-llvm/gnu/target-final
|
||||||
```
|
```
|
||||||
@@ -44,7 +47,7 @@ export LLVM_SYS_181_PREFIX=</path/to/the/extracted/archive>/target-llvm/gnu/targ
|
|||||||
<details>
|
<details>
|
||||||
<summary>Building from source</summary>
|
<summary>Building from source</summary>
|
||||||
|
|
||||||
Use the provided [revive-llvm](crates/llvm-builder/README.md) utility to compile a compatible LLVM build locally and point `$LLVM_SYS_181_PREFIX` to the installation afterwards.
|
Use the provided [revive-llvm](crates/llvm-builder/README.md) utility to compile a compatible LLVM build locally and point `$LLVM_SYS_181_PREFIX` to the installation afterwards.
|
||||||
|
|
||||||
The `Makefile` provides a shortcut target to obtain a compatible LLVM build:
|
The `Makefile` provides a shortcut target to obtain a compatible LLVM build:
|
||||||
|
|
||||||
@@ -97,6 +100,7 @@ Please consult the [Makefile](Makefile) targets to learn how to run tests and be
|
|||||||
Ensure that your branch passes `make test` locally when submitting a pull request.
|
Ensure that your branch passes `make test` locally when submitting a pull request.
|
||||||
|
|
||||||
### Design overview
|
### Design overview
|
||||||
|
|
||||||
See the [relevant section in our documentation](https://contracts.polkadot.io/revive_compiler/architecture) to learn more about how the compiler works.
|
See the [relevant section in our documentation](https://contracts.polkadot.io/revive_compiler/architecture) to learn more about how the compiler works.
|
||||||
|
|
||||||
[Frontend](https://github.com/matter-labs/era-compiler-solidity) and [code generator](https://github.com/matter-labs/era-compiler-llvm-context) are based of ZKSync `zksolc` (the project started as a fork of the era compiler).
|
[Frontend](https://github.com/matter-labs/era-compiler-solidity) and [code generator](https://github.com/matter-labs/era-compiler-llvm-context) are based of ZKSync `zksolc` (the project started as a fork of the era compiler).
|
||||||
|
|||||||
@@ -3,71 +3,71 @@
|
|||||||
## Table of Contents
|
## Table of Contents
|
||||||
|
|
||||||
- [Benchmark Results](#benchmark-results)
|
- [Benchmark Results](#benchmark-results)
|
||||||
- [Baseline](#baseline)
|
- [Baseline](#baseline)
|
||||||
- [OddPorduct](#oddporduct)
|
- [OddPorduct](#oddporduct)
|
||||||
- [TriangleNumber](#trianglenumber)
|
- [TriangleNumber](#trianglenumber)
|
||||||
- [FibonacciRecursive](#fibonaccirecursive)
|
- [FibonacciRecursive](#fibonaccirecursive)
|
||||||
- [FibonacciIterative](#fibonacciiterative)
|
- [FibonacciIterative](#fibonacciiterative)
|
||||||
- [FibonacciBinet](#fibonaccibinet)
|
- [FibonacciBinet](#fibonaccibinet)
|
||||||
- [SHA1](#sha1)
|
- [SHA1](#sha1)
|
||||||
|
|
||||||
## Benchmark Results
|
## Benchmark Results
|
||||||
|
|
||||||
### Baseline
|
### Baseline
|
||||||
|
|
||||||
| | `EVM` | `PVMInterpreter` |
|
| | `EVM` | `PVMInterpreter` |
|
||||||
|:--------|:-------------------------|:-------------------------------- |
|
| :------ | :------------------------ | :------------------------------- |
|
||||||
| **`0`** | `10.08 us` (✅ **1.00x**) | `10.32 us` (✅ **1.02x slower**) |
|
| **`0`** | `10.08 us` (✅ **1.00x**) | `10.32 us` (✅ **1.02x slower**) |
|
||||||
|
|
||||||
### OddPorduct
|
### OddPorduct
|
||||||
|
|
||||||
| | `EVM` | `PVMInterpreter` |
|
| | `EVM` | `PVMInterpreter` |
|
||||||
|:-------------|:--------------------------|:-------------------------------- |
|
| :----------- | :------------------------- | :------------------------------- |
|
||||||
| **`10000`** | `3.60 ms` (✅ **1.00x**) | `1.57 ms` (🚀 **2.28x faster**) |
|
| **`10000`** | `3.60 ms` (✅ **1.00x**) | `1.57 ms` (🚀 **2.28x faster**) |
|
||||||
| **`100000`** | `34.72 ms` (✅ **1.00x**) | `14.82 ms` (🚀 **2.34x faster**) |
|
| **`100000`** | `34.72 ms` (✅ **1.00x**) | `14.82 ms` (🚀 **2.34x faster**) |
|
||||||
| **`300000`** | `105.01 ms` (✅ **1.00x**) | `44.11 ms` (🚀 **2.38x faster**) |
|
| **`300000`** | `105.01 ms` (✅ **1.00x**) | `44.11 ms` (🚀 **2.38x faster**) |
|
||||||
|
|
||||||
### TriangleNumber
|
### TriangleNumber
|
||||||
|
|
||||||
| | `EVM` | `PVMInterpreter` |
|
| | `EVM` | `PVMInterpreter` |
|
||||||
|:-------------|:-------------------------|:-------------------------------- |
|
| :----------- | :------------------------ | :------------------------------- |
|
||||||
| **`10000`** | `2.43 ms` (✅ **1.00x**) | `1.12 ms` (🚀 **2.17x faster**) |
|
| **`10000`** | `2.43 ms` (✅ **1.00x**) | `1.12 ms` (🚀 **2.17x faster**) |
|
||||||
| **`100000`** | `24.20 ms` (✅ **1.00x**) | `10.86 ms` (🚀 **2.23x faster**) |
|
| **`100000`** | `24.20 ms` (✅ **1.00x**) | `10.86 ms` (🚀 **2.23x faster**) |
|
||||||
| **`360000`** | `88.69 ms` (✅ **1.00x**) | `38.46 ms` (🚀 **2.31x faster**) |
|
| **`360000`** | `88.69 ms` (✅ **1.00x**) | `38.46 ms` (🚀 **2.31x faster**) |
|
||||||
|
|
||||||
### FibonacciRecursive
|
### FibonacciRecursive
|
||||||
|
|
||||||
| | `EVM` | `PVMInterpreter` |
|
| | `EVM` | `PVMInterpreter` |
|
||||||
|:---------|:--------------------------|:--------------------------------- |
|
| :------- | :------------------------- | :-------------------------------- |
|
||||||
| **`12`** | `144.17 us` (✅ **1.00x**) | `150.85 us` (✅ **1.05x slower**) |
|
| **`12`** | `144.17 us` (✅ **1.00x**) | `150.85 us` (✅ **1.05x slower**) |
|
||||||
| **`16`** | `938.71 us` (✅ **1.00x**) | `922.11 us` (✅ **1.02x faster**) |
|
| **`16`** | `938.71 us` (✅ **1.00x**) | `922.11 us` (✅ **1.02x faster**) |
|
||||||
| **`20`** | `6.54 ms` (✅ **1.00x**) | `6.20 ms` (✅ **1.05x faster**) |
|
| **`20`** | `6.54 ms` (✅ **1.00x**) | `6.20 ms` (✅ **1.05x faster**) |
|
||||||
| **`24`** | `45.73 ms` (✅ **1.00x**) | `41.98 ms` (✅ **1.09x faster**) |
|
| **`24`** | `45.73 ms` (✅ **1.00x**) | `41.98 ms` (✅ **1.09x faster**) |
|
||||||
|
|
||||||
### FibonacciIterative
|
### FibonacciIterative
|
||||||
|
|
||||||
| | `EVM` | `PVMInterpreter` |
|
| | `EVM` | `PVMInterpreter` |
|
||||||
|:----------|:-------------------------|:-------------------------------- |
|
| :-------- | :------------------------ | :------------------------------- |
|
||||||
| **`64`** | `23.00 us` (✅ **1.00x**) | `31.88 us` (❌ *1.39x slower*) |
|
| **`64`** | `23.00 us` (✅ **1.00x**) | `31.88 us` (❌ _1.39x slower_) |
|
||||||
| **`128`** | `35.28 us` (✅ **1.00x**) | `42.43 us` (❌ *1.20x slower*) |
|
| **`128`** | `35.28 us` (✅ **1.00x**) | `42.43 us` (❌ _1.20x slower_) |
|
||||||
| **`256`** | `60.12 us` (✅ **1.00x**) | `61.20 us` (✅ **1.02x slower**) |
|
| **`256`** | `60.12 us` (✅ **1.00x**) | `61.20 us` (✅ **1.02x slower**) |
|
||||||
|
|
||||||
### FibonacciBinet
|
### FibonacciBinet
|
||||||
|
|
||||||
| | `EVM` | `PVMInterpreter` |
|
| | `EVM` | `PVMInterpreter` |
|
||||||
|:----------|:-------------------------|:-------------------------------- |
|
| :-------- | :------------------------ | :----------------------------- |
|
||||||
| **`64`** | `23.01 us` (✅ **1.00x**) | `47.74 us` (❌ *2.07x slower*) |
|
| **`64`** | `23.01 us` (✅ **1.00x**) | `47.74 us` (❌ _2.07x slower_) |
|
||||||
| **`128`** | `25.44 us` (✅ **1.00x**) | `49.67 us` (❌ *1.95x slower*) |
|
| **`128`** | `25.44 us` (✅ **1.00x**) | `49.67 us` (❌ _1.95x slower_) |
|
||||||
| **`256`** | `28.66 us` (✅ **1.00x**) | `53.01 us` (❌ *1.85x slower*) |
|
| **`256`** | `28.66 us` (✅ **1.00x**) | `53.01 us` (❌ _1.85x slower_) |
|
||||||
|
|
||||||
### SHA1
|
### SHA1
|
||||||
|
|
||||||
| | `EVM` | `PVMInterpreter` |
|
| | `EVM` | `PVMInterpreter` |
|
||||||
|:----------|:--------------------------|:--------------------------------- |
|
| :-------- | :------------------------- | :------------------------------ |
|
||||||
| **`1`** | `135.87 us` (✅ **1.00x**) | `243.75 us` (❌ *1.79x slower*) |
|
| **`1`** | `135.87 us` (✅ **1.00x**) | `243.75 us` (❌ _1.79x slower_) |
|
||||||
| **`64`** | `258.45 us` (✅ **1.00x**) | `355.70 us` (❌ *1.38x slower*) |
|
| **`64`** | `258.45 us` (✅ **1.00x**) | `355.70 us` (❌ _1.38x slower_) |
|
||||||
| **`512`** | `1.10 ms` (✅ **1.00x**) | `1.09 ms` (✅ **1.01x faster**) |
|
| **`512`** | `1.10 ms` (✅ **1.00x**) | `1.09 ms` (✅ **1.01x faster**) |
|
||||||
|
|
||||||
---
|
---
|
||||||
Made with [criterion-table](https://github.com/nu11ptr/criterion-table)
|
|
||||||
|
|
||||||
|
Made with [criterion-table](https://github.com/nu11ptr/criterion-table)
|
||||||
@@ -1,47 +1,47 @@
|
|||||||
{
|
{
|
||||||
"config": {
|
"config": {
|
||||||
"chainId": 420420420,
|
"chainId": 420420420,
|
||||||
"homesteadBlock": 0,
|
"homesteadBlock": 0,
|
||||||
"eip150Block": 0,
|
"eip150Block": 0,
|
||||||
"eip155Block": 0,
|
"eip155Block": 0,
|
||||||
"eip158Block": 0,
|
"eip158Block": 0,
|
||||||
"byzantiumBlock": 0,
|
"byzantiumBlock": 0,
|
||||||
"constantinopleBlock": 0,
|
"constantinopleBlock": 0,
|
||||||
"petersburgBlock": 0,
|
"petersburgBlock": 0,
|
||||||
"istanbulBlock": 0,
|
"istanbulBlock": 0,
|
||||||
"berlinBlock": 0,
|
"berlinBlock": 0,
|
||||||
"londonBlock": 0,
|
"londonBlock": 0,
|
||||||
"arrowGlacierBlock": 0,
|
"arrowGlacierBlock": 0,
|
||||||
"grayGlacierBlock": 0,
|
"grayGlacierBlock": 0,
|
||||||
"shanghaiTime": 0,
|
"shanghaiTime": 0,
|
||||||
"cancunTime": 0,
|
"cancunTime": 0,
|
||||||
"terminalTotalDifficulty": 0,
|
"terminalTotalDifficulty": 0,
|
||||||
"terminalTotalDifficultyPassed": true,
|
"terminalTotalDifficultyPassed": true,
|
||||||
"blobSchedule": {
|
"blobSchedule": {
|
||||||
"cancun": {
|
"cancun": {
|
||||||
"target": 3,
|
"target": 3,
|
||||||
"max": 6,
|
"max": 6,
|
||||||
"baseFeeUpdateFraction": 3338477
|
"baseFeeUpdateFraction": 3338477
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
|
||||||
"coinbase": "0xffffffffffffffffffffffffffffffffffffffff",
|
|
||||||
"difficulty": "0x20000",
|
|
||||||
"extraData": "",
|
|
||||||
"gasLimit": "0xffffffff",
|
|
||||||
"nonce": "0x0000000000000042",
|
|
||||||
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
||||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
|
||||||
"timestamp": "0x00",
|
|
||||||
"alloc": {
|
|
||||||
"0101010101010101010101010101010101010101": {
|
|
||||||
"balance": "1000000000"
|
|
||||||
},
|
|
||||||
"0202020202020202020202020202020202020202": {
|
|
||||||
"balance": "1000000000"
|
|
||||||
},
|
|
||||||
"0303030303030303030303030303030303030303": {
|
|
||||||
"balance": "1000000000"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"coinbase": "0xffffffffffffffffffffffffffffffffffffffff",
|
||||||
|
"difficulty": "0x20000",
|
||||||
|
"extraData": "",
|
||||||
|
"gasLimit": "0xffffffff",
|
||||||
|
"nonce": "0x0000000000000042",
|
||||||
|
"mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"timestamp": "0x00",
|
||||||
|
"alloc": {
|
||||||
|
"0101010101010101010101010101010101010101": {
|
||||||
|
"balance": "1000000000"
|
||||||
|
},
|
||||||
|
"0202020202020202020202020202020202020202": {
|
||||||
|
"balance": "1000000000"
|
||||||
|
},
|
||||||
|
"0303030303030303030303030303030303030303": {
|
||||||
|
"balance": "1000000000"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ Parity fork of the [Matter Labs zksync LLVM builder](https://github.com/matter-l
|
|||||||
|
|
||||||
The LLVM compiler framework for revive must be built with our tool called `revive-llvm`.
|
The LLVM compiler framework for revive must be built with our tool called `revive-llvm`.
|
||||||
This is because the revive compiler has requirements not fullfilled in upstream builds:
|
This is because the revive compiler has requirements not fullfilled in upstream builds:
|
||||||
|
|
||||||
- Special builds for compiling the frontend into statically linked ELF binaries and also Wasm executables
|
- Special builds for compiling the frontend into statically linked ELF binaries and also Wasm executables
|
||||||
- The RISC-V target (the PolkaVM target)
|
- The RISC-V target (the PolkaVM target)
|
||||||
- The compiler-rt builtins for the PolkaVM target
|
- The compiler-rt builtins for the PolkaVM target
|
||||||
@@ -17,85 +18,92 @@ Obtain a compatible build for your host platform from the release section of thi
|
|||||||
<details>
|
<details>
|
||||||
<summary>1. Install the system prerequisites.</summary>
|
<summary>1. Install the system prerequisites.</summary>
|
||||||
|
|
||||||
* Linux (Debian):
|
- Linux (Debian):
|
||||||
|
|
||||||
Install the following packages:
|
Install the following packages:
|
||||||
```shell
|
|
||||||
apt install cmake ninja-build curl git libssl-dev pkg-config clang lld
|
|
||||||
```
|
|
||||||
* Linux (Arch):
|
|
||||||
|
|
||||||
Install the following packages:
|
```shell
|
||||||
```shell
|
apt install cmake ninja-build curl git libssl-dev pkg-config clang lld
|
||||||
pacman -Syu which cmake ninja curl git pkg-config clang lld
|
```
|
||||||
```
|
|
||||||
|
|
||||||
* MacOS:
|
- Linux (Arch):
|
||||||
|
|
||||||
* Install the [HomeBrew](https://brew.sh) package manager.
|
Install the following packages:
|
||||||
* Install the following packages:
|
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
brew install cmake ninja coreutils
|
pacman -Syu which cmake ninja curl git pkg-config clang lld
|
||||||
```
|
```
|
||||||
|
|
||||||
* Install your choice of a recent LLVM/[Clang](https://clang.llvm.org) compiler, e.g. via [Xcode](https://developer.apple.com/xcode/), [Apple’s Command Line Tools](https://developer.apple.com/library/archive/technotes/tn2339/_index.html), or your preferred package manager.
|
- MacOS:
|
||||||
</details>
|
|
||||||
|
* Install the [HomeBrew](https://brew.sh) package manager.
|
||||||
|
* Install the following packages:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
brew install cmake ninja coreutils
|
||||||
|
```
|
||||||
|
|
||||||
|
* Install your choice of a recent LLVM/[Clang](https://clang.llvm.org) compiler, e.g. via [Xcode](https://developer.apple.com/xcode/), [Apple’s Command Line Tools](https://developer.apple.com/library/archive/technotes/tn2339/_index.html), or your preferred package manager.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>2. Install Rust.</summary>
|
<summary>2. Install Rust.</summary>
|
||||||
|
|
||||||
* Follow the latest [official instructions](https://www.rust-lang.org/tools/install:
|
- Follow the latest [official instructions](https://www.rust-lang.org/tools/install:
|
||||||
```shell
|
`shell
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||||
. ${HOME}/.cargo/env
|
. ${HOME}/.cargo/env
|
||||||
```
|
`
|
||||||
|
|
||||||
> Currently we are not pinned to any specific version of Rust, so just install the latest stable build for your platform.
|
> Currently we are not pinned to any specific version of Rust, so just install the latest stable build for your platform.
|
||||||
</details>
|
|
||||||
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>3. Install the revive LLVM framework builder.</summary>
|
<summary>3. Install the revive LLVM framework builder.</summary>
|
||||||
|
|
||||||
* Install the builder using `cargo`:
|
- Install the builder using `cargo`:
|
||||||
```shell
|
|
||||||
cargo install --git https://github.com/paritytech/revive-llvm-builder --force --locked
|
|
||||||
```
|
|
||||||
|
|
||||||
> The builder is not the LLVM framework itself, but a tool that clones its repository and runs a sequence of build commands. By default it is installed in `~/.cargo/bin/`, which is recommended to be added to your `$PATH`.
|
```shell
|
||||||
|
cargo install --git https://github.com/paritytech/revive-llvm-builder --force --locked
|
||||||
|
```
|
||||||
|
|
||||||
|
> The builder is not the LLVM framework itself, but a tool that clones its repository and runs a sequence of build commands. By default it is installed in `~/.cargo/bin/`, which is recommended to be added to your `$PATH`.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>4. (Optional) Create the `LLVM.lock` file.</summary>
|
<summary>4. (Optional) Create the `LLVM.lock` file.</summary>
|
||||||
|
|
||||||
* The `LLVM.lock` dictates the LLVM source tree being used.
|
- The `LLVM.lock` dictates the LLVM source tree being used.
|
||||||
A default `./LLVM.lock` pointing to the release used for development is already provided.
|
A default `./LLVM.lock` pointing to the release used for development is already provided.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>5. Build LLVM.</summary>
|
<summary>5. Build LLVM.</summary>
|
||||||
|
|
||||||
* Clone and build the LLVM framework using the `revive-llvm` tool.
|
- Clone and build the LLVM framework using the `revive-llvm` tool.
|
||||||
|
|
||||||
The clang and lld projects are required for the `resolc` Solidity frontend executable; they are enabled by default. LLVM assertions are also enabled by default.
|
The clang and lld projects are required for the `resolc` Solidity frontend executable; they are enabled by default. LLVM assertions are also enabled by default.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
revive-llvm clone
|
revive-llvm clone
|
||||||
revive-llvm build --llvm-projects lld --llvm-projects clang
|
revive-llvm build --llvm-projects lld --llvm-projects clang
|
||||||
```
|
```
|
||||||
|
|
||||||
Build artifacts end up in the `./target-llvm/gnu/target-final/` directory by default.
|
Build artifacts end up in the `./target-llvm/gnu/target-final/` directory by default.
|
||||||
The `gnu` directory depends on the supported archticture and will either be `gnu`, `musl` or `emscripten`.
|
The `gnu` directory depends on the supported archticture and will either be `gnu`, `musl` or `emscripten`.
|
||||||
You now need to export the final target directory `$LLVM_SYS_181_PREFIX`: `export LLVM_SYS_181_PREFIX=${PWD}/target-llvm/gnu/target-final`
|
You now need to export the final target directory `$LLVM_SYS_181_PREFIX`: `export LLVM_SYS_181_PREFIX=${PWD}/target-llvm/gnu/target-final`
|
||||||
If built with the `--enable-tests` option, test tools will be in the `./target-llvm/gnu/build-final/` directory, along with copies of the build artifacts. For all supported build options, run `revive-llvm build --help`.
|
If built with the `--enable-tests` option, test tools will be in the `./target-llvm/gnu/build-final/` directory, along with copies of the build artifacts. For all supported build options, run `revive-llvm build --help`.
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Supported target architectures
|
## Supported target architectures
|
||||||
|
|
||||||
The following target platforms are supported:
|
The following target platforms are supported:
|
||||||
|
|
||||||
- Linux GNU (x86)
|
- Linux GNU (x86)
|
||||||
- Linux MUSL (x86)
|
- Linux MUSL (x86)
|
||||||
- MacOS (aarch64)
|
- MacOS (aarch64)
|
||||||
@@ -105,28 +113,29 @@ The following target platforms are supported:
|
|||||||
<details>
|
<details>
|
||||||
<summary>Building for MUSL</summary>
|
<summary>Building for MUSL</summary>
|
||||||
|
|
||||||
* Via a musl build we can build revive into fully static ELF binaries.
|
- Via a musl build we can build revive into fully static ELF binaries.
|
||||||
Which is desirable for reproducible Solidity contracts builds.
|
Which is desirable for reproducible Solidity contracts builds.
|
||||||
The resulting binary is also very portable, akin to the`solc` frontend binary distribution.
|
The resulting binary is also very portable, akin to the`solc` frontend binary distribution.
|
||||||
|
|
||||||
Clone and build the LLVM framework using the `revive-llvm` tool:
|
Clone and build the LLVM framework using the `revive-llvm` tool:
|
||||||
```shell
|
|
||||||
revive-llvm --target-env musl clone
|
```shell
|
||||||
revive-llvm --target-env musl build --enable-assertions --llvm-projects clang --llvm-projects lld
|
revive-llvm --target-env musl clone
|
||||||
```
|
revive-llvm --target-env musl build --enable-assertions --llvm-projects clang --llvm-projects lld
|
||||||
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Building for Emscripten</summary>
|
<summary>Building for Emscripten</summary>
|
||||||
|
|
||||||
* Via an emsdk build we can run revive in the browser and on node.js.
|
- Via an emsdk build we can run revive in the browser and on node.js.
|
||||||
|
|
||||||
Clone and build the LLVM framework using the `revive-llvm` tool:
|
Clone and build the LLVM framework using the `revive-llvm` tool:
|
||||||
```shell
|
|
||||||
revive-llvm --target-env emscripten clone
|
```shell
|
||||||
revive-llvm --target-env emscripten build --enable-assertions --llvm-projects clang --llvm-projects lld
|
revive-llvm --target-env emscripten clone
|
||||||
```
|
revive-llvm --target-env emscripten build --enable-assertions --llvm-projects clang --llvm-projects lld
|
||||||
|
```
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
@@ -24,3 +24,4 @@ Set the `RUST_LOG` environment varibale to the `trace` level to see the full Pol
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
RUST_LOG=trace revive-runner -f mycontract.pvm -c a9059cbb000000000000000000000000f24ff3a9cf04c71dbc94d0b566f7a27b94566cac0000000000000000000000000000000000000000000000000000000000000000
|
RUST_LOG=trace revive-runner -f mycontract.pvm -c a9059cbb000000000000000000000000f24ff3a9cf04c71dbc94d0b566f7a27b94566cac0000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
```
|
||||||
@@ -1,103 +1,99 @@
|
|||||||
{
|
{
|
||||||
"language": "Solidity",
|
"language": "Solidity",
|
||||||
"sources": {
|
"sources": {
|
||||||
"lib/forge-std/src/Base.sol": {
|
"lib/forge-std/src/Base.sol": {
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {StdStorage} from \"./StdStorage.sol\";\nimport {Vm, VmSafe} from \"./Vm.sol\";\n\nabstract contract CommonBase {\n // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.\n address internal constant VM_ADDRESS = address(uint160(uint256(keccak256(\"hevm cheat code\"))));\n // console.sol and console2.sol work by executing a staticcall to this address.\n address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;\n // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38.\n address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256(\"foundry default caller\"))));\n // Address of the test contract, deployed by the DEFAULT_SENDER.\n address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;\n // Deterministic deployment address of the Multicall3 contract.\n address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11;\n // The order of the secp256k1 curve.\n uint256 internal constant SECP256K1_ORDER =\n 115792089237316195423570985008687907852837564279074904382605163141518161494337;\n\n uint256 internal constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n Vm internal constant vm = Vm(VM_ADDRESS);\n StdStorage internal stdstore;\n}\n\nabstract contract TestBase is CommonBase {}\n\nabstract contract ScriptBase is CommonBase {\n VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);\n}\n"
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {StdStorage} from \"./StdStorage.sol\";\nimport {Vm, VmSafe} from \"./Vm.sol\";\n\nabstract contract CommonBase {\n // Cheat code address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D.\n address internal constant VM_ADDRESS = address(uint160(uint256(keccak256(\"hevm cheat code\"))));\n // console.sol and console2.sol work by executing a staticcall to this address.\n address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67;\n // Used when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n // Default address for tx.origin and msg.sender, 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38.\n address internal constant DEFAULT_SENDER = address(uint160(uint256(keccak256(\"foundry default caller\"))));\n // Address of the test contract, deployed by the DEFAULT_SENDER.\n address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f;\n // Deterministic deployment address of the Multicall3 contract.\n address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11;\n // The order of the secp256k1 curve.\n uint256 internal constant SECP256K1_ORDER =\n 115792089237316195423570985008687907852837564279074904382605163141518161494337;\n\n uint256 internal constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n Vm internal constant vm = Vm(VM_ADDRESS);\n StdStorage internal stdstore;\n}\n\nabstract contract TestBase is CommonBase {}\n\nabstract contract ScriptBase is CommonBase {\n VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS);\n}\n"
|
||||||
},
|
|
||||||
"lib/forge-std/src/Script.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\n// 💬 ABOUT\n// Forge Std's default Script.\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {safeconsole} from \"./safeconsole.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheatsSafe} from \"./StdCheats.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorageSafe} from \"./StdStorage.sol\";\nimport {StdStyle} from \"./StdStyle.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {VmSafe} from \"./Vm.sol\";\n\n// 📦 BOILERPLATE\nimport {ScriptBase} from \"./Base.sol\";\n\n// ⭐️ SCRIPT\nabstract contract Script is ScriptBase, StdChains, StdCheatsSafe, StdUtils {\n // Note: IS_SCRIPT() must return true.\n bool public IS_SCRIPT = true;\n}\n"
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdAssertions.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\npragma experimental ABIEncoderV2;\n\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdAssertions {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n event log(string);\n event logs(bytes);\n\n event log_address(address);\n event log_bytes32(bytes32);\n event log_int(int256);\n event log_uint(uint256);\n event log_bytes(bytes);\n event log_string(string);\n\n event log_named_address(string key, address val);\n event log_named_bytes32(string key, bytes32 val);\n event log_named_decimal_int(string key, int256 val, uint256 decimals);\n event log_named_decimal_uint(string key, uint256 val, uint256 decimals);\n event log_named_int(string key, int256 val);\n event log_named_uint(string key, uint256 val);\n event log_named_bytes(string key, bytes val);\n event log_named_string(string key, string val);\n\n event log_array(uint256[] val);\n event log_array(int256[] val);\n event log_array(address[] val);\n event log_named_array(string key, uint256[] val);\n event log_named_array(string key, int256[] val);\n event log_named_array(string key, address[] val);\n\n bool private _failed;\n\n function failed() public view returns (bool) {\n if (_failed) {\n return _failed;\n } else {\n return vm.load(address(vm), bytes32(\"failed\")) != bytes32(0);\n }\n }\n\n function fail() internal virtual {\n vm.store(address(vm), bytes32(\"failed\"), bytes32(uint256(1)));\n _failed = true;\n }\n\n function assertTrue(bool data) internal pure virtual {\n vm.assertTrue(data);\n }\n\n function assertTrue(bool data, string memory err) internal pure virtual {\n vm.assertTrue(data, err);\n }\n\n function assertFalse(bool data) internal pure virtual {\n vm.assertFalse(data);\n }\n\n function assertFalse(bool data, string memory err) internal pure virtual {\n vm.assertFalse(data, err);\n }\n\n function assertEq(bool left, bool right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(bool left, bool right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEq(uint256 left, uint256 right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(uint256 left, uint256 right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual {\n vm.assertEqDecimal(left, right, decimals);\n }\n\n function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual {\n vm.assertEqDecimal(left, right, decimals, err);\n }\n\n function assertEq(int256 left, int256 right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(int256 left, int256 right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual {\n vm.assertEqDecimal(left, right, decimals);\n }\n\n function assertEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual {\n vm.assertEqDecimal(left, right, decimals, err);\n }\n\n function assertEq(address left, address right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(address left, address right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEq(bytes32 left, bytes32 right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(bytes32 left, bytes32 right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEq32(bytes32 left, bytes32 right) internal pure virtual {\n assertEq(left, right);\n }\n\n function assertEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual {\n assertEq(left, right, err);\n }\n\n function assertEq(string memory left, string memory right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(string memory left, string memory right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEq(bytes memory left, bytes memory right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(bytes memory left, bytes memory right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEq(bool[] memory left, bool[] Line truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdChains.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n/**\n * StdChains provides information about EVM compatible chains that can be used in scripts/tests.\n * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are\n * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of\n * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the\n * alias used in this contract, which can be found as the first argument to the\n * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function.\n *\n * There are two main ways to use this contract:\n * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or\n * `setChain(string memory chainAlias, Chain memory chain)`\n * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`.\n *\n * The first time either of those are used, chains are initialized with the default set of RPC URLs.\n * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in\n * `defaultRpcUrls`.\n *\n * The `setChain` function is straightforward, and it simply saves off the given chain data.\n *\n * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say\n * we want to retrieve the RPC URL for `mainnet`:\n * - If you have specified data with `setChain`, it will return that.\n * - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it\n * is valid (e.g. a URL is specified, or an environment variable is given and exists).\n * - If neither of the above conditions is met, the default data is returned.\n *\n * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.\n */\nabstract contract StdChains {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private stdChainsInitialized;\n\n struct ChainData {\n string name;\n uint256 chainId;\n string rpcUrl;\n }\n\n struct Chain {\n // The chain name.\n string name;\n // The chain's Chain ID.\n uint256 chainId;\n // The chain's alias. (i.e. what gets specified in `foundry.toml`).\n string chainAlias;\n // A default RPC endpoint for this chain.\n // NOTE: This default RPC URL is included for convenience to facilitate quick tests and\n // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy\n // usage as you will be throttled and this is a disservice to others who need this endpoint.\n string rpcUrl;\n }\n\n // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data.\n mapping(string => Chain) private chains;\n // Maps from the chain's alias to it's default RPC URL.\n mapping(string => string) private defaultRpcUrls;\n // Maps from a chain ID to it's alias.\n mapping(uint256 => string) private idToAlias;\n\n bool private fallbackToDefaultRpcUrls = true;\n\n // The RPC URL will be fetched from config or defaultRpcUrls if possible.\n function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) {\n require(bytes(chainAlias).length != 0, \"StdChains getChain(string): Chain alias cannot be the empty string.\");\n\n initializeStdChains();\n chain = chains[chainAlias];\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(string): Chain with alias \\\"\", chainAlias, \"\\\" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n function getChain(uint256 chainId) internal virtual returns (Chain memory chain) {\n require(chainId != 0, \"StdChains getChain(uint256): Chain ID cannot be 0.\");\n initializeStdChains();\n string memory chainAlias = idToAlias[chainId];\n\n chain = chains[chainAlias];\n\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(uint256): Chain with ID \", vm.toString(chainId), \" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, ChainData memory chain) internal virtual {\n require(\n bytes(chainAlias).length != 0,\n \"StdChains setChain(string,ChainData): Chain alias cannot be the empty string.\"\n );\n\n require(chain.chainId != 0, \"StdChains setChain(string,ChainData): Chain ID cannot be 0.\");\n\n initializeStdChains();\n string memory foundAlias = idToAlias[chain.chainId];\n\n Line truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdCheats.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {console2} from \"./console2.sol\";\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdCheatsSafe {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n bool private gasMeteringOff;\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawTx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n // json value name = function\n string functionSig;\n bytes32 hash;\n // json value name = tx\n RawTx1559Detail txDetail;\n // json value name = type\n string opcode;\n }\n\n struct RawTx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n bytes gas;\n bytes nonce;\n address to;\n bytes txType;\n bytes value;\n }\n\n struct Tx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n bytes32 hash;\n Tx1559Detail txDetail;\n string opcode;\n }\n\n struct Tx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n uint256 gas;\n uint256 nonce;\n address to;\n uint256 txType;\n uint256 value;\n }\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct TxLegacy {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n string hash;\n string opcode;\n TxDetailLegacy transaction;\n }\n\n struct TxDetailLegacy {\n AccessList[] accessList;\n uint256 chainId;\n bytes data;\n address from;\n uint256 gas;\n uint256 gasPrice;\n bytes32 hash;\n uint256 nonce;\n bytes1 opcode;\n bytes32 r;\n bytes32 s;\n uint256 txType;\n address to;\n uint8 v;\n uint256 value;\n }\n\n struct AccessList {\n address accessAddress;\n bytes32[] storageKeys;\n }\n\n // Data structures to parse Receipt objects from the broadcast artifact.\n // The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawReceipt {\n bytes32 blockHash;\n bytes blockNumber;\n address contractAddress;\n bytes cumulativeGasUsed;\n bytes effectiveGasPrice;\n address from;\n bytes gasUsed;\n RawReceiptLog[] logs;\n bytes logsBloom;\n bytes status;\n address to;\n bytes32 transactionHash;\n bytes transactionIndex;\n }\n\n struct Receipt {\n bytes32 blockHash;\n uint256 blockNumber;\n address contractAddress;\n uint256 cumulativeGasUsed;\n uint256 effectiveGasPrice;\n address from;\n uint256 gasUsed;\n ReceiptLog[] logs;\n bytes logsBloom;\n uint256 status;\n address to;\n bytes32 transactionHash;\n uint256 transactionIndex;\n }\n\n // Data structures to parse the entire broadcast artifact, assuming the\n // transactions conform to EIP1559.\n\n struct EIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n Receipt[] receipts;\n uint256 timestamp;\n Tx1559[] transactions;\n TxReturn[] txReturns;\n }\n\n struct RawEIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n RawReceipt[] receipts;\n TxReturn[] txReturns;\n uint256 timestamp;\n RawTx1559[] transactions;\n }\n\n struct RawReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n bytes blockNumber;\n bytes data;\n bytes logIndex;\n bool removed;\n bytes32[] topics;\n bytes32 transactionHash;\n bytes transactionIndex;\n bytes transactionLogIndex;\n }\n\n struct ReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n uint256 blockNumber;\n bytes data;\n uint256 Line truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdError.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\n// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdError {\n bytes public constant assertionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x01);\n bytes public constant arithmeticError = abi.encodeWithSignature(\"Panic(uint256)\", 0x11);\n bytes public constant divisionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x12);\n bytes public constant enumConversionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x21);\n bytes public constant encodeStorageError = abi.encodeWithSignature(\"Panic(uint256)\", 0x22);\n bytes public constant popError = abi.encodeWithSignature(\"Panic(uint256)\", 0x31);\n bytes public constant indexOOBError = abi.encodeWithSignature(\"Panic(uint256)\", 0x32);\n bytes public constant memOverflowError = abi.encodeWithSignature(\"Panic(uint256)\", 0x41);\n bytes public constant zeroVarError = abi.encodeWithSignature(\"Panic(uint256)\", 0x51);\n}\n"
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdInvariant.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nabstract contract StdInvariant {\n struct FuzzSelector {\n address addr;\n bytes4[] selectors;\n }\n\n struct FuzzArtifactSelector {\n string artifact;\n bytes4[] selectors;\n }\n\n struct FuzzInterface {\n address addr;\n string[] artifacts;\n }\n\n address[] private _excludedContracts;\n address[] private _excludedSenders;\n address[] private _targetedContracts;\n address[] private _targetedSenders;\n\n string[] private _excludedArtifacts;\n string[] private _targetedArtifacts;\n\n FuzzArtifactSelector[] private _targetedArtifactSelectors;\n\n FuzzSelector[] private _excludedSelectors;\n FuzzSelector[] private _targetedSelectors;\n\n FuzzInterface[] private _targetedInterfaces;\n\n // Functions for users:\n // These are intended to be called in tests.\n\n function excludeContract(address newExcludedContract_) internal {\n _excludedContracts.push(newExcludedContract_);\n }\n\n function excludeSelector(FuzzSelector memory newExcludedSelector_) internal {\n _excludedSelectors.push(newExcludedSelector_);\n }\n\n function excludeSender(address newExcludedSender_) internal {\n _excludedSenders.push(newExcludedSender_);\n }\n\n function excludeArtifact(string memory newExcludedArtifact_) internal {\n _excludedArtifacts.push(newExcludedArtifact_);\n }\n\n function targetArtifact(string memory newTargetedArtifact_) internal {\n _targetedArtifacts.push(newTargetedArtifact_);\n }\n\n function targetArtifactSelector(FuzzArtifactSelector memory newTargetedArtifactSelector_) internal {\n _targetedArtifactSelectors.push(newTargetedArtifactSelector_);\n }\n\n function targetContract(address newTargetedContract_) internal {\n _targetedContracts.push(newTargetedContract_);\n }\n\n function targetSelector(FuzzSelector memory newTargetedSelector_) internal {\n _targetedSelectors.push(newTargetedSelector_);\n }\n\n function targetSender(address newTargetedSender_) internal {\n _targetedSenders.push(newTargetedSender_);\n }\n\n function targetInterface(FuzzInterface memory newTargetedInterface_) internal {\n _targetedInterfaces.push(newTargetedInterface_);\n }\n\n // Functions for forge:\n // These are called by forge to run invariant tests and don't need to be called in tests.\n\n function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) {\n excludedArtifacts_ = _excludedArtifacts;\n }\n\n function excludeContracts() public view returns (address[] memory excludedContracts_) {\n excludedContracts_ = _excludedContracts;\n }\n\n function excludeSelectors() public view returns (FuzzSelector[] memory excludedSelectors_) {\n excludedSelectors_ = _excludedSelectors;\n }\n\n function excludeSenders() public view returns (address[] memory excludedSenders_) {\n excludedSenders_ = _excludedSenders;\n }\n\n function targetArtifacts() public view returns (string[] memory targetedArtifacts_) {\n targetedArtifacts_ = _targetedArtifacts;\n }\n\n function targetArtifactSelectors() public view returns (FuzzArtifactSelector[] memory targetedArtifactSelectors_) {\n targetedArtifactSelectors_ = _targetedArtifactSelectors;\n }\n\n function targetContracts() public view returns (address[] memory targetedContracts_) {\n targetedContracts_ = _targetedContracts;\n }\n\n function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) {\n targetedSelectors_ = _targetedSelectors;\n }\n\n function targetSenders() public view returns (address[] memory targetedSenders_) {\n targetedSenders_ = _targetedSenders;\n }\n\n function targetInterfaces() public view returns (FuzzInterface[] memory targetedInterfaces_) {\n targetedInterfaces_ = _targetedInterfaces;\n }\n}\n"
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdJson.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing JSON files\n// To parse:\n// ```\n// using stdJson for string;\n// string memory json = vm.readFile(\"<some_path>\");\n// json.readUint(\"<json_path>\");\n// ```\n// To write:\n// ```\n// using stdJson for string;\n// string memory json = \"json\";\n// json.serialize(\"a\", uint256(123));\n// string memory semiFinal = json.serialize(\"b\", string(\"test\"));\n// string memory finalJson = json.serialize(\"c\", semiFinal);\n// finalJson.write(\"<some_path>\");\n// ```\n\nlibrary stdJson {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function keyExists(string memory json, string memory key) internal view returns (bool) {\n return vm.keyExistsJson(json, key);\n }\n\n function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJson(json, key);\n }\n\n function readUint(string memory json, string memory key) internal pure returns (uint256) {\n return vm.parseJsonUint(json, key);\n }\n\n function readUintArray(string memory json, string memory key) internal pure returns (uint256[] memory) {\n return vm.parseJsonUintArray(json, key);\n }\n\n function readInt(string memory json, string memory key) internal pure returns (int256) {\n return vm.parseJsonInt(json, key);\n }\n\n function readIntArray(string memory json, string memory key) internal pure returns (int256[] memory) {\n return vm.parseJsonIntArray(json, key);\n }\n\n function readBytes32(string memory json, string memory key) internal pure returns (bytes32) {\n return vm.parseJsonBytes32(json, key);\n }\n\n function readBytes32Array(string memory json, string memory key) internal pure returns (bytes32[] memory) {\n return vm.parseJsonBytes32Array(json, key);\n }\n\n function readString(string memory json, string memory key) internal pure returns (string memory) {\n return vm.parseJsonString(json, key);\n }\n\n function readStringArray(string memory json, string memory key) internal pure returns (string[] memory) {\n return vm.parseJsonStringArray(json, key);\n }\n\n function readAddress(string memory json, string memory key) internal pure returns (address) {\n return vm.parseJsonAddress(json, key);\n }\n\n function readAddressArray(string memory json, string memory key) internal pure returns (address[] memory) {\n return vm.parseJsonAddressArray(json, key);\n }\n\n function readBool(string memory json, string memory key) internal pure returns (bool) {\n return vm.parseJsonBool(json, key);\n }\n\n function readBoolArray(string memory json, string memory key) internal pure returns (bool[] memory) {\n return vm.parseJsonBoolArray(json, key);\n }\n\n function readBytes(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJsonBytes(json, key);\n }\n\n function readBytesArray(string memory json, string memory key) internal pure returns (bytes[] memory) {\n return vm.parseJsonBytesArray(json, key);\n }\n\n function readUintOr(string memory json, string memory key, uint256 defaultValue) internal view returns (uint256) {\n return keyExists(json, key) ? readUint(json, key) : defaultValue;\n }\n\n function readUintArrayOr(string memory json, string memory key, uint256[] memory defaultValue)\n internal\n view\n returns (uint256[] memory)\n {\n return keyExists(json, key) ? readUintArray(json, key) : defaultValue;\n }\n\n function readIntOr(string memory json, string memory key, int256 defaultValue) internal view returns (int256) {\n return keyExists(json, key) ? readInt(json, key) : defaultValue;\n }\n\n function readIntArrayOr(string memory json, string memory key, int256[] memory defaultValue)\n internal\n view\n returns (int256[] memory)\n {\n return keyExists(json, key) ? readIntArray(json, key) : defaultValue;\n }\n\n function readBytes32Or(string memory json, string memory key, bytes32 defaultValue)\n internal\n view\n returns (bytes32)\n {\n return keyExists(json, key) ? readBytes32(json, key) : defaultValue;\n }\n\n function readBytes32ArrayOr(string memory json, string memory key, bytes32[] memory defaultValue)\n internal\n view\n returns (bytes32[] memory)\n {\n return keyExists(json, key) ? readBytes32Array(json, key) : defaultValue;\n }\n\n function readStringOr(string memory json, string memory key, string memory defaultValue)\n internal\n view\n returns (string memory)\n {\n return keyExists(json, Line truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdMath.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdMath {\n int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n function abs(int256 a) internal pure returns (uint256) {\n // Required or it will fail when `a = type(int256).min`\n if (a == INT256_MIN) {\n return 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n }\n\n return uint256(a > 0 ? a : -a);\n }\n\n function delta(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a - b : b - a;\n }\n\n function delta(int256 a, int256 b) internal pure returns (uint256) {\n // a and b are of the same sign\n // this works thanks to two's complement, the left-most bit is the sign bit\n if ((a ^ b) > -1) {\n return delta(abs(a), abs(b));\n }\n\n // a and b are of opposite signs\n return abs(a) + abs(b);\n }\n\n function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n\n return absDelta * 1e18 / b;\n }\n\n function percentDelta(int256 a, int256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n uint256 absB = abs(b);\n\n return absDelta * 1e18 / absB;\n }\n}\n"
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdStorage.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nstruct FindData {\n uint256 slot;\n uint256 offsetLeft;\n uint256 offsetRight;\n bool found;\n}\n\nstruct StdStorage {\n mapping(address => mapping(bytes4 => mapping(bytes32 => FindData))) finds;\n bytes32[] _keys;\n bytes4 _sig;\n uint256 _depth;\n address _target;\n bytes32 _set;\n bool _enable_packed_slots;\n bytes _calldata;\n}\n\nlibrary stdStorageSafe {\n event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot);\n event WARNING_UninitedSlot(address who, uint256 slot);\n\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n uint256 constant UINT256_MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return bytes4(keccak256(bytes(sigStr)));\n }\n\n function getCallParams(StdStorage storage self) internal view returns (bytes memory) {\n if (self._calldata.length == 0) {\n return flatten(self._keys);\n } else {\n return self._calldata;\n }\n }\n\n // Calls target contract with configured parameters\n function callTarget(StdStorage storage self) internal view returns (bool, bytes32) {\n bytes memory cald = abi.encodePacked(self._sig, getCallParams(self));\n (bool success, bytes memory rdat) = self._target.staticcall(cald);\n bytes32 result = bytesToBytes32(rdat, 32 * self._depth);\n\n return (success, result);\n }\n\n // Tries mutating slot value to determine if the targeted value is stored in it.\n // If current value is 0, then we are setting slot value to type(uint256).max\n // Otherwise, we set it to 0. That way, return value should always be affected.\n function checkSlotMutatesCall(StdStorage storage self, bytes32 slot) internal returns (bool) {\n bytes32 prevSlotValue = vm.load(self._target, slot);\n (bool success, bytes32 prevReturnValue) = callTarget(self);\n\n bytes32 testVal = prevReturnValue == bytes32(0) ? bytes32(UINT256_MAX) : bytes32(0);\n vm.store(self._target, slot, testVal);\n\n (, bytes32 newReturnValue) = callTarget(self);\n\n vm.store(self._target, slot, prevSlotValue);\n\n return (success && (prevReturnValue != newReturnValue));\n }\n\n // Tries setting one of the bits in slot to 1 until return value changes.\n // Index of resulted bit is an offset packed slot has from left/right side\n function findOffset(StdStorage storage self, bytes32 slot, bool left) internal returns (bool, uint256) {\n for (uint256 offset = 0; offset < 256; offset++) {\n uint256 valueToPut = left ? (1 << (255 - offset)) : (1 << offset);\n vm.store(self._target, slot, bytes32(valueToPut));\n\n (bool success, bytes32 data) = callTarget(self);\n\n if (success && (uint256(data) > 0)) {\n return (true, offset);\n }\n }\n return (false, 0);\n }\n\n function findOffsets(StdStorage storage self, bytes32 slot) internal returns (bool, uint256, uint256) {\n bytes32 prevSlotValue = vm.load(self._target, slot);\n\n (bool foundLeft, uint256 offsetLeft) = findOffset(self, slot, true);\n (bool foundRight, uint256 offsetRight) = findOffset(self, slot, false);\n\n // `findOffset` may mutate slot value, so we are setting it to initial value\n vm.store(self._target, slot, prevSlotValue);\n return (foundLeft && foundRight, offsetLeft, offsetRight);\n }\n\n function find(StdStorage storage self) internal returns (FindData storage) {\n return find(self, true);\n }\n\n /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against\n // slot complexity:\n // if flat, will be bytes32(uint256(uint));\n // if map, will be keccak256(abi.encode(key, uint(slot)));\n // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));\n // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);\n function find(StdStorage storage self, bool _clear) internal returns (FindData storage) {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes memory params = getCallParams(self);\n\n // calldata to test against\n if (self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) {\n if (_clear) {\n clear(self);\n }\n return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))];\n }\n vm.record();\n (, bytes32 callResulLine truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdStyle.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nimport {VmSafe} from \"./Vm.sol\";\n\nlibrary StdStyle {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n string constant RED = \"\\u001b[91m\";\n string constant GREEN = \"\\u001b[92m\";\n string constant YELLOW = \"\\u001b[93m\";\n string constant BLUE = \"\\u001b[94m\";\n string constant MAGENTA = \"\\u001b[95m\";\n string constant CYAN = \"\\u001b[96m\";\n string constant BOLD = \"\\u001b[1m\";\n string constant DIM = \"\\u001b[2m\";\n string constant ITALIC = \"\\u001b[3m\";\n string constant UNDERLINE = \"\\u001b[4m\";\n string constant INVERSE = \"\\u001b[7m\";\n string constant RESET = \"\\u001b[0m\";\n\n function styleConcat(string memory style, string memory self) private pure returns (string memory) {\n return string(abi.encodePacked(style, self, RESET));\n }\n\n function red(string memory self) internal pure returns (string memory) {\n return styleConcat(RED, self);\n }\n\n function red(uint256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(int256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(address self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(bool self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes(bytes memory self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes32(bytes32 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function green(string memory self) internal pure returns (string memory) {\n return styleConcat(GREEN, self);\n }\n\n function green(uint256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(int256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(address self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(bool self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes(bytes memory self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes32(bytes32 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function yellow(string memory self) internal pure returns (string memory) {\n return styleConcat(YELLOW, self);\n }\n\n function yellow(uint256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(int256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(address self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(bool self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes(bytes memory self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes32(bytes32 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function blue(string memory self) internal pure returns (string memory) {\n return styleConcat(BLUE, self);\n }\n\n function blue(uint256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(int256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(address self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(bool self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes(bytes memory self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes32(bytes32 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function magenta(string memory self) internal pure returns (string memory) {\n return styleConcat(MAGENTA, self);\n }\n\n function magenta(uint256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(int256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(address self) internal pure returns (string memory) {\n Line truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdToml.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing TOML files\n// To parse:\n// ```\n// using stdToml for string;\n// string memory toml = vm.readFile(\"<some_path>\");\n// toml.readUint(\"<json_path>\");\n// ```\n// To write:\n// ```\n// using stdToml for string;\n// string memory json = \"json\";\n// json.serialize(\"a\", uint256(123));\n// string memory semiFinal = json.serialize(\"b\", string(\"test\"));\n// string memory finalJson = json.serialize(\"c\", semiFinal);\n// finalJson.write(\"<some_path>\");\n// ```\n\nlibrary stdToml {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function keyExists(string memory toml, string memory key) internal view returns (bool) {\n return vm.keyExistsToml(toml, key);\n }\n\n function parseRaw(string memory toml, string memory key) internal pure returns (bytes memory) {\n return vm.parseToml(toml, key);\n }\n\n function readUint(string memory toml, string memory key) internal pure returns (uint256) {\n return vm.parseTomlUint(toml, key);\n }\n\n function readUintArray(string memory toml, string memory key) internal pure returns (uint256[] memory) {\n return vm.parseTomlUintArray(toml, key);\n }\n\n function readInt(string memory toml, string memory key) internal pure returns (int256) {\n return vm.parseTomlInt(toml, key);\n }\n\n function readIntArray(string memory toml, string memory key) internal pure returns (int256[] memory) {\n return vm.parseTomlIntArray(toml, key);\n }\n\n function readBytes32(string memory toml, string memory key) internal pure returns (bytes32) {\n return vm.parseTomlBytes32(toml, key);\n }\n\n function readBytes32Array(string memory toml, string memory key) internal pure returns (bytes32[] memory) {\n return vm.parseTomlBytes32Array(toml, key);\n }\n\n function readString(string memory toml, string memory key) internal pure returns (string memory) {\n return vm.parseTomlString(toml, key);\n }\n\n function readStringArray(string memory toml, string memory key) internal pure returns (string[] memory) {\n return vm.parseTomlStringArray(toml, key);\n }\n\n function readAddress(string memory toml, string memory key) internal pure returns (address) {\n return vm.parseTomlAddress(toml, key);\n }\n\n function readAddressArray(string memory toml, string memory key) internal pure returns (address[] memory) {\n return vm.parseTomlAddressArray(toml, key);\n }\n\n function readBool(string memory toml, string memory key) internal pure returns (bool) {\n return vm.parseTomlBool(toml, key);\n }\n\n function readBoolArray(string memory toml, string memory key) internal pure returns (bool[] memory) {\n return vm.parseTomlBoolArray(toml, key);\n }\n\n function readBytes(string memory toml, string memory key) internal pure returns (bytes memory) {\n return vm.parseTomlBytes(toml, key);\n }\n\n function readBytesArray(string memory toml, string memory key) internal pure returns (bytes[] memory) {\n return vm.parseTomlBytesArray(toml, key);\n }\n\n function readUintOr(string memory toml, string memory key, uint256 defaultValue) internal view returns (uint256) {\n return keyExists(toml, key) ? readUint(toml, key) : defaultValue;\n }\n\n function readUintArrayOr(string memory toml, string memory key, uint256[] memory defaultValue)\n internal\n view\n returns (uint256[] memory)\n {\n return keyExists(toml, key) ? readUintArray(toml, key) : defaultValue;\n }\n\n function readIntOr(string memory toml, string memory key, int256 defaultValue) internal view returns (int256) {\n return keyExists(toml, key) ? readInt(toml, key) : defaultValue;\n }\n\n function readIntArrayOr(string memory toml, string memory key, int256[] memory defaultValue)\n internal\n view\n returns (int256[] memory)\n {\n return keyExists(toml, key) ? readIntArray(toml, key) : defaultValue;\n }\n\n function readBytes32Or(string memory toml, string memory key, bytes32 defaultValue)\n internal\n view\n returns (bytes32)\n {\n return keyExists(toml, key) ? readBytes32(toml, key) : defaultValue;\n }\n\n function readBytes32ArrayOr(string memory toml, string memory key, bytes32[] memory defaultValue)\n internal\n view\n returns (bytes32[] memory)\n {\n return keyExists(toml, key) ? readBytes32Array(toml, key) : defaultValue;\n }\n\n function readStringOr(string memory toml, string memory key, string memory defaultValue)\n internal\n view\n returns (string memory)\n {\n return keyExists(toml, Line truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/StdUtils.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {IMulticall3} from \"./interfaces/IMulticall3.sol\";\nimport {MockERC20} from \"./mocks/MockERC20.sol\";\nimport {MockERC721} from \"./mocks/MockERC721.sol\";\nimport {VmSafe} from \"./Vm.sol\";\n\nabstract contract StdUtils {\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n //////////////////////////////////////////////////////////////////////////*/\n\n IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;\n uint256 private constant INT256_MIN_ABS =\n 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n uint256 private constant SECP256K1_ORDER =\n 115792089237316195423570985008687907852837564279074904382605163141518161494337;\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n /*//////////////////////////////////////////////////////////////////////////\n INTERNAL FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n require(min <= max, \"StdUtils bound(uint256,uint256,uint256): Max is less than min.\");\n // If x is between min and max, return x directly. This is to ensure that dictionary values\n // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188\n if (x >= min && x <= max) return x;\n\n uint256 size = max - min + 1;\n\n // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side.\n // This helps ensure coverage of the min/max values.\n if (x <= 3 && size > x) return min + x;\n if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x);\n\n // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.\n if (x > max) {\n uint256 diff = x - max;\n uint256 rem = diff % size;\n if (rem == 0) return max;\n result = min + rem - 1;\n } else if (x < min) {\n uint256 diff = min - x;\n uint256 rem = diff % size;\n if (rem == 0) return min;\n result = max - rem + 1;\n }\n }\n\n function bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n result = _bound(x, min, max);\n console2_log_StdUtils(\"Bound result\", result);\n }\n\n function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) {\n require(min <= max, \"StdUtils bound(int256,int256,int256): Max is less than min.\");\n\n // Shifting all int256 values to uint256 to use _bound function. The range of two types are:\n // int256 : -(2**255) ~ (2**255 - 1)\n // uint256: 0 ~ (2**256 - 1)\n // So, add 2**255, INT256_MIN_ABS to the integer values.\n //\n // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow.\n // So, use `~uint256(x) + 1` instead.\n uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS);\n uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS);\n uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS);\n\n uint256 y = _bound(_x, _min, _max);\n\n // To move it back to int256 value, subtract INT256_MIN_ABS at here.\n result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS);\n }\n\n function bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) {\n result = _bound(x, min, max);\n console2_log_StdUtils(\"Bound result\", vm.toString(result));\n }\n\n function boundPrivateKey(uint256 privateKey) internal pure virtual returns (uint256 result) {\n result = _bound(privateKey, 1, SECP256K1_ORDER - 1);\n }\n\n function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {\n require(b.length <= 32, \"StdUtils bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePackLine truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/Test.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// 💬 ABOUT\n// Forge Std's default Test.\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {safeconsole} from \"./safeconsole.sol\";\nimport {StdAssertions} from \"./StdAssertions.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheats} from \"./StdCheats.sol\";\nimport {stdError} from \"./StdError.sol\";\nimport {StdInvariant} from \"./StdInvariant.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {StdStyle} from \"./StdStyle.sol\";\nimport {stdToml} from \"./StdToml.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {Vm} from \"./Vm.sol\";\n\n// 📦 BOILERPLATE\nimport {TestBase} from \"./Base.sol\";\n\n// ⭐️ TEST\nabstract contract Test is TestBase, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils {\n // Note: IS_TEST() must return true.\n bool public IS_TEST = true;\n}\n"
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/Vm.sol": {
|
|
||||||
"content": "// Automatically @generated by scripts/vm.py. Do not modify manually.\n\n// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.2 <0.9.0;\npragma experimental ABIEncoderV2;\n\n/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may\n/// result in Script simulations differing from on-chain execution. It is recommended to only use\n/// these cheats in scripts.\ninterface VmSafe {\n /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`.\n enum CallerMode {\n // No caller modification is currently active.\n None,\n // A one time broadcast triggered by a `vm.broadcast()` call is currently active.\n Broadcast,\n // A recurrent broadcast triggered by a `vm.startBroadcast()` call is currently active.\n RecurrentBroadcast,\n // A one time prank triggered by a `vm.prank()` call is currently active.\n Prank,\n // A recurrent prank triggered by a `vm.startPrank()` call is currently active.\n RecurrentPrank\n }\n\n /// The kind of account access that occurred.\n enum AccountAccessKind {\n // The account was called.\n Call,\n // The account was called via delegatecall.\n DelegateCall,\n // The account was called via callcode.\n CallCode,\n // The account was called via staticcall.\n StaticCall,\n // The account was created.\n Create,\n // The account was selfdestructed.\n SelfDestruct,\n // Synthetic access indicating the current context has resumed after a previous sub-context (AccountAccess).\n Resume,\n // The account's balance was read.\n Balance,\n // The account's codesize was read.\n Extcodesize,\n // The account's codehash was read.\n Extcodehash,\n // The account's code was copied.\n Extcodecopy\n }\n\n /// Forge execution contexts.\n enum ForgeContext {\n // Test group execution context (test, coverage or snapshot).\n TestGroup,\n // `forge test` execution context.\n Test,\n // `forge coverage` execution context.\n Coverage,\n // `forge snapshot` execution context.\n Snapshot,\n // Script group execution context (dry run, broadcast or resume).\n ScriptGroup,\n // `forge script` execution context.\n ScriptDryRun,\n // `forge script --broadcast` execution context.\n ScriptBroadcast,\n // `forge script --resume` execution context.\n ScriptResume,\n // Unknown `forge` execution context.\n Unknown\n }\n\n /// The transaction type (`txType`) of the broadcast.\n enum BroadcastTxType {\n // Represents a CALL broadcast tx.\n Call,\n // Represents a CREATE broadcast tx.\n Create,\n // Represents a CREATE2 broadcast tx.\n Create2\n }\n\n /// An Ethereum log. Returned by `getRecordedLogs`.\n struct Log {\n // The topics of the log, including the signature, if any.\n bytes32[] topics;\n // The raw data of the log.\n bytes data;\n // The address of the log's emitter.\n address emitter;\n }\n\n /// An RPC URL and its alias. Returned by `rpcUrlStructs`.\n struct Rpc {\n // The alias of the RPC URL.\n string key;\n // The RPC URL.\n string url;\n }\n\n /// An RPC log object. Returned by `eth_getLogs`.\n struct EthGetLogs {\n // The address of the log's emitter.\n address emitter;\n // The topics of the log, including the signature, if any.\n bytes32[] topics;\n // The raw data of the log.\n bytes data;\n // The block hash.\n bytes32 blockHash;\n // The block number.\n uint64 blockNumber;\n // The transaction hash.\n bytes32 transactionHash;\n // The transaction index in the block.\n uint64 transactionIndex;\n // The log index.\n uint256 logIndex;\n // Whether the log was removed.\n bool removed;\n }\n\n /// A single entry in a directory listing. Returned by `readDir`.\n struct DirEntry {\n // The error message, if any.\n string errorMessage;\n // The path of the entry.\n string path;\n // The depth of the entry.\n uint64 depth;\n // Whether the entry is a directory.\n bool isDir;\n // Whether the entry is a symlink.\n bool isSymlink;\n }\n\n /// Metadata information about a file.\n /// This structure is returned from the `fsMetadata` function and represents known\n /// metadata about a file such as its permissions, size, modification\n /// times, etc.\n struct FsMetadata {\n // True if this metadata is for a directory.\n bool isDir;\n // True if this metadata Line truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/console.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS =\n 0x000000000000000000636F6e736F6c652e6c6f67;\n\n function _sendLogPayloadImplementation(bytes memory payload) internal view {\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n pop(\n staticcall(\n gas(),\n consoleAddress,\n add(payload, 32),\n mload(payload),\n 0,\n 0\n )\n )\n }\n }\n\n function _castToPure(\n function(bytes memory) internal view fnIn\n ) internal pure returns (function(bytes memory) pure fnOut) {\n assembly {\n fnOut := fnIn\n }\n }\n\n function _sendLogPayload(bytes memory payload) internal pure {\n _castToPure(_sendLogPayloadImplementation)(payload);\n }\n\n function log() internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int256 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytLine truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/console2.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nimport {console as console2} from \"./console.sol\";\n"
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/interfaces/IERC165.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n"
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/interfaces/IERC20.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2;\n\n/// @dev Interface of the ERC20 standard as defined in the EIP.\n/// @dev This includes the optional name, symbol, and decimals metadata.\ninterface IERC20 {\n /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value`\n /// is the new allowance.\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /// @notice Returns the amount of tokens in existence.\n function totalSupply() external view returns (uint256);\n\n /// @notice Returns the amount of tokens owned by `account`.\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Moves `amount` tokens from the caller's account to `to`.\n function transfer(address to, uint256 amount) external returns (bool);\n\n /// @notice Returns the remaining number of tokens that `spender` is allowed\n /// to spend on behalf of `owner`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens.\n /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism.\n /// `amount` is then deducted from the caller's allowance.\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n\n /// @notice Returns the name of the token.\n function name() external view returns (string memory);\n\n /// @notice Returns the symbol of the token.\n function symbol() external view returns (string memory);\n\n /// @notice Returns the decimals places of the token.\n function decimals() external view returns (uint8);\n}\n"
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/interfaces/IERC721.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2;\n\nimport \"./IERC165.sol\";\n\n/// @title ERC-721 Non-Fungible Token Standard\n/// @dev See https://eips.ethereum.org/EIPS/eip-721\n/// Note: the ERC-165 identifier for this interface is 0x80ac58cd.\ninterface IERC721 is IERC165 {\n /// @dev This emits when ownership of any NFT changes by any mechanism.\n /// This event emits when NFTs are created (`from` == 0) and destroyed\n /// (`to` == 0). Exception: during contract creation, any number of NFTs\n /// may be created and assigned without emitting Transfer. At the time of\n /// any transfer, the approved address for that NFT (if any) is reset to none.\n event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);\n\n /// @dev This emits when the approved address for an NFT is changed or\n /// reaffirmed. The zero address indicates there is no approved address.\n /// When a Transfer event emits, this also indicates that the approved\n /// address for that NFT (if any) is reset to none.\n event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);\n\n /// @dev This emits when an operator is enabled or disabled for an owner.\n /// The operator can manage all NFTs of the owner.\n event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);\n\n /// @notice Count all NFTs assigned to an owner\n /// @dev NFTs assigned to the zero address are considered invalid, and this\n /// function throws for queries about the zero address.\n /// @param _owner An address for whom to query the balance\n /// @return The number of NFTs owned by `_owner`, possibly zero\n function balanceOf(address _owner) external view returns (uint256);\n\n /// @notice Find the owner of an NFT\n /// @dev NFTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param _tokenId The identifier for an NFT\n /// @return The address of the owner of the NFT\n function ownerOf(uint256 _tokenId) external view returns (address);\n\n /// @notice Transfers the ownership of an NFT from one address to another address\n /// @dev Throws unless `msg.sender` is the current owner, an authorized\n /// operator, or the approved address for this NFT. Throws if `_from` is\n /// not the current owner. Throws if `_to` is the zero address. Throws if\n /// `_tokenId` is not a valid NFT. When transfer is complete, this function\n /// checks if `_to` is a smart contract (code size > 0). If so, it calls\n /// `onERC721Received` on `_to` and throws if the return value is not\n /// `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`.\n /// @param _from The current owner of the NFT\n /// @param _to The new owner\n /// @param _tokenId The NFT to transfer\n /// @param data Additional data with no specified format, sent in call to `_to`\n function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable;\n\n /// @notice Transfers the ownership of an NFT from one address to another address\n /// @dev This works identically to the other function with an extra data parameter,\n /// except this function just sets data to \"\".\n /// @param _from The current owner of the NFT\n /// @param _to The new owner\n /// @param _tokenId The NFT to transfer\n function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;\n\n /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE\n /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE\n /// THEY MAY BE PERMANENTLY LOST\n /// @dev Throws unless `msg.sender` is the current owner, an authorized\n /// operator, or the approved address for this NFT. Throws if `_from` is\n /// not the current owner. Throws if `_to` is the zero address. Throws if\n /// `_tokenId` is not a valid NFT.\n /// @param _from The current owner of the NFT\n /// @param _to The new owner\n /// @param _tokenId The NFT to transfer\n function transferFrom(address _from, address _to, uint256 _tokenId) external payable;\n\n /// @notice Change or reaffirm the approved address for an NFT\n /// @dev The zero address indicates there is no approved address.\n /// Throws unless `msg.sender` is the current NFT owner, or an authorized\n /// operator of the current owner.\n /// @param _approved The new approved NFT controller\n /// @param _tokenId The NFT to approve\n function approve(address _approved, uint256 _tokenId) external payable;\n\n /// @notice Enable or disable approval for a third party (\"operator\") to manage\n /// all of `msg.sender`'s assets\n /// @dev Emits the ApprovalForAll event. The contract MUST allow\n /// multiple operators per owner.\n /// @param _operator Address to add to the set of authorized oLine truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/interfaces/IMulticall3.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ninterface IMulticall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint256 value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n function aggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes[] memory returnData);\n\n function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);\n\n function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData);\n\n function blockAndAggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n\n function getBasefee() external view returns (uint256 basefee);\n\n function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash);\n\n function getBlockNumber() external view returns (uint256 blockNumber);\n\n function getChainId() external view returns (uint256 chainid);\n\n function getCurrentBlockCoinbase() external view returns (address coinbase);\n\n function getCurrentBlockDifficulty() external view returns (uint256 difficulty);\n\n function getCurrentBlockGasLimit() external view returns (uint256 gaslimit);\n\n function getCurrentBlockTimestamp() external view returns (uint256 timestamp);\n\n function getEthBalance(address addr) external view returns (uint256 balance);\n\n function getLastBlockHash() external view returns (bytes32 blockHash);\n\n function tryAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (Result[] memory returnData);\n\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n}\n"
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/mocks/MockERC20.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {IERC20} from \"../interfaces/IERC20.sol\";\n\n/// @notice This is a mock contract of the ERC20 standard for testing purposes only, it SHOULD NOT be used in production.\n/// @dev Forked from: https://github.com/transmissions11/solmate/blob/0384dbaaa4fcb5715738a9254a7c0a4cb62cf458/src/tokens/ERC20.sol\ncontract MockERC20 is IERC20 {\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string internal _name;\n\n string internal _symbol;\n\n uint8 internal _decimals;\n\n function name() external view override returns (string memory) {\n return _name;\n }\n\n function symbol() external view override returns (string memory) {\n return _symbol;\n }\n\n function decimals() external view override returns (uint8) {\n return _decimals;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal _totalSupply;\n\n mapping(address => uint256) internal _balanceOf;\n\n mapping(address => mapping(address => uint256)) internal _allowance;\n\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) external view override returns (uint256) {\n return _balanceOf[owner];\n }\n\n function allowance(address owner, address spender) external view override returns (uint256) {\n return _allowance[owner][spender];\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal INITIAL_CHAIN_ID;\n\n bytes32 internal INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n INITIALIZE\n //////////////////////////////////////////////////////////////*/\n\n /// @dev A bool to track whether the contract has been initialized.\n bool private initialized;\n\n /// @dev To hide constructor warnings across solc versions due to different constructor visibility requirements and\n /// syntaxes, we add an initialization function that can be called only once.\n function initialize(string memory name_, string memory symbol_, uint8 decimals_) public {\n require(!initialized, \"ALREADY_INITIALIZED\");\n\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n\n INITIAL_CHAIN_ID = _pureChainId();\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n\n initialized = true;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n _balanceOf[msg.sender] = _sub(_balanceOf[msg.sender], amount);\n _balanceOf[to] = _add(_balanceOf[to], amount);\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n uint256 allowed = _allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != ~uint256(0)) _allowance[from][msg.sender] = _sub(allowed, amount);\n\n _balanceOf[from] = _sub(_balanceOf[from], amount);\n _balanceOf[to] = _add(_balanceOf[to], amount);\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\n public\n virtual\n {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uLine truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/mocks/MockERC721.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {IERC721Metadata, IERC721TokenReceiver} from \"../interfaces/IERC721.sol\";\n\n/// @notice This is a mock contract of the ERC721 standard for testing purposes only, it SHOULD NOT be used in production.\n/// @dev Forked from: https://github.com/transmissions11/solmate/blob/0384dbaaa4fcb5715738a9254a7c0a4cb62cf458/src/tokens/ERC721.sol\ncontract MockERC721 is IERC721Metadata {\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string internal _name;\n\n string internal _symbol;\n\n function name() external view override returns (string memory) {\n return _name;\n }\n\n function symbol() external view override returns (string memory) {\n return _symbol;\n }\n\n function tokenURI(uint256 id) public view virtual override returns (string memory) {}\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual override returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _getApproved;\n\n mapping(address => mapping(address => bool)) internal _isApprovedForAll;\n\n function getApproved(uint256 id) public view virtual override returns (address) {\n return _getApproved[id];\n }\n\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _isApprovedForAll[owner][operator];\n }\n\n /*//////////////////////////////////////////////////////////////\n INITIALIZE\n //////////////////////////////////////////////////////////////*/\n\n /// @dev A bool to track whether the contract has been initialized.\n bool private initialized;\n\n /// @dev To hide constructor warnings across solc versions due to different constructor visibility requirements and\n /// syntaxes, we add an initialization function that can be called only once.\n function initialize(string memory name_, string memory symbol_) public {\n require(!initialized, \"ALREADY_INITIALIZED\");\n\n _name = name_;\n _symbol = symbol_;\n\n initialized = true;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public payable virtual override {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || _isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n _getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(address from, address to, uint256 id) public payable virtual override {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || _isApprovedForAll[from][msg.sender] || msg.sender == _getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n\n _ownerOf[id] = to;\n\n delete _getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(address from, address to, uint256 id) public payable virtual override {\n transferFrom(from, to, id);\n\n require(\n !_isContract(to)\n || IERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\")\n == IERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(address from, address to, uint256 id, bytes memory dLine truncated
|
|
||||||
},
|
|
||||||
"lib/forge-std/src/safeconsole.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\n/// @author philogy <https://github.com/philogy>\n/// @dev Code generated automatically by script.\nlibrary safeconsole {\n uint256 constant CONSOLE_ADDR = 0x000000000000000000000000000000000000000000636F6e736F6c652e6c6f67;\n\n // Credit to [0age](https://twitter.com/z0age/status/1654922202930888704) and [0xdapper](https://github.com/foundry-rs/forge-std/pull/374)\n // for the view-to-pure log trick.\n function _sendLogPayload(uint256 offset, uint256 size) private pure {\n function(uint256, uint256) internal view fnIn = _sendLogPayloadView;\n function(uint256, uint256) internal pure pureSendLogPayload;\n /// @solidity memory-safe-assembly\n assembly {\n pureSendLogPayload := fnIn\n }\n pureSendLogPayload(offset, size);\n }\n\n function _sendLogPayloadView(uint256 offset, uint256 size) private view {\n /// @solidity memory-safe-assembly\n assembly {\n pop(staticcall(gas(), CONSOLE_ADDR, offset, size, 0x0, 0x0))\n }\n }\n\n function _memcopy(uint256 fromOffset, uint256 toOffset, uint256 length) private pure {\n function(uint256, uint256, uint256) internal view fnIn = _memcopyView;\n function(uint256, uint256, uint256) internal pure pureMemcopy;\n /// @solidity memory-safe-assembly\n assembly {\n pureMemcopy := fnIn\n }\n pureMemcopy(fromOffset, toOffset, length);\n }\n\n function _memcopyView(uint256 fromOffset, uint256 toOffset, uint256 length) private view {\n /// @solidity memory-safe-assembly\n assembly {\n pop(staticcall(gas(), 0x4, fromOffset, length, toOffset, length))\n }\n }\n\n function logMemory(uint256 offset, uint256 length) internal pure {\n if (offset >= 0x60) {\n // Sufficient memory before slice to prepare call header.\n bytes32 m0;\n bytes32 m1;\n bytes32 m2;\n /// @solidity memory-safe-assembly\n assembly {\n m0 := mload(sub(offset, 0x60))\n m1 := mload(sub(offset, 0x40))\n m2 := mload(sub(offset, 0x20))\n // Selector of `log(bytes)`.\n mstore(sub(offset, 0x60), 0x0be77f56)\n mstore(sub(offset, 0x40), 0x20)\n mstore(sub(offset, 0x20), length)\n }\n _sendLogPayload(offset - 0x44, length + 0x44);\n /// @solidity memory-safe-assembly\n assembly {\n mstore(sub(offset, 0x60), m0)\n mstore(sub(offset, 0x40), m1)\n mstore(sub(offset, 0x20), m2)\n }\n } else {\n // Insufficient space, so copy slice forward, add header and reverse.\n bytes32 m0;\n bytes32 m1;\n bytes32 m2;\n uint256 endOffset = offset + length;\n /// @solidity memory-safe-assembly\n assembly {\n m0 := mload(add(endOffset, 0x00))\n m1 := mload(add(endOffset, 0x20))\n m2 := mload(add(endOffset, 0x40))\n }\n _memcopy(offset, offset + 0x60, length);\n /// @solidity memory-safe-assembly\n assembly {\n // Selector of `log(bytes)`.\n mstore(add(offset, 0x00), 0x0be77f56)\n mstore(add(offset, 0x20), 0x20)\n mstore(add(offset, 0x40), length)\n }\n _sendLogPayload(offset + 0x1c, length + 0x44);\n _memcopy(offset + 0x60, offset, length);\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(endOffset, 0x00), m0)\n mstore(add(endOffset, 0x20), m1)\n mstore(add(endOffset, 0x40), m2)\n }\n }\n }\n\n function log(address p0) internal pure {\n bytes32 m0;\n bytes32 m1;\n /// @solidity memory-safe-assembly\n assembly {\n m0 := mload(0x00)\n m1 := mload(0x20)\n // Selector of `log(address)`.\n mstore(0x00, 0x2c2ecbc2)\n mstore(0x20, p0)\n }\n _sendLogPayload(0x1c, 0x24);\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, m0)\n mstore(0x20, m1)\n }\n }\n\n function log(bool p0) internal pure {\n bytes32 m0;\n bytes32 m1;\n /// @solidity memory-safe-assembly\n assembly {\n m0 := mload(0x00)\n m1 := mload(0x20)\n // Selector of `log(bool)`.\n mstore(0x00, 0x32458eed)\n mstore(0x20, p0)\n }\n _sendLogPayload(0x1c, 0x24);\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, m0)\n mstore(0x20, m1)\n }\n }\n\n function lLine truncated
|
|
||||||
},
|
|
||||||
"script/Counter.s.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport {Script, console} from \"forge-std/Script.sol\";\nimport {Counter} from \"../src/Counter.sol\";\n\ncontract CounterScript is Script {\n Counter public counter;\n\n function setUp() public {}\n\n function run() public {\n vm.startBroadcast();\n\n counter = new Counter();\n\n vm.stopBroadcast();\n }\n}\n"
|
|
||||||
},
|
|
||||||
"src/Counter.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ncontract Counter {\n uint256 public number;\n\n function setNumber(uint256 newNumber) public {\n number = newNumber;\n }\n\n function increment() public {\n number++;\n }\n}\n"
|
|
||||||
},
|
|
||||||
"test/Counter.t.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport {Test, console} from \"forge-std/Test.sol\";\nimport {Counter} from \"../src/Counter.sol\";\n\ncontract CounterTest is Test {\n Counter public counter;\n\n function setUp() public {\n counter = new Counter();\n counter.setNumber(0);\n }\n\n function test_Increment() public {\n counter.increment();\n assertEq(counter.number(), 1);\n }\n\n function testFuzz_SetNumber(uint256 x) public {\n counter.setNumber(x);\n assertEq(counter.number(), x);\n }\n}\n"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"settings": {
|
"lib/forge-std/src/Script.sol": {
|
||||||
"optimizer": {
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\n// 💬 ABOUT\n// Forge Std's default Script.\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {safeconsole} from \"./safeconsole.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheatsSafe} from \"./StdCheats.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorageSafe} from \"./StdStorage.sol\";\nimport {StdStyle} from \"./StdStyle.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {VmSafe} from \"./Vm.sol\";\n\n// 📦 BOILERPLATE\nimport {ScriptBase} from \"./Base.sol\";\n\n// ⭐️ SCRIPT\nabstract contract Script is ScriptBase, StdChains, StdCheatsSafe, StdUtils {\n // Note: IS_SCRIPT() must return true.\n bool public IS_SCRIPT = true;\n}\n"
|
||||||
"enabled": false,
|
},
|
||||||
"runs": 200
|
"lib/forge-std/src/StdAssertions.sol": {
|
||||||
},
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\npragma experimental ABIEncoderV2;\n\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdAssertions {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n event log(string);\n event logs(bytes);\n\n event log_address(address);\n event log_bytes32(bytes32);\n event log_int(int256);\n event log_uint(uint256);\n event log_bytes(bytes);\n event log_string(string);\n\n event log_named_address(string key, address val);\n event log_named_bytes32(string key, bytes32 val);\n event log_named_decimal_int(string key, int256 val, uint256 decimals);\n event log_named_decimal_uint(string key, uint256 val, uint256 decimals);\n event log_named_int(string key, int256 val);\n event log_named_uint(string key, uint256 val);\n event log_named_bytes(string key, bytes val);\n event log_named_string(string key, string val);\n\n event log_array(uint256[] val);\n event log_array(int256[] val);\n event log_array(address[] val);\n event log_named_array(string key, uint256[] val);\n event log_named_array(string key, int256[] val);\n event log_named_array(string key, address[] val);\n\n bool private _failed;\n\n function failed() public view returns (bool) {\n if (_failed) {\n return _failed;\n } else {\n return vm.load(address(vm), bytes32(\"failed\")) != bytes32(0);\n }\n }\n\n function fail() internal virtual {\n vm.store(address(vm), bytes32(\"failed\"), bytes32(uint256(1)));\n _failed = true;\n }\n\n function assertTrue(bool data) internal pure virtual {\n vm.assertTrue(data);\n }\n\n function assertTrue(bool data, string memory err) internal pure virtual {\n vm.assertTrue(data, err);\n }\n\n function assertFalse(bool data) internal pure virtual {\n vm.assertFalse(data);\n }\n\n function assertFalse(bool data, string memory err) internal pure virtual {\n vm.assertFalse(data, err);\n }\n\n function assertEq(bool left, bool right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(bool left, bool right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEq(uint256 left, uint256 right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(uint256 left, uint256 right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual {\n vm.assertEqDecimal(left, right, decimals);\n }\n\n function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual {\n vm.assertEqDecimal(left, right, decimals, err);\n }\n\n function assertEq(int256 left, int256 right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(int256 left, int256 right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual {\n vm.assertEqDecimal(left, right, decimals);\n }\n\n function assertEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual {\n vm.assertEqDecimal(left, right, decimals, err);\n }\n\n function assertEq(address left, address right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(address left, address right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEq(bytes32 left, bytes32 right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(bytes32 left, bytes32 right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEq32(bytes32 left, bytes32 right) internal pure virtual {\n assertEq(left, right);\n }\n\n function assertEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual {\n assertEq(left, right, err);\n }\n\n function assertEq(string memory left, string memory right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(string memory left, string memory right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEq(bytes memory left, bytes memory right) internal pure virtual {\n vm.assertEq(left, right);\n }\n\n function assertEq(bytes memory left, bytes memory right, string memory err) internal pure virtual {\n vm.assertEq(left, right, err);\n }\n\n function assertEq(bool[] memory left, bool[] memoryLine truncated
|
||||||
"outputSelection": {
|
},
|
||||||
"*": {
|
"lib/forge-std/src/StdChains.sol": {
|
||||||
"": [
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n/**\n * StdChains provides information about EVM compatible chains that can be used in scripts/tests.\n * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are\n * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of\n * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the\n * alias used in this contract, which can be found as the first argument to the\n * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function.\n *\n * There are two main ways to use this contract:\n * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or\n * `setChain(string memory chainAlias, Chain memory chain)`\n * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`.\n *\n * The first time either of those are used, chains are initialized with the default set of RPC URLs.\n * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in\n * `defaultRpcUrls`.\n *\n * The `setChain` function is straightforward, and it simply saves off the given chain data.\n *\n * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say\n * we want to retrieve the RPC URL for `mainnet`:\n * - If you have specified data with `setChain`, it will return that.\n * - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it\n * is valid (e.g. a URL is specified, or an environment variable is given and exists).\n * - If neither of the above conditions is met, the default data is returned.\n *\n * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.\n */\nabstract contract StdChains {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n bool private stdChainsInitialized;\n\n struct ChainData {\n string name;\n uint256 chainId;\n string rpcUrl;\n }\n\n struct Chain {\n // The chain name.\n string name;\n // The chain's Chain ID.\n uint256 chainId;\n // The chain's alias. (i.e. what gets specified in `foundry.toml`).\n string chainAlias;\n // A default RPC endpoint for this chain.\n // NOTE: This default RPC URL is included for convenience to facilitate quick tests and\n // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy\n // usage as you will be throttled and this is a disservice to others who need this endpoint.\n string rpcUrl;\n }\n\n // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data.\n mapping(string => Chain) private chains;\n // Maps from the chain's alias to it's default RPC URL.\n mapping(string => string) private defaultRpcUrls;\n // Maps from a chain ID to it's alias.\n mapping(uint256 => string) private idToAlias;\n\n bool private fallbackToDefaultRpcUrls = true;\n\n // The RPC URL will be fetched from config or defaultRpcUrls if possible.\n function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) {\n require(bytes(chainAlias).length != 0, \"StdChains getChain(string): Chain alias cannot be the empty string.\");\n\n initializeStdChains();\n chain = chains[chainAlias];\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(string): Chain with alias \\\"\", chainAlias, \"\\\" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n function getChain(uint256 chainId) internal virtual returns (Chain memory chain) {\n require(chainId != 0, \"StdChains getChain(uint256): Chain ID cannot be 0.\");\n initializeStdChains();\n string memory chainAlias = idToAlias[chainId];\n\n chain = chains[chainAlias];\n\n require(\n chain.chainId != 0,\n string(abi.encodePacked(\"StdChains getChain(uint256): Chain with ID \", vm.toString(chainId), \" not found.\"))\n );\n\n chain = getChainWithUpdatedRpcUrl(chainAlias, chain);\n }\n\n // set chain info, with priority to argument's rpcUrl field.\n function setChain(string memory chainAlias, ChainData memory chain) internal virtual {\n require(\n bytes(chainAlias).length != 0,\n \"StdChains setChain(string,ChainData): Chain alias cannot be the empty string.\"\n );\n\n require(chain.chainId != 0, \"StdChains setChain(string,ChainData): Chain ID cannot be 0.\");\n\n initializeStdChains();\n string memory foundAlias = idToAlias[chain.chainId];\n\n Line truncated
|
||||||
"ast"
|
},
|
||||||
]
|
"lib/forge-std/src/StdCheats.sol": {
|
||||||
}
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {console2} from \"./console2.sol\";\nimport {Vm} from \"./Vm.sol\";\n\nabstract contract StdCheatsSafe {\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n bool private gasMeteringOff;\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawTx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n // json value name = function\n string functionSig;\n bytes32 hash;\n // json value name = tx\n RawTx1559Detail txDetail;\n // json value name = type\n string opcode;\n }\n\n struct RawTx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n bytes gas;\n bytes nonce;\n address to;\n bytes txType;\n bytes value;\n }\n\n struct Tx1559 {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n bytes32 hash;\n Tx1559Detail txDetail;\n string opcode;\n }\n\n struct Tx1559Detail {\n AccessList[] accessList;\n bytes data;\n address from;\n uint256 gas;\n uint256 nonce;\n address to;\n uint256 txType;\n uint256 value;\n }\n\n // Data structures to parse Transaction objects from the broadcast artifact\n // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct TxLegacy {\n string[] arguments;\n address contractAddress;\n string contractName;\n string functionSig;\n string hash;\n string opcode;\n TxDetailLegacy transaction;\n }\n\n struct TxDetailLegacy {\n AccessList[] accessList;\n uint256 chainId;\n bytes data;\n address from;\n uint256 gas;\n uint256 gasPrice;\n bytes32 hash;\n uint256 nonce;\n bytes1 opcode;\n bytes32 r;\n bytes32 s;\n uint256 txType;\n address to;\n uint8 v;\n uint256 value;\n }\n\n struct AccessList {\n address accessAddress;\n bytes32[] storageKeys;\n }\n\n // Data structures to parse Receipt objects from the broadcast artifact.\n // The Raw structs is what is parsed from the JSON\n // and then converted to the one that is used by the user for better UX.\n\n struct RawReceipt {\n bytes32 blockHash;\n bytes blockNumber;\n address contractAddress;\n bytes cumulativeGasUsed;\n bytes effectiveGasPrice;\n address from;\n bytes gasUsed;\n RawReceiptLog[] logs;\n bytes logsBloom;\n bytes status;\n address to;\n bytes32 transactionHash;\n bytes transactionIndex;\n }\n\n struct Receipt {\n bytes32 blockHash;\n uint256 blockNumber;\n address contractAddress;\n uint256 cumulativeGasUsed;\n uint256 effectiveGasPrice;\n address from;\n uint256 gasUsed;\n ReceiptLog[] logs;\n bytes logsBloom;\n uint256 status;\n address to;\n bytes32 transactionHash;\n uint256 transactionIndex;\n }\n\n // Data structures to parse the entire broadcast artifact, assuming the\n // transactions conform to EIP1559.\n\n struct EIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n Receipt[] receipts;\n uint256 timestamp;\n Tx1559[] transactions;\n TxReturn[] txReturns;\n }\n\n struct RawEIP1559ScriptArtifact {\n string[] libraries;\n string path;\n string[] pending;\n RawReceipt[] receipts;\n TxReturn[] txReturns;\n uint256 timestamp;\n RawTx1559[] transactions;\n }\n\n struct RawReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n bytes blockNumber;\n bytes data;\n bytes logIndex;\n bool removed;\n bytes32[] topics;\n bytes32 transactionHash;\n bytes transactionIndex;\n bytes transactionLogIndex;\n }\n\n struct ReceiptLog {\n // json value = address\n address logAddress;\n bytes32 blockHash;\n uint256 blockNumber;\n bytes data;\n uint256 logIndLine truncated
|
||||||
},
|
},
|
||||||
"evmVersion": "berlin",
|
"lib/forge-std/src/StdError.sol": {
|
||||||
"remappings": [
|
"content": "// SPDX-License-Identifier: MIT\n// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdError {\n bytes public constant assertionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x01);\n bytes public constant arithmeticError = abi.encodeWithSignature(\"Panic(uint256)\", 0x11);\n bytes public constant divisionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x12);\n bytes public constant enumConversionError = abi.encodeWithSignature(\"Panic(uint256)\", 0x21);\n bytes public constant encodeStorageError = abi.encodeWithSignature(\"Panic(uint256)\", 0x22);\n bytes public constant popError = abi.encodeWithSignature(\"Panic(uint256)\", 0x31);\n bytes public constant indexOOBError = abi.encodeWithSignature(\"Panic(uint256)\", 0x32);\n bytes public constant memOverflowError = abi.encodeWithSignature(\"Panic(uint256)\", 0x41);\n bytes public constant zeroVarError = abi.encodeWithSignature(\"Panic(uint256)\", 0x51);\n}\n"
|
||||||
"forge-std/=lib/forge-std/src/"
|
},
|
||||||
]
|
"lib/forge-std/src/StdInvariant.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nabstract contract StdInvariant {\n struct FuzzSelector {\n address addr;\n bytes4[] selectors;\n }\n\n struct FuzzArtifactSelector {\n string artifact;\n bytes4[] selectors;\n }\n\n struct FuzzInterface {\n address addr;\n string[] artifacts;\n }\n\n address[] private _excludedContracts;\n address[] private _excludedSenders;\n address[] private _targetedContracts;\n address[] private _targetedSenders;\n\n string[] private _excludedArtifacts;\n string[] private _targetedArtifacts;\n\n FuzzArtifactSelector[] private _targetedArtifactSelectors;\n\n FuzzSelector[] private _excludedSelectors;\n FuzzSelector[] private _targetedSelectors;\n\n FuzzInterface[] private _targetedInterfaces;\n\n // Functions for users:\n // These are intended to be called in tests.\n\n function excludeContract(address newExcludedContract_) internal {\n _excludedContracts.push(newExcludedContract_);\n }\n\n function excludeSelector(FuzzSelector memory newExcludedSelector_) internal {\n _excludedSelectors.push(newExcludedSelector_);\n }\n\n function excludeSender(address newExcludedSender_) internal {\n _excludedSenders.push(newExcludedSender_);\n }\n\n function excludeArtifact(string memory newExcludedArtifact_) internal {\n _excludedArtifacts.push(newExcludedArtifact_);\n }\n\n function targetArtifact(string memory newTargetedArtifact_) internal {\n _targetedArtifacts.push(newTargetedArtifact_);\n }\n\n function targetArtifactSelector(FuzzArtifactSelector memory newTargetedArtifactSelector_) internal {\n _targetedArtifactSelectors.push(newTargetedArtifactSelector_);\n }\n\n function targetContract(address newTargetedContract_) internal {\n _targetedContracts.push(newTargetedContract_);\n }\n\n function targetSelector(FuzzSelector memory newTargetedSelector_) internal {\n _targetedSelectors.push(newTargetedSelector_);\n }\n\n function targetSender(address newTargetedSender_) internal {\n _targetedSenders.push(newTargetedSender_);\n }\n\n function targetInterface(FuzzInterface memory newTargetedInterface_) internal {\n _targetedInterfaces.push(newTargetedInterface_);\n }\n\n // Functions for forge:\n // These are called by forge to run invariant tests and don't need to be called in tests.\n\n function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) {\n excludedArtifacts_ = _excludedArtifacts;\n }\n\n function excludeContracts() public view returns (address[] memory excludedContracts_) {\n excludedContracts_ = _excludedContracts;\n }\n\n function excludeSelectors() public view returns (FuzzSelector[] memory excludedSelectors_) {\n excludedSelectors_ = _excludedSelectors;\n }\n\n function excludeSenders() public view returns (address[] memory excludedSenders_) {\n excludedSenders_ = _excludedSenders;\n }\n\n function targetArtifacts() public view returns (string[] memory targetedArtifacts_) {\n targetedArtifacts_ = _targetedArtifacts;\n }\n\n function targetArtifactSelectors() public view returns (FuzzArtifactSelector[] memory targetedArtifactSelectors_) {\n targetedArtifactSelectors_ = _targetedArtifactSelectors;\n }\n\n function targetContracts() public view returns (address[] memory targetedContracts_) {\n targetedContracts_ = _targetedContracts;\n }\n\n function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) {\n targetedSelectors_ = _targetedSelectors;\n }\n\n function targetSenders() public view returns (address[] memory targetedSenders_) {\n targetedSenders_ = _targetedSenders;\n }\n\n function targetInterfaces() public view returns (FuzzInterface[] memory targetedInterfaces_) {\n targetedInterfaces_ = _targetedInterfaces;\n }\n}\n"
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/StdJson.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing JSON files\n// To parse:\n// ```\n// using stdJson for string;\n// string memory json = vm.readFile(\"<some_path>\");\n// json.readUint(\"<json_path>\");\n// ```\n// To write:\n// ```\n// using stdJson for string;\n// string memory json = \"json\";\n// json.serialize(\"a\", uint256(123));\n// string memory semiFinal = json.serialize(\"b\", string(\"test\"));\n// string memory finalJson = json.serialize(\"c\", semiFinal);\n// finalJson.write(\"<some_path>\");\n// ```\n\nlibrary stdJson {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function keyExists(string memory json, string memory key) internal view returns (bool) {\n return vm.keyExistsJson(json, key);\n }\n\n function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJson(json, key);\n }\n\n function readUint(string memory json, string memory key) internal pure returns (uint256) {\n return vm.parseJsonUint(json, key);\n }\n\n function readUintArray(string memory json, string memory key) internal pure returns (uint256[] memory) {\n return vm.parseJsonUintArray(json, key);\n }\n\n function readInt(string memory json, string memory key) internal pure returns (int256) {\n return vm.parseJsonInt(json, key);\n }\n\n function readIntArray(string memory json, string memory key) internal pure returns (int256[] memory) {\n return vm.parseJsonIntArray(json, key);\n }\n\n function readBytes32(string memory json, string memory key) internal pure returns (bytes32) {\n return vm.parseJsonBytes32(json, key);\n }\n\n function readBytes32Array(string memory json, string memory key) internal pure returns (bytes32[] memory) {\n return vm.parseJsonBytes32Array(json, key);\n }\n\n function readString(string memory json, string memory key) internal pure returns (string memory) {\n return vm.parseJsonString(json, key);\n }\n\n function readStringArray(string memory json, string memory key) internal pure returns (string[] memory) {\n return vm.parseJsonStringArray(json, key);\n }\n\n function readAddress(string memory json, string memory key) internal pure returns (address) {\n return vm.parseJsonAddress(json, key);\n }\n\n function readAddressArray(string memory json, string memory key) internal pure returns (address[] memory) {\n return vm.parseJsonAddressArray(json, key);\n }\n\n function readBool(string memory json, string memory key) internal pure returns (bool) {\n return vm.parseJsonBool(json, key);\n }\n\n function readBoolArray(string memory json, string memory key) internal pure returns (bool[] memory) {\n return vm.parseJsonBoolArray(json, key);\n }\n\n function readBytes(string memory json, string memory key) internal pure returns (bytes memory) {\n return vm.parseJsonBytes(json, key);\n }\n\n function readBytesArray(string memory json, string memory key) internal pure returns (bytes[] memory) {\n return vm.parseJsonBytesArray(json, key);\n }\n\n function readUintOr(string memory json, string memory key, uint256 defaultValue) internal view returns (uint256) {\n return keyExists(json, key) ? readUint(json, key) : defaultValue;\n }\n\n function readUintArrayOr(string memory json, string memory key, uint256[] memory defaultValue)\n internal\n view\n returns (uint256[] memory)\n {\n return keyExists(json, key) ? readUintArray(json, key) : defaultValue;\n }\n\n function readIntOr(string memory json, string memory key, int256 defaultValue) internal view returns (int256) {\n return keyExists(json, key) ? readInt(json, key) : defaultValue;\n }\n\n function readIntArrayOr(string memory json, string memory key, int256[] memory defaultValue)\n internal\n view\n returns (int256[] memory)\n {\n return keyExists(json, key) ? readIntArray(json, key) : defaultValue;\n }\n\n function readBytes32Or(string memory json, string memory key, bytes32 defaultValue)\n internal\n view\n returns (bytes32)\n {\n return keyExists(json, key) ? readBytes32(json, key) : defaultValue;\n }\n\n function readBytes32ArrayOr(string memory json, string memory key, bytes32[] memory defaultValue)\n internal\n view\n returns (bytes32[] memory)\n {\n return keyExists(json, key) ? readBytes32Array(json, key) : defaultValue;\n }\n\n function readStringOr(string memory json, string memory key, string memory defaultValue)\n internal\n view\n returns (string memory)\n {\n return keyExists(json, key) ?Line truncated
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/StdMath.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nlibrary stdMath {\n int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968;\n\n function abs(int256 a) internal pure returns (uint256) {\n // Required or it will fail when `a = type(int256).min`\n if (a == INT256_MIN) {\n return 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n }\n\n return uint256(a > 0 ? a : -a);\n }\n\n function delta(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a - b : b - a;\n }\n\n function delta(int256 a, int256 b) internal pure returns (uint256) {\n // a and b are of the same sign\n // this works thanks to two's complement, the left-most bit is the sign bit\n if ((a ^ b) > -1) {\n return delta(abs(a), abs(b));\n }\n\n // a and b are of opposite signs\n return abs(a) + abs(b);\n }\n\n function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n\n return absDelta * 1e18 / b;\n }\n\n function percentDelta(int256 a, int256 b) internal pure returns (uint256) {\n uint256 absDelta = delta(a, b);\n uint256 absB = abs(b);\n\n return absDelta * 1e18 / absB;\n }\n}\n"
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/StdStorage.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {Vm} from \"./Vm.sol\";\n\nstruct FindData {\n uint256 slot;\n uint256 offsetLeft;\n uint256 offsetRight;\n bool found;\n}\n\nstruct StdStorage {\n mapping(address => mapping(bytes4 => mapping(bytes32 => FindData))) finds;\n bytes32[] _keys;\n bytes4 _sig;\n uint256 _depth;\n address _target;\n bytes32 _set;\n bool _enable_packed_slots;\n bytes _calldata;\n}\n\nlibrary stdStorageSafe {\n event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot);\n event WARNING_UninitedSlot(address who, uint256 slot);\n\n Vm private constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n uint256 constant UINT256_MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n function sigs(string memory sigStr) internal pure returns (bytes4) {\n return bytes4(keccak256(bytes(sigStr)));\n }\n\n function getCallParams(StdStorage storage self) internal view returns (bytes memory) {\n if (self._calldata.length == 0) {\n return flatten(self._keys);\n } else {\n return self._calldata;\n }\n }\n\n // Calls target contract with configured parameters\n function callTarget(StdStorage storage self) internal view returns (bool, bytes32) {\n bytes memory cald = abi.encodePacked(self._sig, getCallParams(self));\n (bool success, bytes memory rdat) = self._target.staticcall(cald);\n bytes32 result = bytesToBytes32(rdat, 32 * self._depth);\n\n return (success, result);\n }\n\n // Tries mutating slot value to determine if the targeted value is stored in it.\n // If current value is 0, then we are setting slot value to type(uint256).max\n // Otherwise, we set it to 0. That way, return value should always be affected.\n function checkSlotMutatesCall(StdStorage storage self, bytes32 slot) internal returns (bool) {\n bytes32 prevSlotValue = vm.load(self._target, slot);\n (bool success, bytes32 prevReturnValue) = callTarget(self);\n\n bytes32 testVal = prevReturnValue == bytes32(0) ? bytes32(UINT256_MAX) : bytes32(0);\n vm.store(self._target, slot, testVal);\n\n (, bytes32 newReturnValue) = callTarget(self);\n\n vm.store(self._target, slot, prevSlotValue);\n\n return (success && (prevReturnValue != newReturnValue));\n }\n\n // Tries setting one of the bits in slot to 1 until return value changes.\n // Index of resulted bit is an offset packed slot has from left/right side\n function findOffset(StdStorage storage self, bytes32 slot, bool left) internal returns (bool, uint256) {\n for (uint256 offset = 0; offset < 256; offset++) {\n uint256 valueToPut = left ? (1 << (255 - offset)) : (1 << offset);\n vm.store(self._target, slot, bytes32(valueToPut));\n\n (bool success, bytes32 data) = callTarget(self);\n\n if (success && (uint256(data) > 0)) {\n return (true, offset);\n }\n }\n return (false, 0);\n }\n\n function findOffsets(StdStorage storage self, bytes32 slot) internal returns (bool, uint256, uint256) {\n bytes32 prevSlotValue = vm.load(self._target, slot);\n\n (bool foundLeft, uint256 offsetLeft) = findOffset(self, slot, true);\n (bool foundRight, uint256 offsetRight) = findOffset(self, slot, false);\n\n // `findOffset` may mutate slot value, so we are setting it to initial value\n vm.store(self._target, slot, prevSlotValue);\n return (foundLeft && foundRight, offsetLeft, offsetRight);\n }\n\n function find(StdStorage storage self) internal returns (FindData storage) {\n return find(self, true);\n }\n\n /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against\n // slot complexity:\n // if flat, will be bytes32(uint256(uint));\n // if map, will be keccak256(abi.encode(key, uint(slot)));\n // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))));\n // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth);\n function find(StdStorage storage self, bool _clear) internal returns (FindData storage) {\n address who = self._target;\n bytes4 fsig = self._sig;\n uint256 field_depth = self._depth;\n bytes memory params = getCallParams(self);\n\n // calldata to test against\n if (self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) {\n if (_clear) {\n clear(self);\n }\n return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))];\n }\n vm.record();\n (, bytes32 callResult) = cLine truncated
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/StdStyle.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nimport {VmSafe} from \"./Vm.sol\";\n\nlibrary StdStyle {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n string constant RED = \"\\u001b[91m\";\n string constant GREEN = \"\\u001b[92m\";\n string constant YELLOW = \"\\u001b[93m\";\n string constant BLUE = \"\\u001b[94m\";\n string constant MAGENTA = \"\\u001b[95m\";\n string constant CYAN = \"\\u001b[96m\";\n string constant BOLD = \"\\u001b[1m\";\n string constant DIM = \"\\u001b[2m\";\n string constant ITALIC = \"\\u001b[3m\";\n string constant UNDERLINE = \"\\u001b[4m\";\n string constant INVERSE = \"\\u001b[7m\";\n string constant RESET = \"\\u001b[0m\";\n\n function styleConcat(string memory style, string memory self) private pure returns (string memory) {\n return string(abi.encodePacked(style, self, RESET));\n }\n\n function red(string memory self) internal pure returns (string memory) {\n return styleConcat(RED, self);\n }\n\n function red(uint256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(int256 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(address self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function red(bool self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes(bytes memory self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function redBytes32(bytes32 self) internal pure returns (string memory) {\n return red(vm.toString(self));\n }\n\n function green(string memory self) internal pure returns (string memory) {\n return styleConcat(GREEN, self);\n }\n\n function green(uint256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(int256 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(address self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function green(bool self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes(bytes memory self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function greenBytes32(bytes32 self) internal pure returns (string memory) {\n return green(vm.toString(self));\n }\n\n function yellow(string memory self) internal pure returns (string memory) {\n return styleConcat(YELLOW, self);\n }\n\n function yellow(uint256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(int256 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(address self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellow(bool self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes(bytes memory self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function yellowBytes32(bytes32 self) internal pure returns (string memory) {\n return yellow(vm.toString(self));\n }\n\n function blue(string memory self) internal pure returns (string memory) {\n return styleConcat(BLUE, self);\n }\n\n function blue(uint256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(int256 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(address self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blue(bool self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes(bytes memory self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function blueBytes32(bytes32 self) internal pure returns (string memory) {\n return blue(vm.toString(self));\n }\n\n function magenta(string memory self) internal pure returns (string memory) {\n return styleConcat(MAGENTA, self);\n }\n\n function magenta(uint256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(int256 self) internal pure returns (string memory) {\n return magenta(vm.toString(self));\n }\n\n function magenta(address self) internal pure returns (string memory) {\n Line truncated
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/StdToml.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {VmSafe} from \"./Vm.sol\";\n\n// Helpers for parsing and writing TOML files\n// To parse:\n// ```\n// using stdToml for string;\n// string memory toml = vm.readFile(\"<some_path>\");\n// toml.readUint(\"<json_path>\");\n// ```\n// To write:\n// ```\n// using stdToml for string;\n// string memory json = \"json\";\n// json.serialize(\"a\", uint256(123));\n// string memory semiFinal = json.serialize(\"b\", string(\"test\"));\n// string memory finalJson = json.serialize(\"c\", semiFinal);\n// finalJson.write(\"<some_path>\");\n// ```\n\nlibrary stdToml {\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n\n function keyExists(string memory toml, string memory key) internal view returns (bool) {\n return vm.keyExistsToml(toml, key);\n }\n\n function parseRaw(string memory toml, string memory key) internal pure returns (bytes memory) {\n return vm.parseToml(toml, key);\n }\n\n function readUint(string memory toml, string memory key) internal pure returns (uint256) {\n return vm.parseTomlUint(toml, key);\n }\n\n function readUintArray(string memory toml, string memory key) internal pure returns (uint256[] memory) {\n return vm.parseTomlUintArray(toml, key);\n }\n\n function readInt(string memory toml, string memory key) internal pure returns (int256) {\n return vm.parseTomlInt(toml, key);\n }\n\n function readIntArray(string memory toml, string memory key) internal pure returns (int256[] memory) {\n return vm.parseTomlIntArray(toml, key);\n }\n\n function readBytes32(string memory toml, string memory key) internal pure returns (bytes32) {\n return vm.parseTomlBytes32(toml, key);\n }\n\n function readBytes32Array(string memory toml, string memory key) internal pure returns (bytes32[] memory) {\n return vm.parseTomlBytes32Array(toml, key);\n }\n\n function readString(string memory toml, string memory key) internal pure returns (string memory) {\n return vm.parseTomlString(toml, key);\n }\n\n function readStringArray(string memory toml, string memory key) internal pure returns (string[] memory) {\n return vm.parseTomlStringArray(toml, key);\n }\n\n function readAddress(string memory toml, string memory key) internal pure returns (address) {\n return vm.parseTomlAddress(toml, key);\n }\n\n function readAddressArray(string memory toml, string memory key) internal pure returns (address[] memory) {\n return vm.parseTomlAddressArray(toml, key);\n }\n\n function readBool(string memory toml, string memory key) internal pure returns (bool) {\n return vm.parseTomlBool(toml, key);\n }\n\n function readBoolArray(string memory toml, string memory key) internal pure returns (bool[] memory) {\n return vm.parseTomlBoolArray(toml, key);\n }\n\n function readBytes(string memory toml, string memory key) internal pure returns (bytes memory) {\n return vm.parseTomlBytes(toml, key);\n }\n\n function readBytesArray(string memory toml, string memory key) internal pure returns (bytes[] memory) {\n return vm.parseTomlBytesArray(toml, key);\n }\n\n function readUintOr(string memory toml, string memory key, uint256 defaultValue) internal view returns (uint256) {\n return keyExists(toml, key) ? readUint(toml, key) : defaultValue;\n }\n\n function readUintArrayOr(string memory toml, string memory key, uint256[] memory defaultValue)\n internal\n view\n returns (uint256[] memory)\n {\n return keyExists(toml, key) ? readUintArray(toml, key) : defaultValue;\n }\n\n function readIntOr(string memory toml, string memory key, int256 defaultValue) internal view returns (int256) {\n return keyExists(toml, key) ? readInt(toml, key) : defaultValue;\n }\n\n function readIntArrayOr(string memory toml, string memory key, int256[] memory defaultValue)\n internal\n view\n returns (int256[] memory)\n {\n return keyExists(toml, key) ? readIntArray(toml, key) : defaultValue;\n }\n\n function readBytes32Or(string memory toml, string memory key, bytes32 defaultValue)\n internal\n view\n returns (bytes32)\n {\n return keyExists(toml, key) ? readBytes32(toml, key) : defaultValue;\n }\n\n function readBytes32ArrayOr(string memory toml, string memory key, bytes32[] memory defaultValue)\n internal\n view\n returns (bytes32[] memory)\n {\n return keyExists(toml, key) ? readBytes32Array(toml, key) : defaultValue;\n }\n\n function readStringOr(string memory toml, string memory key, string memory defaultValue)\n internal\n view\n returns (string memory)\n {\n return keyExists(toml, key) ?Line truncated
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/StdUtils.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\nimport {IMulticall3} from \"./interfaces/IMulticall3.sol\";\nimport {MockERC20} from \"./mocks/MockERC20.sol\";\nimport {MockERC721} from \"./mocks/MockERC721.sol\";\nimport {VmSafe} from \"./Vm.sol\";\n\nabstract contract StdUtils {\n /*//////////////////////////////////////////////////////////////////////////\n CONSTANTS\n //////////////////////////////////////////////////////////////////////////*/\n\n IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11);\n VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67;\n uint256 private constant INT256_MIN_ABS =\n 57896044618658097711785492504343953926634992332820282019728792003956564819968;\n uint256 private constant SECP256K1_ORDER =\n 115792089237316195423570985008687907852837564279074904382605163141518161494337;\n uint256 private constant UINT256_MAX =\n 115792089237316195423570985008687907853269984665640564039457584007913129639935;\n\n // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy.\n address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C;\n\n /*//////////////////////////////////////////////////////////////////////////\n INTERNAL FUNCTIONS\n //////////////////////////////////////////////////////////////////////////*/\n\n function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n require(min <= max, \"StdUtils bound(uint256,uint256,uint256): Max is less than min.\");\n // If x is between min and max, return x directly. This is to ensure that dictionary values\n // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188\n if (x >= min && x <= max) return x;\n\n uint256 size = max - min + 1;\n\n // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side.\n // This helps ensure coverage of the min/max values.\n if (x <= 3 && size > x) return min + x;\n if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x);\n\n // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.\n if (x > max) {\n uint256 diff = x - max;\n uint256 rem = diff % size;\n if (rem == 0) return max;\n result = min + rem - 1;\n } else if (x < min) {\n uint256 diff = min - x;\n uint256 rem = diff % size;\n if (rem == 0) return min;\n result = max - rem + 1;\n }\n }\n\n function bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) {\n result = _bound(x, min, max);\n console2_log_StdUtils(\"Bound result\", result);\n }\n\n function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) {\n require(min <= max, \"StdUtils bound(int256,int256,int256): Max is less than min.\");\n\n // Shifting all int256 values to uint256 to use _bound function. The range of two types are:\n // int256 : -(2**255) ~ (2**255 - 1)\n // uint256: 0 ~ (2**256 - 1)\n // So, add 2**255, INT256_MIN_ABS to the integer values.\n //\n // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow.\n // So, use `~uint256(x) + 1` instead.\n uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS);\n uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS);\n uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS);\n\n uint256 y = _bound(_x, _min, _max);\n\n // To move it back to int256 value, subtract INT256_MIN_ABS at here.\n result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS);\n }\n\n function bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) {\n result = _bound(x, min, max);\n console2_log_StdUtils(\"Bound result\", vm.toString(result));\n }\n\n function boundPrivateKey(uint256 privateKey) internal pure virtual returns (uint256 result) {\n result = _bound(privateKey, 1, SECP256K1_ORDER - 1);\n }\n\n function bytesToUint(bytes memory b) internal pure virtual returns (uint256) {\n require(b.length <= 32, \"StdUtils bytesToUint(bytes): Bytes length exceeds 32.\");\n return abi.decode(abi.encodePacked(newLine truncated
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/Test.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\n// 💬 ABOUT\n// Forge Std's default Test.\n\n// 🧩 MODULES\nimport {console} from \"./console.sol\";\nimport {console2} from \"./console2.sol\";\nimport {safeconsole} from \"./safeconsole.sol\";\nimport {StdAssertions} from \"./StdAssertions.sol\";\nimport {StdChains} from \"./StdChains.sol\";\nimport {StdCheats} from \"./StdCheats.sol\";\nimport {stdError} from \"./StdError.sol\";\nimport {StdInvariant} from \"./StdInvariant.sol\";\nimport {stdJson} from \"./StdJson.sol\";\nimport {stdMath} from \"./StdMath.sol\";\nimport {StdStorage, stdStorage} from \"./StdStorage.sol\";\nimport {StdStyle} from \"./StdStyle.sol\";\nimport {stdToml} from \"./StdToml.sol\";\nimport {StdUtils} from \"./StdUtils.sol\";\nimport {Vm} from \"./Vm.sol\";\n\n// 📦 BOILERPLATE\nimport {TestBase} from \"./Base.sol\";\n\n// ⭐️ TEST\nabstract contract Test is TestBase, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils {\n // Note: IS_TEST() must return true.\n bool public IS_TEST = true;\n}\n"
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/Vm.sol": {
|
||||||
|
"content": "// Automatically @generated by scripts/vm.py. Do not modify manually.\n\n// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.6.2 <0.9.0;\npragma experimental ABIEncoderV2;\n\n/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may\n/// result in Script simulations differing from on-chain execution. It is recommended to only use\n/// these cheats in scripts.\ninterface VmSafe {\n /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`.\n enum CallerMode {\n // No caller modification is currently active.\n None,\n // A one time broadcast triggered by a `vm.broadcast()` call is currently active.\n Broadcast,\n // A recurrent broadcast triggered by a `vm.startBroadcast()` call is currently active.\n RecurrentBroadcast,\n // A one time prank triggered by a `vm.prank()` call is currently active.\n Prank,\n // A recurrent prank triggered by a `vm.startPrank()` call is currently active.\n RecurrentPrank\n }\n\n /// The kind of account access that occurred.\n enum AccountAccessKind {\n // The account was called.\n Call,\n // The account was called via delegatecall.\n DelegateCall,\n // The account was called via callcode.\n CallCode,\n // The account was called via staticcall.\n StaticCall,\n // The account was created.\n Create,\n // The account was selfdestructed.\n SelfDestruct,\n // Synthetic access indicating the current context has resumed after a previous sub-context (AccountAccess).\n Resume,\n // The account's balance was read.\n Balance,\n // The account's codesize was read.\n Extcodesize,\n // The account's codehash was read.\n Extcodehash,\n // The account's code was copied.\n Extcodecopy\n }\n\n /// Forge execution contexts.\n enum ForgeContext {\n // Test group execution context (test, coverage or snapshot).\n TestGroup,\n // `forge test` execution context.\n Test,\n // `forge coverage` execution context.\n Coverage,\n // `forge snapshot` execution context.\n Snapshot,\n // Script group execution context (dry run, broadcast or resume).\n ScriptGroup,\n // `forge script` execution context.\n ScriptDryRun,\n // `forge script --broadcast` execution context.\n ScriptBroadcast,\n // `forge script --resume` execution context.\n ScriptResume,\n // Unknown `forge` execution context.\n Unknown\n }\n\n /// The transaction type (`txType`) of the broadcast.\n enum BroadcastTxType {\n // Represents a CALL broadcast tx.\n Call,\n // Represents a CREATE broadcast tx.\n Create,\n // Represents a CREATE2 broadcast tx.\n Create2\n }\n\n /// An Ethereum log. Returned by `getRecordedLogs`.\n struct Log {\n // The topics of the log, including the signature, if any.\n bytes32[] topics;\n // The raw data of the log.\n bytes data;\n // The address of the log's emitter.\n address emitter;\n }\n\n /// An RPC URL and its alias. Returned by `rpcUrlStructs`.\n struct Rpc {\n // The alias of the RPC URL.\n string key;\n // The RPC URL.\n string url;\n }\n\n /// An RPC log object. Returned by `eth_getLogs`.\n struct EthGetLogs {\n // The address of the log's emitter.\n address emitter;\n // The topics of the log, including the signature, if any.\n bytes32[] topics;\n // The raw data of the log.\n bytes data;\n // The block hash.\n bytes32 blockHash;\n // The block number.\n uint64 blockNumber;\n // The transaction hash.\n bytes32 transactionHash;\n // The transaction index in the block.\n uint64 transactionIndex;\n // The log index.\n uint256 logIndex;\n // Whether the log was removed.\n bool removed;\n }\n\n /// A single entry in a directory listing. Returned by `readDir`.\n struct DirEntry {\n // The error message, if any.\n string errorMessage;\n // The path of the entry.\n string path;\n // The depth of the entry.\n uint64 depth;\n // Whether the entry is a directory.\n bool isDir;\n // Whether the entry is a symlink.\n bool isSymlink;\n }\n\n /// Metadata information about a file.\n /// This structure is returned from the `fsMetadata` function and represents known\n /// metadata about a file such as its permissions, size, modification\n /// times, etc.\n struct FsMetadata {\n // True if this metadata is for a directory.\n bool isDir;\n // True if this metadata is forLine truncated
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/console.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nlibrary console {\n address constant CONSOLE_ADDRESS =\n 0x000000000000000000636F6e736F6c652e6c6f67;\n\n function _sendLogPayloadImplementation(bytes memory payload) internal view {\n address consoleAddress = CONSOLE_ADDRESS;\n /// @solidity memory-safe-assembly\n assembly {\n pop(\n staticcall(\n gas(),\n consoleAddress,\n add(payload, 32),\n mload(payload),\n 0,\n 0\n )\n )\n }\n }\n\n function _castToPure(\n function(bytes memory) internal view fnIn\n ) internal pure returns (function(bytes memory) pure fnOut) {\n assembly {\n fnOut := fnIn\n }\n }\n\n function _sendLogPayload(bytes memory payload) internal pure {\n _castToPure(_sendLogPayloadImplementation)(payload);\n }\n\n function log() internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log()\"));\n }\n\n function logInt(int256 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(int256)\", p0));\n }\n\n function logUint(uint256 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(uint256)\", p0));\n }\n\n function logString(string memory p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(string)\", p0));\n }\n\n function logBool(bool p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bool)\", p0));\n }\n\n function logAddress(address p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(address)\", p0));\n }\n\n function logBytes(bytes memory p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes)\", p0));\n }\n\n function logBytes1(bytes1 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes1)\", p0));\n }\n\n function logBytes2(bytes2 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes2)\", p0));\n }\n\n function logBytes3(bytes3 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes3)\", p0));\n }\n\n function logBytes4(bytes4 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes4)\", p0));\n }\n\n function logBytes5(bytes5 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes5)\", p0));\n }\n\n function logBytes6(bytes6 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes6)\", p0));\n }\n\n function logBytes7(bytes7 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes7)\", p0));\n }\n\n function logBytes8(bytes8 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes8)\", p0));\n }\n\n function logBytes9(bytes9 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes9)\", p0));\n }\n\n function logBytes10(bytes10 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes10)\", p0));\n }\n\n function logBytes11(bytes11 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes11)\", p0));\n }\n\n function logBytes12(bytes12 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes12)\", p0));\n }\n\n function logBytes13(bytes13 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes13)\", p0));\n }\n\n function logBytes14(bytes14 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes14)\", p0));\n }\n\n function logBytes15(bytes15 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes15)\", p0));\n }\n\n function logBytes16(bytes16 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes16)\", p0));\n }\n\n function logBytes17(bytes17 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes17)\", p0));\n }\n\n function logBytes18(bytes18 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes18)\", p0));\n }\n\n function logBytes19(bytes19 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes19)\", p0));\n }\n\n function logBytes20(bytes20 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes20)\", p0));\n }\n\n function logBytes21(bytes21 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes21)\", p0));\n }\n\n function logBytes22(bytes22 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes22)\", p0));\n }\n\n function logBytes23(bytes23 p0) internal pure {\n _sendLogPayload(abi.encodeWithSignature(\"log(bytes23)\Line truncated
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/console2.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.4.22 <0.9.0;\n\nimport {console as console2} from \"./console.sol\";\n"
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/interfaces/IERC165.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2;\n\ninterface IERC165 {\n /// @notice Query if a contract implements an interface\n /// @param interfaceID The interface identifier, as specified in ERC-165\n /// @dev Interface identification is specified in ERC-165. This function\n /// uses less than 30,000 gas.\n /// @return `true` if the contract implements `interfaceID` and\n /// `interfaceID` is not 0xffffffff, `false` otherwise\n function supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n"
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/interfaces/IERC20.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2;\n\n/// @dev Interface of the ERC20 standard as defined in the EIP.\n/// @dev This includes the optional name, symbol, and decimals metadata.\ninterface IERC20 {\n /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`).\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value`\n /// is the new allowance.\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /// @notice Returns the amount of tokens in existence.\n function totalSupply() external view returns (uint256);\n\n /// @notice Returns the amount of tokens owned by `account`.\n function balanceOf(address account) external view returns (uint256);\n\n /// @notice Moves `amount` tokens from the caller's account to `to`.\n function transfer(address to, uint256 amount) external returns (bool);\n\n /// @notice Returns the remaining number of tokens that `spender` is allowed\n /// to spend on behalf of `owner`\n function allowance(address owner, address spender) external view returns (uint256);\n\n /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens.\n /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n function approve(address spender, uint256 amount) external returns (bool);\n\n /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism.\n /// `amount` is then deducted from the caller's allowance.\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n\n /// @notice Returns the name of the token.\n function name() external view returns (string memory);\n\n /// @notice Returns the symbol of the token.\n function symbol() external view returns (string memory);\n\n /// @notice Returns the decimals places of the token.\n function decimals() external view returns (uint8);\n}\n"
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/interfaces/IERC721.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2;\n\nimport \"./IERC165.sol\";\n\n/// @title ERC-721 Non-Fungible Token Standard\n/// @dev See https://eips.ethereum.org/EIPS/eip-721\n/// Note: the ERC-165 identifier for this interface is 0x80ac58cd.\ninterface IERC721 is IERC165 {\n /// @dev This emits when ownership of any NFT changes by any mechanism.\n /// This event emits when NFTs are created (`from` == 0) and destroyed\n /// (`to` == 0). Exception: during contract creation, any number of NFTs\n /// may be created and assigned without emitting Transfer. At the time of\n /// any transfer, the approved address for that NFT (if any) is reset to none.\n event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);\n\n /// @dev This emits when the approved address for an NFT is changed or\n /// reaffirmed. The zero address indicates there is no approved address.\n /// When a Transfer event emits, this also indicates that the approved\n /// address for that NFT (if any) is reset to none.\n event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);\n\n /// @dev This emits when an operator is enabled or disabled for an owner.\n /// The operator can manage all NFTs of the owner.\n event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);\n\n /// @notice Count all NFTs assigned to an owner\n /// @dev NFTs assigned to the zero address are considered invalid, and this\n /// function throws for queries about the zero address.\n /// @param _owner An address for whom to query the balance\n /// @return The number of NFTs owned by `_owner`, possibly zero\n function balanceOf(address _owner) external view returns (uint256);\n\n /// @notice Find the owner of an NFT\n /// @dev NFTs assigned to zero address are considered invalid, and queries\n /// about them do throw.\n /// @param _tokenId The identifier for an NFT\n /// @return The address of the owner of the NFT\n function ownerOf(uint256 _tokenId) external view returns (address);\n\n /// @notice Transfers the ownership of an NFT from one address to another address\n /// @dev Throws unless `msg.sender` is the current owner, an authorized\n /// operator, or the approved address for this NFT. Throws if `_from` is\n /// not the current owner. Throws if `_to` is the zero address. Throws if\n /// `_tokenId` is not a valid NFT. When transfer is complete, this function\n /// checks if `_to` is a smart contract (code size > 0). If so, it calls\n /// `onERC721Received` on `_to` and throws if the return value is not\n /// `bytes4(keccak256(\"onERC721Received(address,address,uint256,bytes)\"))`.\n /// @param _from The current owner of the NFT\n /// @param _to The new owner\n /// @param _tokenId The NFT to transfer\n /// @param data Additional data with no specified format, sent in call to `_to`\n function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable;\n\n /// @notice Transfers the ownership of an NFT from one address to another address\n /// @dev This works identically to the other function with an extra data parameter,\n /// except this function just sets data to \"\".\n /// @param _from The current owner of the NFT\n /// @param _to The new owner\n /// @param _tokenId The NFT to transfer\n function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;\n\n /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE\n /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE\n /// THEY MAY BE PERMANENTLY LOST\n /// @dev Throws unless `msg.sender` is the current owner, an authorized\n /// operator, or the approved address for this NFT. Throws if `_from` is\n /// not the current owner. Throws if `_to` is the zero address. Throws if\n /// `_tokenId` is not a valid NFT.\n /// @param _from The current owner of the NFT\n /// @param _to The new owner\n /// @param _tokenId The NFT to transfer\n function transferFrom(address _from, address _to, uint256 _tokenId) external payable;\n\n /// @notice Change or reaffirm the approved address for an NFT\n /// @dev The zero address indicates there is no approved address.\n /// Throws unless `msg.sender` is the current NFT owner, or an authorized\n /// operator of the current owner.\n /// @param _approved The new approved NFT controller\n /// @param _tokenId The NFT to approve\n function approve(address _approved, uint256 _tokenId) external payable;\n\n /// @notice Enable or disable approval for a third party (\"operator\") to manage\n /// all of `msg.sender`'s assets\n /// @dev Emits the ApprovalForAll event. The contract MUST allow\n /// multiple operators per owner.\n /// @param _operator Address to add to the set of authorized operatoLine truncated
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/interfaces/IMulticall3.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\npragma experimental ABIEncoderV2;\n\ninterface IMulticall3 {\n struct Call {\n address target;\n bytes callData;\n }\n\n struct Call3 {\n address target;\n bool allowFailure;\n bytes callData;\n }\n\n struct Call3Value {\n address target;\n bool allowFailure;\n uint256 value;\n bytes callData;\n }\n\n struct Result {\n bool success;\n bytes returnData;\n }\n\n function aggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes[] memory returnData);\n\n function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData);\n\n function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData);\n\n function blockAndAggregate(Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n\n function getBasefee() external view returns (uint256 basefee);\n\n function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash);\n\n function getBlockNumber() external view returns (uint256 blockNumber);\n\n function getChainId() external view returns (uint256 chainid);\n\n function getCurrentBlockCoinbase() external view returns (address coinbase);\n\n function getCurrentBlockDifficulty() external view returns (uint256 difficulty);\n\n function getCurrentBlockGasLimit() external view returns (uint256 gaslimit);\n\n function getCurrentBlockTimestamp() external view returns (uint256 timestamp);\n\n function getEthBalance(address addr) external view returns (uint256 balance);\n\n function getLastBlockHash() external view returns (bytes32 blockHash);\n\n function tryAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (Result[] memory returnData);\n\n function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls)\n external\n payable\n returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData);\n}\n"
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/mocks/MockERC20.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {IERC20} from \"../interfaces/IERC20.sol\";\n\n/// @notice This is a mock contract of the ERC20 standard for testing purposes only, it SHOULD NOT be used in production.\n/// @dev Forked from: https://github.com/transmissions11/solmate/blob/0384dbaaa4fcb5715738a9254a7c0a4cb62cf458/src/tokens/ERC20.sol\ncontract MockERC20 is IERC20 {\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE\n //////////////////////////////////////////////////////////////*/\n\n string internal _name;\n\n string internal _symbol;\n\n uint8 internal _decimals;\n\n function name() external view override returns (string memory) {\n return _name;\n }\n\n function symbol() external view override returns (string memory) {\n return _symbol;\n }\n\n function decimals() external view override returns (uint8) {\n return _decimals;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal _totalSupply;\n\n mapping(address => uint256) internal _balanceOf;\n\n mapping(address => mapping(address => uint256)) internal _allowance;\n\n function totalSupply() external view override returns (uint256) {\n return _totalSupply;\n }\n\n function balanceOf(address owner) external view override returns (uint256) {\n return _balanceOf[owner];\n }\n\n function allowance(address owner, address spender) external view override returns (uint256) {\n return _allowance[owner][spender];\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 STORAGE\n //////////////////////////////////////////////////////////////*/\n\n uint256 internal INITIAL_CHAIN_ID;\n\n bytes32 internal INITIAL_DOMAIN_SEPARATOR;\n\n mapping(address => uint256) public nonces;\n\n /*//////////////////////////////////////////////////////////////\n INITIALIZE\n //////////////////////////////////////////////////////////////*/\n\n /// @dev A bool to track whether the contract has been initialized.\n bool private initialized;\n\n /// @dev To hide constructor warnings across solc versions due to different constructor visibility requirements and\n /// syntaxes, we add an initialization function that can be called only once.\n function initialize(string memory name_, string memory symbol_, uint8 decimals_) public {\n require(!initialized, \"ALREADY_INITIALIZED\");\n\n _name = name_;\n _symbol = symbol_;\n _decimals = decimals_;\n\n INITIAL_CHAIN_ID = _pureChainId();\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\n\n initialized = true;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC20 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _allowance[msg.sender][spender] = amount;\n\n emit Approval(msg.sender, spender, amount);\n\n return true;\n }\n\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n _balanceOf[msg.sender] = _sub(_balanceOf[msg.sender], amount);\n _balanceOf[to] = _add(_balanceOf[to], amount);\n\n emit Transfer(msg.sender, to, amount);\n\n return true;\n }\n\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n uint256 allowed = _allowance[from][msg.sender]; // Saves gas for limited approvals.\n\n if (allowed != ~uint256(0)) _allowance[from][msg.sender] = _sub(allowed, amount);\n\n _balanceOf[from] = _sub(_balanceOf[from], amount);\n _balanceOf[to] = _add(_balanceOf[to], amount);\n\n emit Transfer(from, to, amount);\n\n return true;\n }\n\n /*//////////////////////////////////////////////////////////////\n EIP-2612 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s)\n public\n virtual\n {\n require(deadline >= block.timestamp, \"PERMIT_DEADLINE_EXPIRED\");\n\n address recoveredAddress = ecrecover(\n keccak256(\n abi.encodePacked(\n \"\\x19\\x01\",\n DOMAIN_SEPARATOR(),\n keccak256(\n abi.encode(\n keccak256(\n \"Permit(address owner,address spender,uint256 value,uint256Line truncated
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/mocks/MockERC721.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\nimport {IERC721Metadata, IERC721TokenReceiver} from \"../interfaces/IERC721.sol\";\n\n/// @notice This is a mock contract of the ERC721 standard for testing purposes only, it SHOULD NOT be used in production.\n/// @dev Forked from: https://github.com/transmissions11/solmate/blob/0384dbaaa4fcb5715738a9254a7c0a4cb62cf458/src/tokens/ERC721.sol\ncontract MockERC721 is IERC721Metadata {\n /*//////////////////////////////////////////////////////////////\n METADATA STORAGE/LOGIC\n //////////////////////////////////////////////////////////////*/\n\n string internal _name;\n\n string internal _symbol;\n\n function name() external view override returns (string memory) {\n return _name;\n }\n\n function symbol() external view override returns (string memory) {\n return _symbol;\n }\n\n function tokenURI(uint256 id) public view virtual override returns (string memory) {}\n\n /*//////////////////////////////////////////////////////////////\n ERC721 BALANCE/OWNER STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _ownerOf;\n\n mapping(address => uint256) internal _balanceOf;\n\n function ownerOf(uint256 id) public view virtual override returns (address owner) {\n require((owner = _ownerOf[id]) != address(0), \"NOT_MINTED\");\n }\n\n function balanceOf(address owner) public view virtual override returns (uint256) {\n require(owner != address(0), \"ZERO_ADDRESS\");\n\n return _balanceOf[owner];\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 APPROVAL STORAGE\n //////////////////////////////////////////////////////////////*/\n\n mapping(uint256 => address) internal _getApproved;\n\n mapping(address => mapping(address => bool)) internal _isApprovedForAll;\n\n function getApproved(uint256 id) public view virtual override returns (address) {\n return _getApproved[id];\n }\n\n function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {\n return _isApprovedForAll[owner][operator];\n }\n\n /*//////////////////////////////////////////////////////////////\n INITIALIZE\n //////////////////////////////////////////////////////////////*/\n\n /// @dev A bool to track whether the contract has been initialized.\n bool private initialized;\n\n /// @dev To hide constructor warnings across solc versions due to different constructor visibility requirements and\n /// syntaxes, we add an initialization function that can be called only once.\n function initialize(string memory name_, string memory symbol_) public {\n require(!initialized, \"ALREADY_INITIALIZED\");\n\n _name = name_;\n _symbol = symbol_;\n\n initialized = true;\n }\n\n /*//////////////////////////////////////////////////////////////\n ERC721 LOGIC\n //////////////////////////////////////////////////////////////*/\n\n function approve(address spender, uint256 id) public payable virtual override {\n address owner = _ownerOf[id];\n\n require(msg.sender == owner || _isApprovedForAll[owner][msg.sender], \"NOT_AUTHORIZED\");\n\n _getApproved[id] = spender;\n\n emit Approval(owner, spender, id);\n }\n\n function setApprovalForAll(address operator, bool approved) public virtual override {\n _isApprovedForAll[msg.sender][operator] = approved;\n\n emit ApprovalForAll(msg.sender, operator, approved);\n }\n\n function transferFrom(address from, address to, uint256 id) public payable virtual override {\n require(from == _ownerOf[id], \"WRONG_FROM\");\n\n require(to != address(0), \"INVALID_RECIPIENT\");\n\n require(\n msg.sender == from || _isApprovedForAll[from][msg.sender] || msg.sender == _getApproved[id],\n \"NOT_AUTHORIZED\"\n );\n\n // Underflow of the sender's balance is impossible because we check for\n // ownership above and the recipient's balance can't realistically overflow.\n _balanceOf[from]--;\n\n _balanceOf[to]++;\n\n _ownerOf[id] = to;\n\n delete _getApproved[id];\n\n emit Transfer(from, to, id);\n }\n\n function safeTransferFrom(address from, address to, uint256 id) public payable virtual override {\n transferFrom(from, to, id);\n\n require(\n !_isContract(to)\n || IERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, \"\")\n == IERC721TokenReceiver.onERC721Received.selector,\n \"UNSAFE_RECIPIENT\"\n );\n }\n\n function safeTransferFrom(address from, address to, uint256 id, bytes memory data)\nLine truncated
|
||||||
|
},
|
||||||
|
"lib/forge-std/src/safeconsole.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: MIT\npragma solidity >=0.6.2 <0.9.0;\n\n/// @author philogy <https://github.com/philogy>\n/// @dev Code generated automatically by script.\nlibrary safeconsole {\n uint256 constant CONSOLE_ADDR = 0x000000000000000000000000000000000000000000636F6e736F6c652e6c6f67;\n\n // Credit to [0age](https://twitter.com/z0age/status/1654922202930888704) and [0xdapper](https://github.com/foundry-rs/forge-std/pull/374)\n // for the view-to-pure log trick.\n function _sendLogPayload(uint256 offset, uint256 size) private pure {\n function(uint256, uint256) internal view fnIn = _sendLogPayloadView;\n function(uint256, uint256) internal pure pureSendLogPayload;\n /// @solidity memory-safe-assembly\n assembly {\n pureSendLogPayload := fnIn\n }\n pureSendLogPayload(offset, size);\n }\n\n function _sendLogPayloadView(uint256 offset, uint256 size) private view {\n /// @solidity memory-safe-assembly\n assembly {\n pop(staticcall(gas(), CONSOLE_ADDR, offset, size, 0x0, 0x0))\n }\n }\n\n function _memcopy(uint256 fromOffset, uint256 toOffset, uint256 length) private pure {\n function(uint256, uint256, uint256) internal view fnIn = _memcopyView;\n function(uint256, uint256, uint256) internal pure pureMemcopy;\n /// @solidity memory-safe-assembly\n assembly {\n pureMemcopy := fnIn\n }\n pureMemcopy(fromOffset, toOffset, length);\n }\n\n function _memcopyView(uint256 fromOffset, uint256 toOffset, uint256 length) private view {\n /// @solidity memory-safe-assembly\n assembly {\n pop(staticcall(gas(), 0x4, fromOffset, length, toOffset, length))\n }\n }\n\n function logMemory(uint256 offset, uint256 length) internal pure {\n if (offset >= 0x60) {\n // Sufficient memory before slice to prepare call header.\n bytes32 m0;\n bytes32 m1;\n bytes32 m2;\n /// @solidity memory-safe-assembly\n assembly {\n m0 := mload(sub(offset, 0x60))\n m1 := mload(sub(offset, 0x40))\n m2 := mload(sub(offset, 0x20))\n // Selector of `log(bytes)`.\n mstore(sub(offset, 0x60), 0x0be77f56)\n mstore(sub(offset, 0x40), 0x20)\n mstore(sub(offset, 0x20), length)\n }\n _sendLogPayload(offset - 0x44, length + 0x44);\n /// @solidity memory-safe-assembly\n assembly {\n mstore(sub(offset, 0x60), m0)\n mstore(sub(offset, 0x40), m1)\n mstore(sub(offset, 0x20), m2)\n }\n } else {\n // Insufficient space, so copy slice forward, add header and reverse.\n bytes32 m0;\n bytes32 m1;\n bytes32 m2;\n uint256 endOffset = offset + length;\n /// @solidity memory-safe-assembly\n assembly {\n m0 := mload(add(endOffset, 0x00))\n m1 := mload(add(endOffset, 0x20))\n m2 := mload(add(endOffset, 0x40))\n }\n _memcopy(offset, offset + 0x60, length);\n /// @solidity memory-safe-assembly\n assembly {\n // Selector of `log(bytes)`.\n mstore(add(offset, 0x00), 0x0be77f56)\n mstore(add(offset, 0x20), 0x20)\n mstore(add(offset, 0x40), length)\n }\n _sendLogPayload(offset + 0x1c, length + 0x44);\n _memcopy(offset + 0x60, offset, length);\n /// @solidity memory-safe-assembly\n assembly {\n mstore(add(endOffset, 0x00), m0)\n mstore(add(endOffset, 0x20), m1)\n mstore(add(endOffset, 0x40), m2)\n }\n }\n }\n\n function log(address p0) internal pure {\n bytes32 m0;\n bytes32 m1;\n /// @solidity memory-safe-assembly\n assembly {\n m0 := mload(0x00)\n m1 := mload(0x20)\n // Selector of `log(address)`.\n mstore(0x00, 0x2c2ecbc2)\n mstore(0x20, p0)\n }\n _sendLogPayload(0x1c, 0x24);\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, m0)\n mstore(0x20, m1)\n }\n }\n\n function log(bool p0) internal pure {\n bytes32 m0;\n bytes32 m1;\n /// @solidity memory-safe-assembly\n assembly {\n m0 := mload(0x00)\n m1 := mload(0x20)\n // Selector of `log(bool)`.\n mstore(0x00, 0x32458eed)\n mstore(0x20, p0)\n }\n _sendLogPayload(0x1c, 0x24);\n /// @solidity memory-safe-assembly\n assembly {\n mstore(0x00, m0)\n mstore(0x20, m1)\n }\n }\n\n function log(uinLine truncated
|
||||||
|
},
|
||||||
|
"script/Counter.s.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport {Script, console} from \"forge-std/Script.sol\";\nimport {Counter} from \"../src/Counter.sol\";\n\ncontract CounterScript is Script {\n Counter public counter;\n\n function setUp() public {}\n\n function run() public {\n vm.startBroadcast();\n\n counter = new Counter();\n\n vm.stopBroadcast();\n }\n}\n"
|
||||||
|
},
|
||||||
|
"src/Counter.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\ncontract Counter {\n uint256 public number;\n\n function setNumber(uint256 newNumber) public {\n number = newNumber;\n }\n\n function increment() public {\n number++;\n }\n}\n"
|
||||||
|
},
|
||||||
|
"test/Counter.t.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: UNLICENSED\npragma solidity ^0.8.13;\n\nimport {Test, console} from \"forge-std/Test.sol\";\nimport {Counter} from \"../src/Counter.sol\";\n\ncontract CounterTest is Test {\n Counter public counter;\n\n function setUp() public {\n counter = new Counter();\n counter.setNumber(0);\n }\n\n function test_Increment() public {\n counter.increment();\n assertEq(counter.number(), 1);\n }\n\n function testFuzz_SetNumber(uint256 x) public {\n counter.setNumber(x);\n assertEq(counter.number(), x);\n }\n}\n"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"optimizer": {
|
||||||
|
"enabled": false,
|
||||||
|
"runs": 200
|
||||||
|
},
|
||||||
|
"outputSelection": {
|
||||||
|
"*": {
|
||||||
|
"": ["ast"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"evmVersion": "berlin",
|
||||||
|
"remappings": ["forge-std/=lib/forge-std/src/"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,33 @@
|
|||||||
import * as path from 'path';
|
import * as path from "path";
|
||||||
|
|
||||||
const outputDir = 'artifacts';
|
const outputDir = "artifacts";
|
||||||
const binExtension = ':C.pvm';
|
const binExtension = ":C.pvm";
|
||||||
const asmExtension = ':C.pvmasm';
|
const asmExtension = ":C.pvmasm";
|
||||||
const llvmExtension = '.ll';
|
const llvmExtension = ".ll";
|
||||||
const contractSolFilename = 'contract.sol';
|
const contractSolFilename = "contract.sol";
|
||||||
const contractYulFilename = 'contract.yul';
|
const contractYulFilename = "contract.yul";
|
||||||
const contractOptimizedLLVMFilename = contractSolFilename + '.C.optimized';
|
const contractOptimizedLLVMFilename = contractSolFilename + ".C.optimized";
|
||||||
const contractUnoptimizedLLVMFilename = contractSolFilename + '.C.unoptimized';
|
const contractUnoptimizedLLVMFilename = contractSolFilename + ".C.unoptimized";
|
||||||
const pathToOutputDir = path.join(__dirname, '..', outputDir);
|
const pathToOutputDir = path.join(__dirname, "..", outputDir);
|
||||||
const pathToContracts = path.join(__dirname, '..', 'src', 'contracts');
|
const pathToContracts = path.join(__dirname, "..", "src", "contracts");
|
||||||
const pathToBasicYulContract = path.join(pathToContracts, 'yul', contractYulFilename);
|
const pathToBasicYulContract = path.join(
|
||||||
const pathToBasicSolContract = path.join(pathToContracts, 'solidity', contractSolFilename);
|
pathToContracts,
|
||||||
const pathToSolBinOutputFile = path.join(pathToOutputDir, contractSolFilename + binExtension);
|
"yul",
|
||||||
const pathToSolAsmOutputFile = path.join(pathToOutputDir, contractSolFilename + asmExtension);
|
contractYulFilename,
|
||||||
|
);
|
||||||
|
const pathToBasicSolContract = path.join(
|
||||||
|
pathToContracts,
|
||||||
|
"solidity",
|
||||||
|
contractSolFilename,
|
||||||
|
);
|
||||||
|
const pathToSolBinOutputFile = path.join(
|
||||||
|
pathToOutputDir,
|
||||||
|
contractSolFilename + binExtension,
|
||||||
|
);
|
||||||
|
const pathToSolAsmOutputFile = path.join(
|
||||||
|
pathToOutputDir,
|
||||||
|
contractSolFilename + asmExtension,
|
||||||
|
);
|
||||||
|
|
||||||
export const paths = {
|
export const paths = {
|
||||||
outputDir: outputDir,
|
outputDir: outputDir,
|
||||||
|
|||||||
@@ -1,44 +1,51 @@
|
|||||||
import * as shell from 'shelljs';
|
import * as shell from "shelljs";
|
||||||
import * as fs from 'fs';
|
import * as fs from "fs";
|
||||||
import { spawnSync } from 'child_process';
|
import { spawnSync } from "child_process";
|
||||||
|
|
||||||
interface CommandResult {
|
interface CommandResult {
|
||||||
output: string;
|
output: string;
|
||||||
exitCode: number;
|
exitCode: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const executeCommand = (command: string, stdin?: string): CommandResult => {
|
export const executeCommand = (
|
||||||
if (stdin) {
|
command: string,
|
||||||
const process = spawnSync(command, [], {
|
stdin?: string,
|
||||||
input: stdin,
|
): CommandResult => {
|
||||||
shell: true,
|
if (stdin) {
|
||||||
encoding: 'utf8',
|
const process = spawnSync(command, [], {
|
||||||
maxBuffer: 30 * 1024 * 1024
|
input: stdin,
|
||||||
});
|
shell: true,
|
||||||
|
encoding: "utf8",
|
||||||
|
maxBuffer: 30 * 1024 * 1024,
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
|
||||||
exitCode: process.status || 0,
|
|
||||||
output: (process.stdout || process.stderr || '').toString()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = shell.exec(command, { silent: true, async: false });
|
|
||||||
return {
|
return {
|
||||||
exitCode: result.code,
|
exitCode: process.status || 0,
|
||||||
output: result.stdout || result.stderr || ''
|
output: (process.stdout || process.stderr || "").toString(),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = shell.exec(command, { silent: true, async: false });
|
||||||
|
return {
|
||||||
|
exitCode: result.code,
|
||||||
|
output: result.stdout || result.stderr || "",
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isFolderExist = (folder: string): boolean => {
|
export const isFolderExist = (folder: string): boolean => {
|
||||||
return shell.test('-d', folder);
|
return shell.test("-d", folder);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isFileExist = (pathToFileDir: string, fileName: string, fileExtension: string): boolean => {
|
export const isFileExist = (
|
||||||
return shell.ls(pathToFileDir).stdout.includes(fileName + fileExtension);
|
pathToFileDir: string,
|
||||||
|
fileName: string,
|
||||||
|
fileExtension: string,
|
||||||
|
): boolean => {
|
||||||
|
return shell.ls(pathToFileDir).stdout.includes(fileName + fileExtension);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isFileEmpty = (file: string): boolean => {
|
export const isFileEmpty = (file: string): boolean => {
|
||||||
if (fs.existsSync(file)) {
|
if (fs.existsSync(file)) {
|
||||||
return (fs.readFileSync(file).length === 0);
|
return fs.readFileSync(file).length === 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
import {executeCommand} from "../src/helper";
|
import { executeCommand } from "../src/helper";
|
||||||
import { paths } from '../src/entities';
|
import { paths } from "../src/entities";
|
||||||
|
|
||||||
|
|
||||||
//id1746
|
//id1746
|
||||||
describe("Run with --asm by default", () => {
|
describe("Run with --asm by default", () => {
|
||||||
const command = `resolc ${paths.pathToBasicSolContract} --asm`;
|
const command = `resolc ${paths.pathToBasicSolContract} --asm`;
|
||||||
const result = executeCommand(command);
|
const result = executeCommand(command);
|
||||||
const commandInvalid = 'resolc --asm';
|
const commandInvalid = "resolc --asm";
|
||||||
const resultInvalid = executeCommand(commandInvalid);
|
const resultInvalid = executeCommand(commandInvalid);
|
||||||
|
|
||||||
it("Valid command exit code = 0", () => {
|
it("Valid command exit code = 0", () => {
|
||||||
@@ -28,7 +27,9 @@ describe("Run with --asm by default", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("run invalid: resolc --asm", () => {
|
it("run invalid: resolc --asm", () => {
|
||||||
expect(resultInvalid.output).toMatch(/(No input sources specified|Compilation aborted)/i);
|
expect(resultInvalid.output).toMatch(
|
||||||
|
/(No input sources specified|Compilation aborted)/i,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Invalid command exit code = 1", () => {
|
it("Invalid command exit code = 1", () => {
|
||||||
@@ -36,7 +37,7 @@ describe("Run with --asm by default", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Invalid solc exit code == Invalid resolc exit code", () => {
|
it("Invalid solc exit code == Invalid resolc exit code", () => {
|
||||||
const command = 'solc --asm';
|
const command = "solc --asm";
|
||||||
const solcResult = executeCommand(command);
|
const solcResult = executeCommand(command);
|
||||||
expect(solcResult.exitCode).toBe(resultInvalid.exitCode);
|
expect(solcResult.exitCode).toBe(resultInvalid.exitCode);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,191 +1,241 @@
|
|||||||
import { executeCommand, isFolderExist, isFileExist, isFileEmpty } from "../src/helper";
|
import {
|
||||||
import { paths } from '../src/entities';
|
executeCommand,
|
||||||
import * as shell from 'shelljs';
|
isFolderExist,
|
||||||
import * as path from 'path';
|
isFileExist,
|
||||||
|
isFileEmpty,
|
||||||
|
} from "../src/helper";
|
||||||
|
import { paths } from "../src/entities";
|
||||||
|
import * as shell from "shelljs";
|
||||||
|
import * as path from "path";
|
||||||
|
|
||||||
//id1762
|
//id1762
|
||||||
describe("Run resolc without any options", () => {
|
describe("Run resolc without any options", () => {
|
||||||
const command = 'resolc';
|
const command = "resolc";
|
||||||
const result = executeCommand(command);
|
const result = executeCommand(command);
|
||||||
|
|
||||||
it("Info with help is presented", () => {
|
it("Info with help is presented", () => {
|
||||||
expect(result.output).toMatch(/(Usage: resolc)/i);
|
expect(result.output).toMatch(/(Usage: resolc)/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Exit code = 1", () => {
|
it("Exit code = 1", () => {
|
||||||
expect(result.exitCode).toBe(1);
|
expect(result.exitCode).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("solc exit code == resolc exit code", () => {
|
it("solc exit code == resolc exit code", () => {
|
||||||
const command = 'solc';
|
const command = "solc";
|
||||||
const solcResult = executeCommand(command);
|
const solcResult = executeCommand(command);
|
||||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//#1713
|
//#1713
|
||||||
describe("Default run a command from the help", () => {
|
describe("Default run a command from the help", () => {
|
||||||
|
const command = `resolc ${paths.pathToBasicSolContract} --overwrite -O3 --bin --output-dir "${paths.pathToOutputDir}"`; // potential issue on resolc with full path on Windows cmd
|
||||||
|
const result = executeCommand(command);
|
||||||
|
|
||||||
const command = `resolc ${paths.pathToBasicSolContract} --overwrite -O3 --bin --output-dir "${paths.pathToOutputDir}"`; // potential issue on resolc with full path on Windows cmd
|
it("Compiler run successful", () => {
|
||||||
const result = executeCommand(command);
|
expect(result.output).toMatch(/(Compiler run successful.)/i);
|
||||||
|
});
|
||||||
it("Compiler run successful", () => {
|
it("Exit code = 0", () => {
|
||||||
expect(result.output).toMatch(/(Compiler run successful.)/i);
|
expect(result.exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
it("Exit code = 0", () => {
|
it("Output dir is created", () => {
|
||||||
expect(result.exitCode).toBe(0);
|
expect(isFolderExist(paths.pathToOutputDir)).toBe(true);
|
||||||
});
|
});
|
||||||
it("Output dir is created", () => {
|
xit("Output file is created", () => {
|
||||||
expect(isFolderExist(paths.pathToOutputDir)).toBe(true);
|
// a bug on windows
|
||||||
});
|
expect(
|
||||||
xit("Output file is created", () => { // a bug on windows
|
isFileExist(
|
||||||
expect(isFileExist(paths.pathToOutputDir, paths.contractSolFilename, paths.binExtension)).toBe(true);
|
paths.pathToOutputDir,
|
||||||
});
|
paths.contractSolFilename,
|
||||||
it("the output file is not empty", () => {
|
paths.binExtension,
|
||||||
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false);
|
),
|
||||||
});
|
).toBe(true);
|
||||||
it("No 'Error'/'Warning'/'Fail' in the output", () => {
|
});
|
||||||
expect(result.output).not.toMatch(/([Ee]rror|[Ww]arning|[Ff]ail)/i);
|
it("the output file is not empty", () => {
|
||||||
});
|
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false);
|
||||||
|
});
|
||||||
|
it("No 'Error'/'Warning'/'Fail' in the output", () => {
|
||||||
|
expect(result.output).not.toMatch(/([Ee]rror|[Ww]arning|[Ff]ail)/i);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//#1818
|
//#1818
|
||||||
describe("Default run a command from the help", () => {
|
describe("Default run a command from the help", () => {
|
||||||
|
const command = `resolc ${paths.pathToBasicSolContract} --overwrite -O3 --bin --asm --output-dir "${paths.pathToOutputDir}"`; // potential issue on resolc with full path on Windows cmd
|
||||||
|
const result = executeCommand(command);
|
||||||
|
|
||||||
const command = `resolc ${paths.pathToBasicSolContract} --overwrite -O3 --bin --asm --output-dir "${paths.pathToOutputDir}"`; // potential issue on resolc with full path on Windows cmd
|
it("Compiler run successful", () => {
|
||||||
const result = executeCommand(command);
|
expect(result.output).toMatch(/(Compiler run successful.)/i);
|
||||||
|
});
|
||||||
it("Compiler run successful", () => {
|
it("Exit code = 0", () => {
|
||||||
expect(result.output).toMatch(/(Compiler run successful.)/i);
|
expect(result.exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
it("Exit code = 0", () => {
|
it("Output dir is created", () => {
|
||||||
expect(result.exitCode).toBe(0);
|
expect(isFolderExist(paths.pathToOutputDir)).toBe(true);
|
||||||
});
|
});
|
||||||
it("Output dir is created", () => {
|
xit("Output files are created", () => {
|
||||||
expect(isFolderExist(paths.pathToOutputDir)).toBe(true);
|
// a bug on windows
|
||||||
});
|
expect(
|
||||||
xit("Output files are created", () => { // a bug on windows
|
isFileExist(
|
||||||
expect(isFileExist(paths.pathToOutputDir, paths.contractSolFilename, paths.binExtension)).toBe(true);
|
paths.pathToOutputDir,
|
||||||
expect(isFileExist(paths.pathToOutputDir, paths.contractSolFilename, paths.asmExtension)).toBe(true);
|
paths.contractSolFilename,
|
||||||
});
|
paths.binExtension,
|
||||||
it("the output files are not empty", () => {
|
),
|
||||||
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false);
|
).toBe(true);
|
||||||
expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false);
|
expect(
|
||||||
});
|
isFileExist(
|
||||||
it("No 'Error'/'Warning'/'Fail' in the output", () => {
|
paths.pathToOutputDir,
|
||||||
expect(result.output).not.toMatch(/([Ee]rror|[Ww]arning|[Ff]ail)/i);
|
paths.contractSolFilename,
|
||||||
});
|
paths.asmExtension,
|
||||||
|
),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
it("the output files are not empty", () => {
|
||||||
|
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false);
|
||||||
|
expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false);
|
||||||
|
});
|
||||||
|
it("No 'Error'/'Warning'/'Fail' in the output", () => {
|
||||||
|
expect(result.output).not.toMatch(/([Ee]rror|[Ww]arning|[Ff]ail)/i);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Run resolc with source debug information", () => {
|
describe("Run resolc with source debug information", () => {
|
||||||
const commands = [
|
const commands = [
|
||||||
`resolc -g ${paths.pathToBasicSolContract} --overwrite --bin --asm --output-dir "${paths.pathToOutputDir}"`,
|
`resolc -g ${paths.pathToBasicSolContract} --overwrite --bin --asm --output-dir "${paths.pathToOutputDir}"`,
|
||||||
`resolc --disable-solc-optimizer -g ${paths.pathToBasicSolContract} --overwrite --bin --asm --output-dir "${paths.pathToOutputDir}"`
|
`resolc --disable-solc-optimizer -g ${paths.pathToBasicSolContract} --overwrite --bin --asm --output-dir "${paths.pathToOutputDir}"`,
|
||||||
]; // potential issue on resolc with full path on Windows cmd`;
|
]; // potential issue on resolc with full path on Windows cmd`;
|
||||||
|
|
||||||
for (var idx in commands) {
|
for (var idx in commands) {
|
||||||
const command = commands[idx];
|
const command = commands[idx];
|
||||||
const result = executeCommand(command);
|
const result = executeCommand(command);
|
||||||
|
|
||||||
it("Compiler run successful", () => {
|
it("Compiler run successful", () => {
|
||||||
expect(result.output).toMatch(/(Compiler run successful.)/i);
|
expect(result.output).toMatch(/(Compiler run successful.)/i);
|
||||||
});
|
});
|
||||||
it("Exit code = 0", () => {
|
it("Exit code = 0", () => {
|
||||||
expect(result.exitCode).toBe(0);
|
expect(result.exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
it("Output dir is created", () => {
|
it("Output dir is created", () => {
|
||||||
expect(isFolderExist(paths.pathToOutputDir)).toBe(true);
|
expect(isFolderExist(paths.pathToOutputDir)).toBe(true);
|
||||||
});
|
});
|
||||||
it("Output files are created", () => { // a bug on windows
|
it("Output files are created", () => {
|
||||||
expect(isFileExist(paths.pathToOutputDir, paths.contractSolFilename, paths.binExtension)).toBe(true);
|
// a bug on windows
|
||||||
expect(isFileExist(paths.pathToOutputDir, paths.contractSolFilename, paths.asmExtension)).toBe(true);
|
expect(
|
||||||
});
|
isFileExist(
|
||||||
it("the output files are not empty", () => {
|
paths.pathToOutputDir,
|
||||||
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false);
|
paths.contractSolFilename,
|
||||||
expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false);
|
paths.binExtension,
|
||||||
});
|
),
|
||||||
it("No 'Error'/'Fail' in the output", () => {
|
).toBe(true);
|
||||||
expect(result.output).not.toMatch(/([Ee]rror|[Ff]ail)/i);
|
expect(
|
||||||
});
|
isFileExist(
|
||||||
}
|
paths.pathToOutputDir,
|
||||||
|
paths.contractSolFilename,
|
||||||
|
paths.asmExtension,
|
||||||
|
),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
it("the output files are not empty", () => {
|
||||||
|
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false);
|
||||||
|
expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false);
|
||||||
|
});
|
||||||
|
it("No 'Error'/'Fail' in the output", () => {
|
||||||
|
expect(result.output).not.toMatch(/([Ee]rror|[Ff]ail)/i);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Run resolc with source debug information, check LLVM debug-info", () => {
|
describe("Run resolc with source debug information, check LLVM debug-info", () => {
|
||||||
const commands = [
|
const commands = [
|
||||||
`resolc -g ${paths.pathToBasicSolContract} --overwrite --debug-output-dir="${paths.pathToOutputDir}"`,
|
`resolc -g ${paths.pathToBasicSolContract} --overwrite --debug-output-dir="${paths.pathToOutputDir}"`,
|
||||||
`resolc -g --disable-solc-optimizer ${paths.pathToBasicSolContract} --overwrite --debug-output-dir="${paths.pathToOutputDir}"`
|
`resolc -g --disable-solc-optimizer ${paths.pathToBasicSolContract} --overwrite --debug-output-dir="${paths.pathToOutputDir}"`,
|
||||||
]; // potential issue on resolc with full path on Windows cmd`;
|
]; // potential issue on resolc with full path on Windows cmd`;
|
||||||
|
|
||||||
for (var idx in commands) {
|
for (var idx in commands) {
|
||||||
const command = commands[idx];
|
const command = commands[idx];
|
||||||
const result = executeCommand(command);
|
const result = executeCommand(command);
|
||||||
|
|
||||||
it("Compiler run successful", () => {
|
it("Compiler run successful", () => {
|
||||||
expect(result.output).toMatch(/(Compiler run successful.)/i);
|
expect(result.output).toMatch(/(Compiler run successful.)/i);
|
||||||
});
|
});
|
||||||
it("Exit code = 0", () => {
|
it("Exit code = 0", () => {
|
||||||
expect(result.exitCode).toBe(0);
|
expect(result.exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
it("Output dir is created", () => {
|
it("Output dir is created", () => {
|
||||||
expect(isFolderExist(paths.pathToOutputDir)).toBe(true);
|
expect(isFolderExist(paths.pathToOutputDir)).toBe(true);
|
||||||
});
|
});
|
||||||
it("Output files are created", () => { // a bug on windows
|
it("Output files are created", () => {
|
||||||
expect(isFileExist(paths.pathToOutputDir, paths.contractOptimizedLLVMFilename, paths.llvmExtension)).toBe(true);
|
// a bug on windows
|
||||||
expect(isFileExist(paths.pathToOutputDir, paths.contractUnoptimizedLLVMFilename, paths.llvmExtension)).toBe(true);
|
expect(
|
||||||
});
|
isFileExist(
|
||||||
it("the output files are not empty", () => {
|
paths.pathToOutputDir,
|
||||||
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false);
|
paths.contractOptimizedLLVMFilename,
|
||||||
expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false);
|
paths.llvmExtension,
|
||||||
});
|
),
|
||||||
it("No 'Error'/'Fail' in the output", () => {
|
).toBe(true);
|
||||||
expect(result.output).not.toMatch(/([Ee]rror|[Ff]ail)/i);
|
expect(
|
||||||
});
|
isFileExist(
|
||||||
}
|
paths.pathToOutputDir,
|
||||||
|
paths.contractUnoptimizedLLVMFilename,
|
||||||
|
paths.llvmExtension,
|
||||||
|
),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
it("the output files are not empty", () => {
|
||||||
|
expect(isFileEmpty(paths.pathToSolBinOutputFile)).toBe(false);
|
||||||
|
expect(isFileEmpty(paths.pathToSolAsmOutputFile)).toBe(false);
|
||||||
|
});
|
||||||
|
it("No 'Error'/'Fail' in the output", () => {
|
||||||
|
expect(result.output).not.toMatch(/([Ee]rror|[Ff]ail)/i);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
describe("Standard JSON compilation with path options", () => {
|
describe("Standard JSON compilation with path options", () => {
|
||||||
const contractsDir = path.join(shell.tempdir(), 'contracts-test');
|
const contractsDir = path.join(shell.tempdir(), "contracts-test");
|
||||||
const inputFile = path.join(__dirname, '..', 'src/contracts/compiled/1.json');
|
const inputFile = path.join(__dirname, "..", "src/contracts/compiled/1.json");
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
shell.mkdir("-p", contractsDir);
|
||||||
|
|
||||||
|
const input = JSON.parse(shell.cat(inputFile).toString());
|
||||||
|
|
||||||
|
Object.entries(input.sources).forEach(
|
||||||
|
([sourcePath, source]: [string, any]) => {
|
||||||
|
const filePath = path.join(contractsDir, sourcePath);
|
||||||
|
shell.mkdir("-p", path.dirname(filePath));
|
||||||
|
shell.ShellString(source.content).to(filePath);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
shell.rm("-rf", contractsDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Output with all path options", () => {
|
||||||
|
let result: { exitCode: number; output: string };
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
shell.mkdir('-p', contractsDir);
|
const tempInputFile = path.join(contractsDir, "temp-input.json");
|
||||||
|
shell.cp(inputFile, tempInputFile);
|
||||||
|
const inputContent = shell.cat(inputFile).toString();
|
||||||
|
|
||||||
const input = JSON.parse(shell.cat(inputFile).toString());
|
const command = `resolc --standard-json --base-path "${contractsDir}" --include-path "${contractsDir}" --allow-paths "${contractsDir}"`;
|
||||||
|
|
||||||
Object.entries(input.sources).forEach(([sourcePath, source]: [string, any]) => {
|
result = executeCommand(command, inputContent);
|
||||||
const filePath = path.join(contractsDir, sourcePath);
|
|
||||||
shell.mkdir('-p', path.dirname(filePath));
|
shell.rm(tempInputFile);
|
||||||
shell.ShellString(source.content).to(filePath);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
it("Compiler run successful without emiting warnings", () => {
|
||||||
shell.rm('-rf', contractsDir);
|
const parsedResults = JSON.parse(result.output);
|
||||||
});
|
expect(
|
||||||
|
parsedResults.errors.filter(
|
||||||
describe("Output with all path options", () => {
|
(error: { type: string }) => error.type != "Warning",
|
||||||
let result: { exitCode: number; output: string };
|
),
|
||||||
|
).toEqual([]);
|
||||||
beforeAll(() => {
|
|
||||||
const tempInputFile = path.join(contractsDir, 'temp-input.json');
|
|
||||||
shell.cp(inputFile, tempInputFile);
|
|
||||||
const inputContent = shell.cat(inputFile).toString();
|
|
||||||
|
|
||||||
const command = `resolc --standard-json --base-path "${contractsDir}" --include-path "${contractsDir}" --allow-paths "${contractsDir}"`;
|
|
||||||
|
|
||||||
result = executeCommand(command, inputContent);
|
|
||||||
|
|
||||||
shell.rm(tempInputFile);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Compiler run successful without emiting warnings", () => {
|
|
||||||
const parsedResults = JSON.parse(result.output)
|
|
||||||
expect(parsedResults.errors.filter((error: { type: string; }) => error.type != 'Warning')).toEqual([]);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
import {executeCommand} from "../src/helper";
|
import { executeCommand } from "../src/helper";
|
||||||
import { paths } from '../src/entities';
|
import { paths } from "../src/entities";
|
||||||
|
|
||||||
|
|
||||||
//id1743
|
//id1743
|
||||||
describe("Run with --yul by default", () => {
|
describe("Run with --yul by default", () => {
|
||||||
const command = `resolc ${paths.pathToBasicYulContract} --yul`;
|
const command = `resolc ${paths.pathToBasicYulContract} --yul`;
|
||||||
const result = executeCommand(command);
|
const result = executeCommand(command);
|
||||||
const commandInvalid = 'resolc --yul';
|
const commandInvalid = "resolc --yul";
|
||||||
const resultInvalid = executeCommand(commandInvalid);
|
const resultInvalid = executeCommand(commandInvalid);
|
||||||
|
|
||||||
it("Valid command exit code = 0", () => {
|
it("Valid command exit code = 0", () => {
|
||||||
@@ -18,11 +17,11 @@ describe("Run with --yul by default", () => {
|
|||||||
expect(result.output).toMatch(/(No output requested)/i);
|
expect(result.output).toMatch(/(No output requested)/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
xit("solc exit code == resolc exit code", () => {
|
||||||
xit("solc exit code == resolc exit code", () => { // unknown solc issue for datatype of the contract
|
// unknown solc issue for datatype of the contract
|
||||||
const command = `solc ${paths.pathToBasicSolContract} --yul`;
|
const command = `solc ${paths.pathToBasicSolContract} --yul`;
|
||||||
const solcResult = executeCommand(command);
|
const solcResult = executeCommand(command);
|
||||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("run invalid: resolc --yul", () => {
|
it("run invalid: resolc --yul", () => {
|
||||||
@@ -33,7 +32,7 @@ describe("Run with --yul by default", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Invalid solc exit code == Invalid resolc exit code", () => {
|
it("Invalid solc exit code == Invalid resolc exit code", () => {
|
||||||
const command = 'solc --yul';
|
const command = "solc --yul";
|
||||||
const solcResult = executeCommand(command);
|
const solcResult = executeCommand(command);
|
||||||
expect(solcResult.exitCode).toBe(resultInvalid.exitCode);
|
expect(solcResult.exitCode).toBe(resultInvalid.exitCode);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES6",
|
"target": "ES6",
|
||||||
"module": "CommonJS",
|
"module": "CommonJS",
|
||||||
"outDir": "./dist",
|
"outDir": "./dist"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,153 +1,192 @@
|
|||||||
import { executeCommand } from "../src/helper";
|
import { executeCommand } from "../src/helper";
|
||||||
import { paths } from '../src/entities';
|
import { paths } from "../src/entities";
|
||||||
|
|
||||||
|
|
||||||
describe("Set of --combined-json tests", () => {
|
describe("Set of --combined-json tests", () => {
|
||||||
const zksolcCommand = 'zksolc';
|
const zksolcCommand = "zksolc";
|
||||||
const solcCommand = 'solc';
|
const solcCommand = "solc";
|
||||||
const json_args: string[] = [`abi`, `hashes`, `metadata`, `devdoc`, `userdoc`, `storage-layout`, `ast`, `asm`, `bin`, `bin-runtime`];
|
const json_args: string[] = [
|
||||||
|
`abi`,
|
||||||
|
`hashes`,
|
||||||
|
`metadata`,
|
||||||
|
`devdoc`,
|
||||||
|
`userdoc`,
|
||||||
|
`storage-layout`,
|
||||||
|
`ast`,
|
||||||
|
`asm`,
|
||||||
|
`bin`,
|
||||||
|
`bin-runtime`,
|
||||||
|
];
|
||||||
|
|
||||||
//id1742:I
|
//id1742:I
|
||||||
describe(`Run ${zksolcCommand} with just --combined-json`, () => {
|
describe(`Run ${zksolcCommand} with just --combined-json`, () => {
|
||||||
const args = [`--combined-json`];
|
const args = [`--combined-json`];
|
||||||
const result = executeCommand(zksolcCommand, args);
|
const result = executeCommand(zksolcCommand, args);
|
||||||
|
|
||||||
it("Valid command exit code = 1", () => {
|
it("Valid command exit code = 1", () => {
|
||||||
expect(result.exitCode).toBe(1);
|
expect(result.exitCode).toBe(1);
|
||||||
});
|
|
||||||
|
|
||||||
it("--combined-json error is presented", () => {
|
|
||||||
expect(result.output).toMatch(/(requires a value but none was supplied)/i);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("solc exit code == zksolc exit code", () => {
|
|
||||||
const solcResult = executeCommand(solcCommand, args);
|
|
||||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//id1742:II
|
it("--combined-json error is presented", () => {
|
||||||
describe(`Run ${zksolcCommand} with Sol contract and --combined-json`, () => {
|
expect(result.output).toMatch(
|
||||||
const args = [`${paths.pathToBasicSolContract}`, `--combined-json`];
|
/(requires a value but none was supplied)/i,
|
||||||
const result = executeCommand(zksolcCommand, args);
|
);
|
||||||
|
|
||||||
it("Valid command exit code = 1", () => {
|
|
||||||
expect(result.exitCode).toBe(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("--combined-json error is presented", () => {
|
|
||||||
expect(result.output).toMatch(/(requires a value but none was supplied)/i);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("solc exit code == zksolc exit code", () => {
|
|
||||||
const solcResult = executeCommand(solcCommand, args);
|
|
||||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
//id1742:III
|
it("solc exit code == zksolc exit code", () => {
|
||||||
for (let i = 0; i < json_args.length; i++) {
|
const solcResult = executeCommand(solcCommand, args);
|
||||||
describe(`Run ${zksolcCommand} with Sol, --combined-json and ARG: ${json_args[i]}`, () => {
|
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||||
const args = [`${paths.pathToBasicSolContract}`, `--combined-json`, `${json_args[i]}`];
|
});
|
||||||
const result = executeCommand(zksolcCommand, args);
|
});
|
||||||
|
|
||||||
it("Valid command exit code = 0", () => {
|
//id1742:II
|
||||||
expect(result.exitCode).toBe(0);
|
describe(`Run ${zksolcCommand} with Sol contract and --combined-json`, () => {
|
||||||
});
|
const args = [`${paths.pathToBasicSolContract}`, `--combined-json`];
|
||||||
|
const result = executeCommand(zksolcCommand, args);
|
||||||
|
|
||||||
it("--combined-json error is presented", () => {
|
it("Valid command exit code = 1", () => {
|
||||||
expect(result.output).toMatch(/(contracts)/i);
|
expect(result.exitCode).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("solc exit code == zksolc exit code", () => {
|
it("--combined-json error is presented", () => {
|
||||||
const solcResult = executeCommand(solcCommand, args);
|
expect(result.output).toMatch(
|
||||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
/(requires a value but none was supplied)/i,
|
||||||
});
|
);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
//id1829:I
|
it("solc exit code == zksolc exit code", () => {
|
||||||
for (let i = 0; i < json_args.length; i++) {
|
const solcResult = executeCommand(solcCommand, args);
|
||||||
describe(`Run ${zksolcCommand} with Sol, --combined-json and wrong ARG: --${json_args[i]}`, () => {
|
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||||
const args = [`${paths.pathToBasicSolContract}`, `--combined-json`, `--${json_args[i]}`];
|
});
|
||||||
const result = executeCommand(zksolcCommand, args);
|
});
|
||||||
|
|
||||||
it("Valid command exit code = 1", () => {
|
//id1742:III
|
||||||
expect(result.exitCode).toBe(1);
|
for (let i = 0; i < json_args.length; i++) {
|
||||||
});
|
describe(`Run ${zksolcCommand} with Sol, --combined-json and ARG: ${json_args[i]}`, () => {
|
||||||
|
const args = [
|
||||||
|
`${paths.pathToBasicSolContract}`,
|
||||||
|
`--combined-json`,
|
||||||
|
`${json_args[i]}`,
|
||||||
|
];
|
||||||
|
const result = executeCommand(zksolcCommand, args);
|
||||||
|
|
||||||
it("--combined-json error is presented", () => {
|
it("Valid command exit code = 0", () => {
|
||||||
expect(result.output).toMatch(/(Invalid option|error)/i);
|
expect(result.exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("solc exit code == zksolc exit code", () => {
|
it("--combined-json error is presented", () => {
|
||||||
const solcResult = executeCommand(solcCommand, args);
|
expect(result.output).toMatch(/(contracts)/i);
|
||||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//id1829:II
|
it("solc exit code == zksolc exit code", () => {
|
||||||
for (let i = 0; i < json_args.length; i++) {
|
const solcResult = executeCommand(solcCommand, args);
|
||||||
describe(`Run ${zksolcCommand} with Sol, --combined-json and multiple ARG: ${json_args[i]} ${json_args[i]}`, () => {
|
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||||
const args = [`${paths.pathToBasicSolContract}`, `--combined-json`, `${json_args[i]}`, `${json_args[i]}`];
|
});
|
||||||
const result = executeCommand(zksolcCommand, args);
|
});
|
||||||
|
}
|
||||||
|
|
||||||
xit("Valid command exit code = 1", () => {
|
//id1829:I
|
||||||
expect(result.exitCode).toBe(1);
|
for (let i = 0; i < json_args.length; i++) {
|
||||||
});
|
describe(`Run ${zksolcCommand} with Sol, --combined-json and wrong ARG: --${json_args[i]}`, () => {
|
||||||
|
const args = [
|
||||||
|
`${paths.pathToBasicSolContract}`,
|
||||||
|
`--combined-json`,
|
||||||
|
`--${json_args[i]}`,
|
||||||
|
];
|
||||||
|
const result = executeCommand(zksolcCommand, args);
|
||||||
|
|
||||||
it("--combined-json error is presented", () => {
|
it("Valid command exit code = 1", () => {
|
||||||
expect(result.output).toMatch(/(No such file or directory|cannot find the file specified)/i); // Hopefully we should have more precise message here!
|
expect(result.exitCode).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
xit("solc exit code == zksolc exit code", () => {
|
it("--combined-json error is presented", () => {
|
||||||
const solcResult = executeCommand(solcCommand, args);
|
expect(result.output).toMatch(/(Invalid option|error)/i);
|
||||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//id1829:III
|
it("solc exit code == zksolc exit code", () => {
|
||||||
for (let i = 0; i < json_args.length; i++) {
|
const solcResult = executeCommand(solcCommand, args);
|
||||||
describe(`Run ${zksolcCommand} with Sol, and multiple (--combined-json ${json_args[i]})`, () => {
|
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||||
const args = [`${paths.pathToBasicSolContract}`, `--combined-json`, `${json_args[i]}`, `--combined-json`, `${json_args[i]}`];
|
});
|
||||||
const result = executeCommand(zksolcCommand, args);
|
});
|
||||||
|
}
|
||||||
|
|
||||||
it("Valid command exit code = 1", () => {
|
//id1829:II
|
||||||
expect(result.exitCode).toBe(1);
|
for (let i = 0; i < json_args.length; i++) {
|
||||||
});
|
describe(`Run ${zksolcCommand} with Sol, --combined-json and multiple ARG: ${json_args[i]} ${json_args[i]}`, () => {
|
||||||
|
const args = [
|
||||||
|
`${paths.pathToBasicSolContract}`,
|
||||||
|
`--combined-json`,
|
||||||
|
`${json_args[i]}`,
|
||||||
|
`${json_args[i]}`,
|
||||||
|
];
|
||||||
|
const result = executeCommand(zksolcCommand, args);
|
||||||
|
|
||||||
it("--combined-json error is presented", () => {
|
xit("Valid command exit code = 1", () => {
|
||||||
expect(result.output).toMatch(/(cannot be used multiple times)/i);
|
expect(result.exitCode).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("solc exit code == zksolc exit code", () => {
|
it("--combined-json error is presented", () => {
|
||||||
const solcResult = executeCommand(solcCommand, args);
|
expect(result.output).toMatch(
|
||||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
/(No such file or directory|cannot find the file specified)/i,
|
||||||
});
|
); // Hopefully we should have more precise message here!
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
//id1830
|
xit("solc exit code == zksolc exit code", () => {
|
||||||
for (let i = 0; i < json_args.length; i++) {
|
const solcResult = executeCommand(solcCommand, args);
|
||||||
describe(`Run ${zksolcCommand} with Yul, and --combined-json ${json_args[i]}`, () => {
|
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||||
const args = [`${paths.pathToBasicYulContract}`, `--combined-json`, `${json_args[i]}`];
|
});
|
||||||
const result = executeCommand(zksolcCommand, args);
|
});
|
||||||
|
}
|
||||||
|
|
||||||
it("Valid command exit code = 1", () => {
|
//id1829:III
|
||||||
expect(result.exitCode).toBe(1);
|
for (let i = 0; i < json_args.length; i++) {
|
||||||
});
|
describe(`Run ${zksolcCommand} with Sol, and multiple (--combined-json ${json_args[i]})`, () => {
|
||||||
|
const args = [
|
||||||
|
`${paths.pathToBasicSolContract}`,
|
||||||
|
`--combined-json`,
|
||||||
|
`${json_args[i]}`,
|
||||||
|
`--combined-json`,
|
||||||
|
`${json_args[i]}`,
|
||||||
|
];
|
||||||
|
const result = executeCommand(zksolcCommand, args);
|
||||||
|
|
||||||
it("--combined-json error is presented", () => {
|
it("Valid command exit code = 1", () => {
|
||||||
expect(result.output).toMatch(/(ParserError: Expected identifier)/i);
|
expect(result.exitCode).toBe(1);
|
||||||
});
|
});
|
||||||
asd
|
|
||||||
|
|
||||||
it("solc exit code == zksolc exit code", () => {
|
it("--combined-json error is presented", () => {
|
||||||
const solcResult = executeCommand(solcCommand, args);
|
expect(result.output).toMatch(/(cannot be used multiple times)/i);
|
||||||
expect(solcResult.exitCode).toBe(result.exitCode);
|
});
|
||||||
});
|
|
||||||
});
|
it("solc exit code == zksolc exit code", () => {
|
||||||
}
|
const solcResult = executeCommand(solcCommand, args);
|
||||||
|
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//id1830
|
||||||
|
for (let i = 0; i < json_args.length; i++) {
|
||||||
|
describe(`Run ${zksolcCommand} with Yul, and --combined-json ${json_args[i]}`, () => {
|
||||||
|
const args = [
|
||||||
|
`${paths.pathToBasicYulContract}`,
|
||||||
|
`--combined-json`,
|
||||||
|
`${json_args[i]}`,
|
||||||
|
];
|
||||||
|
const result = executeCommand(zksolcCommand, args);
|
||||||
|
|
||||||
|
it("Valid command exit code = 1", () => {
|
||||||
|
expect(result.exitCode).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("--combined-json error is presented", () => {
|
||||||
|
expect(result.output).toMatch(/(ParserError: Expected identifier)/i);
|
||||||
|
});
|
||||||
|
asd;
|
||||||
|
|
||||||
|
it("solc exit code == zksolc exit code", () => {
|
||||||
|
const solcResult = executeCommand(solcCommand, args);
|
||||||
|
expect(solcResult.exitCode).toBe(result.exitCode);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../target/wasm32-unknown-emscripten/release/resolc.js
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../target/wasm32-unknown-emscripten/release/resolc.wasm
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"language": "Solidity",
|
|
||||||
"sources": {
|
|
||||||
"fixtures/instantiate.sol": {
|
|
||||||
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.8.2 <0.9.0;\ncontract ChildContract {\n constructor() {\n }\n}\ncontract MainContract {\n constructor() {\n ChildContract newContract = new ChildContract();\n }\n}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"optimizer": {
|
|
||||||
"enabled": true,
|
|
||||||
"runs": 200
|
|
||||||
},
|
|
||||||
"outputSelection": {
|
|
||||||
"*": {
|
|
||||||
"*": ["abi"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 4,
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# @parity/revive
|
||||||
|
|
||||||
|
Node.js module to compile Solidity contracts to Polkavm bytecode, using [Revive](https://github.com/paritytech/revive)
|
||||||
|
|
||||||
|
# Usage from Node.js
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const sources = {
|
||||||
|
["contracts/1_Storage.sol"]: {
|
||||||
|
content: readFileSync("fixtures/storage.sol", "utf8"),
|
||||||
|
}
|
||||||
|
|
||||||
|
const out = await compile(sources);
|
||||||
|
```
|
||||||
|
|
||||||
|
# Usage from shell
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @parity/revive@latest --bin contracts/1_Storage.sol
|
||||||
|
```
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import globals from 'globals'
|
||||||
|
import pluginJs from '@eslint/js'
|
||||||
|
import tseslint from 'typescript-eslint'
|
||||||
|
|
||||||
|
/** @type {import('eslint').Linter.Config[]} */
|
||||||
|
export default [
|
||||||
|
{ files: ['**/*.{mjs,ts}'] },
|
||||||
|
{ languageOptions: { globals: globals.browser } },
|
||||||
|
pluginJs.configs.recommended,
|
||||||
|
...tseslint.configs.recommended,
|
||||||
|
]
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
pragma solidity ^9999;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title Storage
|
||||||
|
* @dev Store & retrieve value in a variable
|
||||||
|
* @custom:dev-run-script ./scripts/deploy_with_ethers.ts
|
||||||
|
*/
|
||||||
|
contract BadPragma {
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
pragma solidity >=0.8.2 <0.9.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @title Storage
|
||||||
|
* @dev Store & retrieve value in a variable
|
||||||
|
* @custom:dev-run-script ./scripts/deploy_with_ethers.ts
|
||||||
|
*/
|
||||||
|
contract Storage {
|
||||||
|
|
||||||
|
uint256 number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Store value in variable
|
||||||
|
* @param num value to store
|
||||||
|
*/
|
||||||
|
function store(uint256 num) public {
|
||||||
|
number = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Return value
|
||||||
|
* @return value of 'number'
|
||||||
|
*/
|
||||||
|
function retrieve() public view returns (uint256){
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// missing license and pragama
|
||||||
|
/**
|
||||||
|
* @title Storage
|
||||||
|
* @dev Store & retrieve value in a variable
|
||||||
|
* @custom:dev-run-script ./scripts/deploy_with_ethers.ts
|
||||||
|
*/
|
||||||
|
contract Storage {
|
||||||
|
|
||||||
|
uint256 number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Store value in variable
|
||||||
|
* @param num value to store
|
||||||
|
*/
|
||||||
|
function store(uint256 num) public {
|
||||||
|
number = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Return value
|
||||||
|
* @return value of 'number'
|
||||||
|
*/
|
||||||
|
function retrieve() public view returns (uint256){
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
// Compatible with OpenZeppelin Contracts ^5.0.0
|
||||||
|
pragma solidity ^0.8.22;
|
||||||
|
|
||||||
|
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||||
|
import "@openzeppelin/contracts/access/Ownable.sol";
|
||||||
|
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Permit.sol";
|
||||||
|
|
||||||
|
contract MyToken is ERC20, Ownable, ERC20Permit {
|
||||||
|
constructor(address initialOwner)
|
||||||
|
ERC20("MyToken", "MTK")
|
||||||
|
Ownable(initialOwner)
|
||||||
|
ERC20Permit("MyToken")
|
||||||
|
{
|
||||||
|
_mint(msg.sender, 100 * 10 ** decimals());
|
||||||
|
}
|
||||||
|
|
||||||
|
function mint(address to, uint256 amount) public onlyOwner {
|
||||||
|
_mint(to, amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
"name": "@parity/resolc",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"version": "0.0.0-updated-via-gh-releases",
|
||||||
|
"author": "Parity <admin@parity.io> (https://parity.io)",
|
||||||
|
"module": "index.ts",
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"main": "./dist/index.js",
|
||||||
|
"bin": {
|
||||||
|
"resolc": "./dist/bin.js"
|
||||||
|
},
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"import": "./dist/index.js",
|
||||||
|
"require": "./dist/index.js",
|
||||||
|
"types": "./dist/index.d.ts"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc && cp src/resolc/** dist/resolc",
|
||||||
|
"test": "npm run build && node ./dist/index.test.js"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.14.0",
|
||||||
|
"@openzeppelin/contracts": "5.1.0",
|
||||||
|
"eslint": "^9.14.0",
|
||||||
|
"globals": "^15.12.0",
|
||||||
|
"tar": "^7.4.3",
|
||||||
|
"typescript": "^5.6.3",
|
||||||
|
"typescript-eslint": "^8.13.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "^22.9.0",
|
||||||
|
"commander": "^13.1.0",
|
||||||
|
"package-json": "^10.0.1",
|
||||||
|
"solc": "^0.8.29"
|
||||||
|
},
|
||||||
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||||
|
}
|
||||||
Executable
+203
@@ -0,0 +1,203 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import * as commander from 'commander'
|
||||||
|
import * as fs from 'fs'
|
||||||
|
import * as os from 'os'
|
||||||
|
import * as path from 'path'
|
||||||
|
import * as resolc from '.'
|
||||||
|
import { SolcInput } from '.'
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
// hold on to any exception handlers that existed prior to this script running, we'll be adding them back at the end
|
||||||
|
const originalUncaughtExceptionListeners =
|
||||||
|
process.listeners('uncaughtException')
|
||||||
|
// FIXME: remove annoying exception catcher of Emscripten
|
||||||
|
// see https://github.com/chriseth/browser-solidity/issues/167
|
||||||
|
process.removeAllListeners('uncaughtException')
|
||||||
|
|
||||||
|
const program = new commander.Command()
|
||||||
|
|
||||||
|
program.name('solcjs')
|
||||||
|
program.version(resolc.version())
|
||||||
|
program
|
||||||
|
.option('--bin', 'Binary of the contracts in hex.')
|
||||||
|
.option('--abi', 'ABI of the contracts.')
|
||||||
|
.option(
|
||||||
|
'--base-path <path>',
|
||||||
|
'Root of the project source tree. ' +
|
||||||
|
'The import callback will attempt to interpret all import paths as relative to this directory.'
|
||||||
|
)
|
||||||
|
.option(
|
||||||
|
'--include-path <path...>',
|
||||||
|
'Extra source directories available to the import callback. ' +
|
||||||
|
'When using a package manager to install libraries, use this option to specify directories where packages are installed. ' +
|
||||||
|
'Can be used multiple times to provide multiple locations.'
|
||||||
|
)
|
||||||
|
.option(
|
||||||
|
'-o, --output-dir <output-directory>',
|
||||||
|
'Output directory for the contracts.'
|
||||||
|
)
|
||||||
|
.option('-p, --pretty-json', 'Pretty-print all JSON output.', false)
|
||||||
|
.option('-v, --verbose', 'More detailed console output.', false)
|
||||||
|
.argument('<files...>')
|
||||||
|
|
||||||
|
program.parse(process.argv)
|
||||||
|
const options = program.opts<{
|
||||||
|
verbose: boolean
|
||||||
|
abi: boolean
|
||||||
|
bin: boolean
|
||||||
|
outputDir?: string
|
||||||
|
prettyJson: boolean
|
||||||
|
basePath?: string
|
||||||
|
includePath?: string[]
|
||||||
|
}>()
|
||||||
|
const files: string[] = program.args
|
||||||
|
const destination = options.outputDir ?? '.'
|
||||||
|
|
||||||
|
function abort(msg: string) {
|
||||||
|
console.error(msg || 'Error occurred')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
function withUnixPathSeparators(filePath: string) {
|
||||||
|
// On UNIX-like systems forward slashes in paths are just a part of the file name.
|
||||||
|
if (os.platform() !== 'win32') {
|
||||||
|
return filePath
|
||||||
|
}
|
||||||
|
|
||||||
|
return filePath.replace(/\\/g, '/')
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeSourcePathRelativeIfPossible(sourcePath: string) {
|
||||||
|
const absoluteBasePath = options.basePath
|
||||||
|
? path.resolve(options.basePath)
|
||||||
|
: path.resolve('.')
|
||||||
|
const absoluteIncludePaths = options.includePath
|
||||||
|
? options.includePath.map((prefix: string) => {
|
||||||
|
return path.resolve(prefix)
|
||||||
|
})
|
||||||
|
: []
|
||||||
|
|
||||||
|
// Compared to base path stripping logic in solc this is much simpler because path.resolve()
|
||||||
|
// handles symlinks correctly (does not resolve them except in work dir) and strips .. segments
|
||||||
|
// from paths going beyond root (e.g. `/../../a/b/c` -> `/a/b/c/`). It's simpler also because it
|
||||||
|
// ignores less important corner cases: drive letters are not stripped from absolute paths on
|
||||||
|
// Windows and UNC paths are not handled in a special way (at least on Linux). Finally, it has
|
||||||
|
// very little test coverage so there might be more differences that we are just not aware of.
|
||||||
|
const absoluteSourcePath = path.resolve(sourcePath)
|
||||||
|
|
||||||
|
for (const absolutePrefix of [absoluteBasePath].concat(
|
||||||
|
absoluteIncludePaths
|
||||||
|
)) {
|
||||||
|
const relativeSourcePath = path.relative(
|
||||||
|
absolutePrefix,
|
||||||
|
absoluteSourcePath
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!relativeSourcePath.startsWith('../')) {
|
||||||
|
return withUnixPathSeparators(relativeSourcePath)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// File is not located inside base path or include paths so use its absolute path.
|
||||||
|
return withUnixPathSeparators(absoluteSourcePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
function toFormattedJson<T>(input: T) {
|
||||||
|
return JSON.stringify(input, null, options.prettyJson ? 4 : 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (files.length === 0) {
|
||||||
|
console.error('Must provide a file')
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(options.bin || options.abi)) {
|
||||||
|
abort('Invalid option selected, must specify either --bin or --abi')
|
||||||
|
}
|
||||||
|
|
||||||
|
const sources: SolcInput = {}
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++) {
|
||||||
|
try {
|
||||||
|
sources[makeSourcePathRelativeIfPossible(files[i])] = {
|
||||||
|
content: fs.readFileSync(files[i]).toString(),
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
abort('Error reading ' + files[i] + ': ' + e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.verbose) {
|
||||||
|
console.log('>>> Compiling:\n' + toFormattedJson(sources) + '\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
const output = await resolc.compile(sources)
|
||||||
|
let hasError = false
|
||||||
|
|
||||||
|
if (!output) {
|
||||||
|
abort('No output from compiler')
|
||||||
|
} else if (output.errors) {
|
||||||
|
for (const error in output.errors) {
|
||||||
|
const message = output.errors[error]
|
||||||
|
if (message.severity === 'warning') {
|
||||||
|
console.log(message.formattedMessage)
|
||||||
|
} else {
|
||||||
|
console.error(message.formattedMessage)
|
||||||
|
hasError = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.mkdirSync(destination, { recursive: true })
|
||||||
|
|
||||||
|
function writeFile(file: string, content: Buffer | string) {
|
||||||
|
file = path.join(destination, file)
|
||||||
|
fs.writeFile(file, content, function (err) {
|
||||||
|
if (err) {
|
||||||
|
console.error('Failed to write ' + file + ': ' + err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const fileName in output.contracts) {
|
||||||
|
for (const contractName in output.contracts[fileName]) {
|
||||||
|
let contractFileName = fileName + ':' + contractName
|
||||||
|
contractFileName = contractFileName.replace(/[:./\\]/g, '_')
|
||||||
|
|
||||||
|
if (options.bin) {
|
||||||
|
writeFile(
|
||||||
|
contractFileName + '.polkavm',
|
||||||
|
Buffer.from(
|
||||||
|
output.contracts[fileName][contractName].evm.bytecode
|
||||||
|
.object,
|
||||||
|
'hex'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.abi) {
|
||||||
|
writeFile(
|
||||||
|
contractFileName + '.abi',
|
||||||
|
toFormattedJson(
|
||||||
|
output.contracts[fileName][contractName].abi
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put back original exception handlers.
|
||||||
|
originalUncaughtExceptionListeners.forEach(function (listener) {
|
||||||
|
process.addListener('uncaughtException', listener)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (hasError) {
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((err) => {
|
||||||
|
console.error('Error:', err)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
import { test } from 'node:test'
|
||||||
|
import { readFileSync } from 'node:fs'
|
||||||
|
import assert from 'node:assert'
|
||||||
|
import { compile, tryResolveImport } from '.'
|
||||||
|
import { resolve } from 'node:path'
|
||||||
|
import { execSync } from 'node:child_process'
|
||||||
|
|
||||||
|
function isResolcInPath() {
|
||||||
|
try {
|
||||||
|
execSync('resolc --version', { stdio: 'ignore' })
|
||||||
|
return true
|
||||||
|
} catch {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const compileOptions = [{}]
|
||||||
|
if (isResolcInPath()) {
|
||||||
|
compileOptions.push({ bin: 'resolc' })
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const options of compileOptions) {
|
||||||
|
test(`check Ok output with option ${JSON.stringify(options)}`, async () => {
|
||||||
|
const contract = 'fixtures/token.sol'
|
||||||
|
const sources = {
|
||||||
|
[contract]: {
|
||||||
|
content: readFileSync('fixtures/storage.sol', 'utf8'),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const out = await compile(sources, options)
|
||||||
|
assert(out.contracts[contract].Storage.abi != null)
|
||||||
|
assert(out.contracts[contract].Storage.evm.bytecode != null)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
test('check Err output', async () => {
|
||||||
|
const sources = {
|
||||||
|
bad: {
|
||||||
|
content: readFileSync('fixtures/storage_bad.sol', 'utf8'),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const out = await compile(sources)
|
||||||
|
assert(
|
||||||
|
out?.errors?.[0].message.includes(
|
||||||
|
'SPDX license identifier not provided in source file'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert(
|
||||||
|
out?.errors?.[1].message.includes(
|
||||||
|
'Source file does not specify required compiler version'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('check Err from stderr', async () => {
|
||||||
|
const sources = {
|
||||||
|
bad: {
|
||||||
|
content: readFileSync('fixtures/bad_pragma.sol', 'utf8'),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await compile(sources)
|
||||||
|
assert(false, 'Expected error')
|
||||||
|
} catch (error) {
|
||||||
|
assert(
|
||||||
|
String(error).includes(
|
||||||
|
'Source file requires different compiler version'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
test('resolve import', () => {
|
||||||
|
const cases = [
|
||||||
|
// local
|
||||||
|
{
|
||||||
|
file: './fixtures/storage.sol',
|
||||||
|
expected: resolve('fixtures/storage.sol'),
|
||||||
|
},
|
||||||
|
// scopped module with version
|
||||||
|
{
|
||||||
|
file: '@openzeppelin/contracts@5.1.0/token/ERC20/ERC20.sol',
|
||||||
|
expected: resolve(
|
||||||
|
'node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// scopped module without version
|
||||||
|
{
|
||||||
|
file: '@openzeppelin/contracts/token/ERC20/ERC20.sol',
|
||||||
|
expected: resolve(
|
||||||
|
'node_modules/@openzeppelin/contracts/token/ERC20/ERC20.sol'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// scopped module with wrong version
|
||||||
|
{
|
||||||
|
file: '@openzeppelin/contracts@4.8.3/token/ERC20/ERC20.sol',
|
||||||
|
expected: `Error: Version mismatch: Specified @openzeppelin/contracts@4.8.3, but installed version is 5.1.0`,
|
||||||
|
},
|
||||||
|
// module without version
|
||||||
|
{
|
||||||
|
file: 'acorn/package.json',
|
||||||
|
expected: resolve('node_modules/acorn/package.json'),
|
||||||
|
},
|
||||||
|
// scopped module with version
|
||||||
|
{
|
||||||
|
file: 'acorn@8.14.0/package.json',
|
||||||
|
expected: resolve('node_modules/acorn/package.json'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
file: 'acorn@8.14.1/package.json',
|
||||||
|
expected: `Error: Version mismatch: Specified acorn@8.14.1, but installed version is 8.14.0`,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const { file, expected } of cases) {
|
||||||
|
try {
|
||||||
|
const resolved = tryResolveImport(file)
|
||||||
|
assert(
|
||||||
|
resolved === expected,
|
||||||
|
`\nGot:\n${resolved}\nExpected:\n${expected}`
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
assert(
|
||||||
|
String(error) == expected,
|
||||||
|
`\nGot:\n${String(error)}\nExpected:\n${expected}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -0,0 +1,202 @@
|
|||||||
|
import solc from 'solc'
|
||||||
|
import { spawn } from 'child_process'
|
||||||
|
import { resolc, version as resolcVersion } from './resolc'
|
||||||
|
import path from 'path'
|
||||||
|
import { existsSync, readFileSync } from 'fs'
|
||||||
|
|
||||||
|
export type SolcInput = {
|
||||||
|
[contractName: string]: {
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SolcError = {
|
||||||
|
component: string
|
||||||
|
errorCode: string
|
||||||
|
formattedMessage: string
|
||||||
|
message: string
|
||||||
|
severity: string
|
||||||
|
sourceLocation?: {
|
||||||
|
file: string
|
||||||
|
start: number
|
||||||
|
end: number
|
||||||
|
}
|
||||||
|
type: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SolcOutput = {
|
||||||
|
contracts: {
|
||||||
|
[contractPath: string]: {
|
||||||
|
[contractName: string]: {
|
||||||
|
abi: Array<{
|
||||||
|
name: string
|
||||||
|
inputs: Array<{ name: string; type: string }>
|
||||||
|
outputs: Array<{ name: string; type: string }>
|
||||||
|
stateMutability: string
|
||||||
|
type: string
|
||||||
|
}>
|
||||||
|
evm: {
|
||||||
|
bytecode: { object: string }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errors?: Array<SolcError>
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resolveInputs(sources: SolcInput): SolcInput {
|
||||||
|
const input = {
|
||||||
|
language: 'Solidity',
|
||||||
|
sources,
|
||||||
|
settings: {
|
||||||
|
outputSelection: {
|
||||||
|
'*': {
|
||||||
|
'*': ['evm.bytecode.object'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const out = solc.compile(JSON.stringify(input), {
|
||||||
|
import: (path: string) => {
|
||||||
|
return {
|
||||||
|
contents: readFileSync(tryResolveImport(path), 'utf8'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const output = JSON.parse(out) as {
|
||||||
|
sources: { [fileName: string]: { id: number } }
|
||||||
|
errors: Array<SolcError>
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output.errors && Object.keys(output.sources).length === 0) {
|
||||||
|
throw new Error(output.errors[0].formattedMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.fromEntries(
|
||||||
|
Object.keys(output.sources).map((fileName) => {
|
||||||
|
return [
|
||||||
|
fileName,
|
||||||
|
sources[fileName] ?? {
|
||||||
|
content: readFileSync(tryResolveImport(fileName), 'utf8'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function version(): string {
|
||||||
|
const v = resolcVersion()
|
||||||
|
return v.split(' ').pop() ?? v
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function compile(
|
||||||
|
sources: SolcInput,
|
||||||
|
option: { bin?: string } = {}
|
||||||
|
): Promise<SolcOutput> {
|
||||||
|
const input = JSON.stringify({
|
||||||
|
language: 'Solidity',
|
||||||
|
sources: resolveInputs(sources),
|
||||||
|
settings: {
|
||||||
|
optimizer: { enabled: true, runs: 200 },
|
||||||
|
outputSelection: {
|
||||||
|
'*': {
|
||||||
|
'*': ['abi'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (option.bin) {
|
||||||
|
return compileWithBin(input, option.bin)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolc(input)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve an import path to a file path.
|
||||||
|
* @param importPath - The import path to resolve.
|
||||||
|
*/
|
||||||
|
export function tryResolveImport(importPath: string) {
|
||||||
|
// resolve local path
|
||||||
|
if (existsSync(importPath)) {
|
||||||
|
return path.resolve(importPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
const importRegex = /^(@?[^@/]+(?:\/[^@/]+)?)(?:@([^/]+))?(\/.+)$/
|
||||||
|
const match = importPath.match(importRegex)
|
||||||
|
|
||||||
|
if (!match) {
|
||||||
|
throw new Error('Invalid import path format.')
|
||||||
|
}
|
||||||
|
|
||||||
|
const basePackage = match[1] // "foo", "@scope/foo"
|
||||||
|
const specifiedVersion = match[2] // "1.2.3" (optional)
|
||||||
|
const relativePath = match[3] // "/path/to/file.sol"
|
||||||
|
|
||||||
|
let packageJsonPath
|
||||||
|
try {
|
||||||
|
packageJsonPath = require.resolve(
|
||||||
|
path.join(basePackage, 'package.json')
|
||||||
|
)
|
||||||
|
} catch {
|
||||||
|
throw new Error(`Could not resolve package ${basePackage}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a version was specified and compare with the installed version
|
||||||
|
if (specifiedVersion) {
|
||||||
|
const installedVersion = JSON.parse(
|
||||||
|
readFileSync(packageJsonPath, 'utf-8')
|
||||||
|
).version
|
||||||
|
|
||||||
|
if (installedVersion !== specifiedVersion) {
|
||||||
|
throw new Error(
|
||||||
|
`Version mismatch: Specified ${basePackage}@${specifiedVersion}, but installed version is ${installedVersion}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const packageRoot = path.dirname(packageJsonPath)
|
||||||
|
|
||||||
|
// Construct full path to the requested file
|
||||||
|
const resolvedPath = path.join(packageRoot, relativePath)
|
||||||
|
if (existsSync(resolvedPath)) {
|
||||||
|
return resolvedPath
|
||||||
|
} else {
|
||||||
|
throw new Error(`Resolved path ${resolvedPath} does not exist.`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function compileWithBin(input: string, bin: string): PromiseLike<SolcOutput> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const process = spawn(bin, ['--standard-json'])
|
||||||
|
|
||||||
|
let output = ''
|
||||||
|
let error = ''
|
||||||
|
|
||||||
|
process.stdin.write(input)
|
||||||
|
process.stdin.end()
|
||||||
|
|
||||||
|
process.stdout.on('data', (data) => {
|
||||||
|
output += data.toString()
|
||||||
|
})
|
||||||
|
|
||||||
|
process.stderr.on('data', (data) => {
|
||||||
|
error += data.toString()
|
||||||
|
})
|
||||||
|
|
||||||
|
process.on('close', (code) => {
|
||||||
|
if (code === 0) {
|
||||||
|
try {
|
||||||
|
const result: SolcOutput = JSON.parse(output)
|
||||||
|
resolve(result)
|
||||||
|
} catch {
|
||||||
|
reject(new Error(`Failed to parse output`))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reject(new Error(`Process exited with code ${code}: ${error}`))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import soljson from 'solc/soljson'
|
||||||
|
import Resolc from './resolc/resolc'
|
||||||
|
import type { SolcOutput } from '.'
|
||||||
|
|
||||||
|
export function resolc(input: string): SolcOutput {
|
||||||
|
const m = Resolc() as any // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
|
m.soljson = soljson
|
||||||
|
m.writeToStdin(input)
|
||||||
|
m.callMain(['--standard-json'])
|
||||||
|
const err = m.readFromStderr()
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
throw new Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return JSON.parse(m.readFromStdout()) as SolcOutput
|
||||||
|
}
|
||||||
|
|
||||||
|
export function version(): string {
|
||||||
|
const m = Resolc() as any // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
|
m.soljson = soljson
|
||||||
|
m.callMain(['--version'])
|
||||||
|
const err = m.readFromStderr()
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
throw new Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return m.readFromStdout()
|
||||||
|
}
|
||||||
Whitespace-only changes.
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../../../target/wasm32-unknown-emscripten/release/resolc.js
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../../../target/wasm32-unknown-emscripten/release/resolc.wasm
|
||||||
Vendored
+95
@@ -0,0 +1,95 @@
|
|||||||
|
declare module 'solc/soljson' {}
|
||||||
|
|
||||||
|
declare module 'solc' {
|
||||||
|
// Basic types for input/output handling
|
||||||
|
export interface CompileInput {
|
||||||
|
language: string
|
||||||
|
sources: {
|
||||||
|
[fileName: string]: {
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
settings?: {
|
||||||
|
optimizer?: {
|
||||||
|
enabled: boolean
|
||||||
|
runs: number
|
||||||
|
}
|
||||||
|
outputSelection: {
|
||||||
|
[fileName: string]: {
|
||||||
|
[contractName: string]: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompileOutput {
|
||||||
|
errors?: Array<{
|
||||||
|
component: string
|
||||||
|
errorCode: string
|
||||||
|
formattedMessage: string
|
||||||
|
message: string
|
||||||
|
severity: string
|
||||||
|
sourceLocation?: {
|
||||||
|
file: string
|
||||||
|
start: number
|
||||||
|
end: number
|
||||||
|
}
|
||||||
|
type: string
|
||||||
|
}>
|
||||||
|
sources?: {
|
||||||
|
[fileName: string]: {
|
||||||
|
id: number
|
||||||
|
ast: object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contracts?: {
|
||||||
|
[fileName: string]: {
|
||||||
|
[contractName: string]: {
|
||||||
|
abi: object[]
|
||||||
|
evm: {
|
||||||
|
bytecode: {
|
||||||
|
object: string
|
||||||
|
sourceMap: string
|
||||||
|
linkReferences: {
|
||||||
|
[fileName: string]: {
|
||||||
|
[libraryName: string]: Array<{
|
||||||
|
start: number
|
||||||
|
length: number
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deployedBytecode: {
|
||||||
|
object: string
|
||||||
|
sourceMap: string
|
||||||
|
linkReferences: {
|
||||||
|
[fileName: string]: {
|
||||||
|
[libraryName: string]: Array<{
|
||||||
|
start: number
|
||||||
|
length: number
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main exported functions
|
||||||
|
export function compile(
|
||||||
|
input: string | CompileInput,
|
||||||
|
options?: {
|
||||||
|
import: (path: string) =>
|
||||||
|
| {
|
||||||
|
contents: string
|
||||||
|
error?: undefined
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
error: string
|
||||||
|
contents?: undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
): string
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": ".",
|
||||||
|
"outDir": "dist",
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "ES2022",
|
||||||
|
"lib": ["ES2022"],
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"useUnknownInCatchVariables": true,
|
||||||
|
"types": ["node"],
|
||||||
|
"typeRoots": ["./node_modules/@types", "./src"],
|
||||||
|
"paths": {
|
||||||
|
"#src/*": ["./src/*"]
|
||||||
|
},
|
||||||
|
"plugins": []
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"]
|
||||||
|
}
|
||||||
+1213
File diff suppressed because it is too large.
Load diff
@@ -8,7 +8,7 @@ const RESOLC_WASM_URI =
|
|||||||
process.env.RELEASE_RESOLC_WASM_URI || "http://127.0.0.1:8080/resolc.wasm";
|
process.env.RELEASE_RESOLC_WASM_URI || "http://127.0.0.1:8080/resolc.wasm";
|
||||||
const RESOLC_WASM_TARGET_DIR = path.join(
|
const RESOLC_WASM_TARGET_DIR = path.join(
|
||||||
__dirname,
|
__dirname,
|
||||||
"../target/wasm32-unknown-emscripten/release",
|
"../../target/wasm32-unknown-emscripten/release",
|
||||||
);
|
);
|
||||||
const RESOLC_JS = path.join(RESOLC_WASM_TARGET_DIR, "resolc.js");
|
const RESOLC_JS = path.join(RESOLC_WASM_TARGET_DIR, "resolc.js");
|
||||||
const RESOLC_WEB_JS = path.join(RESOLC_WASM_TARGET_DIR, "resolc_web.js");
|
const RESOLC_WEB_JS = path.join(RESOLC_WASM_TARGET_DIR, "resolc_web.js");
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../../../target/wasm32-unknown-emscripten/release/resolc.js
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
../../../../target/wasm32-unknown-emscripten/release/resolc.wasm
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"language": "Solidity",
|
||||||
|
"sources": {
|
||||||
|
"fixtures/instantiate.sol": {
|
||||||
|
"content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.8.2 <0.9.0;\ncontract ChildContract {\n constructor() {\n }\n}\ncontract MainContract {\n constructor() {\n ChildContract newContract = new ChildContract();\n }\n}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"optimizer": {
|
||||||
|
"enabled": true,
|
||||||
|
"runs": 200
|
||||||
|
},
|
||||||
|
"outputSelection": {
|
||||||
|
"*": {
|
||||||
|
"*": ["abi"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,9 +72,7 @@
|
|||||||
},
|
},
|
||||||
"outputSelection": {
|
"outputSelection": {
|
||||||
"*": {
|
"*": {
|
||||||
"*": [
|
"*": ["abi"]
|
||||||
"abi"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -65,15 +65,15 @@ describe("Compile Function Tests", function () {
|
|||||||
expect(result).to.be.a("string");
|
expect(result).to.be.a("string");
|
||||||
const output = JSON.parse(result);
|
const output = JSON.parse(result);
|
||||||
expect(output).to.have.property("contracts");
|
expect(output).to.have.property("contracts");
|
||||||
expect(output.contracts["fixtures/instantiate_tokens.sol"]).to.have.property(
|
expect(
|
||||||
"TokensFactory",
|
output.contracts["fixtures/instantiate_tokens.sol"],
|
||||||
);
|
).to.have.property("TokensFactory");
|
||||||
expect(output.contracts["fixtures/instantiate_tokens.sol"].TokensFactory).to.have.property(
|
expect(
|
||||||
"abi",
|
output.contracts["fixtures/instantiate_tokens.sol"].TokensFactory,
|
||||||
);
|
).to.have.property("abi");
|
||||||
expect(output.contracts["fixtures/instantiate_tokens.sol"].TokensFactory).to.have.property(
|
expect(
|
||||||
"evm",
|
output.contracts["fixtures/instantiate_tokens.sol"].TokensFactory,
|
||||||
);
|
).to.have.property("evm");
|
||||||
expect(
|
expect(
|
||||||
output.contracts["fixtures/instantiate_tokens.sol"].TokensFactory.evm,
|
output.contracts["fixtures/instantiate_tokens.sol"].TokensFactory.evm,
|
||||||
).to.have.property("bytecode");
|
).to.have.property("bytecode");
|
||||||
@@ -117,27 +117,26 @@ describe("Compile Function Tests", function () {
|
|||||||
expect(output.contracts["fixtures/instantiate.sol"]).to.have.property(
|
expect(output.contracts["fixtures/instantiate.sol"]).to.have.property(
|
||||||
"ChildContract",
|
"ChildContract",
|
||||||
);
|
);
|
||||||
expect(output.contracts["fixtures/instantiate.sol"].ChildContract).to.have.property(
|
expect(
|
||||||
"abi",
|
output.contracts["fixtures/instantiate.sol"].ChildContract,
|
||||||
);
|
).to.have.property("abi");
|
||||||
expect(output.contracts["fixtures/instantiate.sol"].ChildContract).to.have.property(
|
expect(
|
||||||
"evm",
|
output.contracts["fixtures/instantiate.sol"].ChildContract,
|
||||||
);
|
).to.have.property("evm");
|
||||||
expect(
|
expect(
|
||||||
output.contracts["fixtures/instantiate.sol"].ChildContract.evm,
|
output.contracts["fixtures/instantiate.sol"].ChildContract.evm,
|
||||||
).to.have.property("bytecode");
|
).to.have.property("bytecode");
|
||||||
expect(output.contracts["fixtures/instantiate.sol"]).to.have.property(
|
expect(output.contracts["fixtures/instantiate.sol"]).to.have.property(
|
||||||
"MainContract",
|
"MainContract",
|
||||||
);
|
);
|
||||||
expect(output.contracts["fixtures/instantiate.sol"].MainContract).to.have.property(
|
expect(
|
||||||
"abi",
|
output.contracts["fixtures/instantiate.sol"].MainContract,
|
||||||
);
|
).to.have.property("abi");
|
||||||
expect(output.contracts["fixtures/instantiate.sol"].MainContract).to.have.property(
|
expect(
|
||||||
"evm",
|
output.contracts["fixtures/instantiate.sol"].MainContract,
|
||||||
);
|
).to.have.property("evm");
|
||||||
expect(
|
expect(
|
||||||
output.contracts["fixtures/instantiate.sol"].MainContract.evm,
|
output.contracts["fixtures/instantiate.sol"].MainContract.evm,
|
||||||
).to.have.property("bytecode");
|
).to.have.property("bytecode");
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
+14
-11
@@ -1,13 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "root",
|
"name": "root",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test:cli": "npm run test -w crates/solidity/src/tests/cli-tests",
|
"test:cli": "npm run test -w crates/solidity/src/tests/cli-tests",
|
||||||
"test:wasm": "npm run test:node -w js",
|
"test:wasm": "npm run test:node -w js/wasm",
|
||||||
"build:package": "npm run build:package -w js"
|
"build:package": "npm run build:package -w js/wasm",
|
||||||
},
|
"lint": "npx eslint 'js/**/*.{cjs,mjs,ts}' && npx prettier --check '**/*.{ts,json,yml,md}'",
|
||||||
"workspaces": [
|
"lint:fix": "npx prettier --write '**/*.{mjs,cjs,ts,json,yml,md}'"
|
||||||
"crates/solidity/src/tests/cli-tests",
|
},
|
||||||
"js"
|
"workspaces": [
|
||||||
]
|
"crates/solidity/src/tests/cli-tests",
|
||||||
|
"js/wasm",
|
||||||
|
"js/resolc"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user