Skip to content

Commit

Permalink
feat: OVM (#147)
Browse files Browse the repository at this point in the history
* Will drop eventually. Connect to the ovm compatible v3-core contracts

* Ignore optimism folder from source control

* Add hardhat-ovm package and config

* Add npm scripts for compiling and testing against the OVM

* Update to latest rebased with upstream changes core

* Add scripts for starting/stopping the optimism services (copy from core)

* Remove obsoleted Address.isContract check
as EOAs are contracts in Optimism

* Add @eth-optimism/hardhat-ovm and hardhat-contract-sizer to hardhat config

* Update commit used for ovm-compatible uniswap v3 core contracts

* Add to gitignore the ovm cache and artifacts folders

* Add hardhat-contract-sizer package

* Update PeripheryPayments.refundETH to use WETH instead of ETH

* Add hardhat-dependency-compiler plugin and use it to help link libraries

* Lower optimisation runs

* Patch @OpenZeppelin Address library for compliance with OVM

* Use WETH only for value transfer

* Extract NonfungiblePositionManager.collect function into a library
Lower NonfungiblePositionManager bytecode size by 1250 bytes

* Extract NonfungiblePositionManager.decreaseLiquidity function into a library
Lower NonfungiblePositionManager bytecode size by 972 bytes

* Extract NonfungiblePositionManager.increaseLiquidity function into a library
Lower NonfungiblePositionManager bytecode size by 523 bytes

* Extract LiquidityManagement.addLiquidity function into a library
Lower NonfungiblePositionManager bytecode size by 1483 bytes

* Merge NonfungibleTokenPositionDescriptor with NonfungiblePositionLibrary and make tokenURI function a library functionThis change made NonfungiblePositionManager contract size drop by just 83 bytes but more refactoring of this logic will follow to optimise that

* Do not recompose PoolKey struct. Saves 57 bytes in NonfungiblePositionManager contract size

* Do not recompose PoolKey struct in mint function. Saves 102 bytes in NonfungiblePositionManager contract size

* Remove mistakenly added empty file

* Do not instantiate PoolKey struct in memory, reference storage instead. Save 177 bytes in NonfungiblePositionManager contract size

* Optimise NonfungiblePositionLibrary.collect function. NonfungiblePositionManager bytecode decreased by 72 bytes

* Remove parameterisation of WETH address and make that constant
Saves 297 bytes from contract NonfungiblePositionManager contract size

* Cleanup usage of the NonfungiblePositionLibrary

* Optimise NonfungiblePositionLibrary.decreaseLiquidity function.
Saves NonfungiblePositionManager 113 bytes off contract size

* UniswapV3Pool and UniswapV3Factory are now only deployed once per test suite run

This change was required to accommodate the new libraries that need to
be linked to Uniswap V3 Core contracts. See the comments in
test/shared/setup.ts for more info

* Fix ABI imports

* Fix WETH test which broke from changes in commit de5a8d0

* Fix deployment of MockTimeNonfungiblePositionManager

* Add typechain-ovm folder to .gitignore

* fix import

* Update hardhat config with same adjustments made to Uniswap V3 Core

* Fix deployment of NonfungiblePositionManager

* Hardcode response to estimateGas to get more info on failures

* Fix: when testing on OVM, use pre-deployed WETH instead of deploying it

* Make NonfungiblePositionManager.poolIdToPoolKey mapping public

* Refactor NonfungibleTokenPositionDescriptor tests into NonfungibleTokenPositionLibrary

* Update @uniswap/v3-core to latest OVM-compatible commit

* Reduce optimizer's number of runs

* Update POOL_INIT_CODE_HASH - required due to update of v3-core contracts

* Optimise increaseLiquidity function in NonfungiblePositionManager
bytecode size decresed by 455 bytes

* Move all events from INonfungiblePositionManager to NonfungiblePositionLibrary
Decreased NonfungiblePositionManager bytecodesize by 301 bytes

* Switch isAuthorizedForToken from modifier to a private function
Saves 91 bytes in NonfungiblePositionManager bytecodesize

* Extract logic for updating a position after minting
Decreased NonfungiblePositionManager bytecode by 641 bytes

* Update script to pull regenesis/0.4.0 branch

* Restoring ETH opcodes: remove openzeppelin patch (undo 390ddbf)

* Restoring ETH opcodes: Restore how PeripheryPayments handles ETH (undo 0fd3c46)

* Restoring ETH opcodes: Undo test changes used to accomodate hardcoded WETH (undo b6b57c7 and f5b905d)

* Restoring ETH opcodes: Add WETH back as an input parameter (undo 72c0000)

* Switch l2geth and ovm solc version to WIP versions supporting ETH opcodes

* Add WETH address constructor arg to MockTimeNonfungiblePositionManager

* Fix token ordering in V3 migrator test (token input order must be sorted)

* Restore isContract check so EVM tests pass (undo 42577c0)

* Fix test that expected a revert but is no longer expected to revert

* Remove estimateGas override - estimateGas now provides useful error messages

* Add original WETH9 contract (sourced from https://etherscan.io/address/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2#code)

* Modify WETH9 to support 0.7.6 and deploy it from compiled contract

* Fix nonce too low error by awaiting each deploy instead of Promise.all()

* Fix unsafe opcode from IncreaseLiquidity event

* Fix various nonce too low errors by awaiting each call instead of Promise.all()

* Add a 'Setup' test to ensure we always get the same bytecode hash

* Update optimism repo and branch used

* Remove unnecessary isContract check (undo 26519a2)

On the OVM all accounts are contracts so this is not necessary. This
change is also required to get contracts below the size limit

* Update fixtures to only deploy WETH once to ensure safe address

* Skip EOA tests since OVM has no EOAs

* Fix nonce too low error by awaiting each call instead of Promise.all()

* Fix for 'fully populated ticks' test reverting by using too much gas

* Add instructions about how to run tests

* Update to latest v3-core commit

* Update branch used for optimism docker containers

* Fix WETH9 to use a call instead of msg.sender.transfer()

* Update run-optimism script to use the regenesis/0.4.0 branch

* Rename NonfungibleTokenPositionLibrary test file back to NonfungibleTokenPositionDescriptor

This was renamed to better describe what the test file does after
library changes, but is renamed back here to make the diff more clear

* Update expected revert string for permit test with invalid v value

* Merge commit fix: Add WETH9 getter to TestNonfungiblePositionLibrary

* Merge commit fix: Remove Promise.all and link library in Oracle test

* Merge commit fix: Remove Promise.all, only run gas estimate assertions on EVM

* Patch waffle's deployMockContract to support mock OVM contracts

* Only run EOA permit tests on the OVM since they require EIP-1271

* Update multicall test to use two transactions to avoid exceeding OVM gas limit

* Update README

* Update OVM solc version (same build, cleaner syntax)

* Automatically update POOL_INIT_CODE_HASH when running tests

* Add CI job for OVM unit tests

* Update @uniswap/v3-core dependency to point to Uniswap repo

* Run prettier

* deploy WETH in EVM, use 0x420..06 in OVM

* Configure test reliant on hardcoded WETH address to only run on OVM

* Run prettier

* Skip V3 migrator tests on OVM

* Don't fail if there is no backup file created by sed (for CI)

* Update EVM snapshots for CI (OVM CI tests update snapshots)

Co-authored-by: elenadimitrova <elena@arenabg.com>
Co-authored-by: Kevin Ho <kevinjho1996@gmail.com>
  • Loading branch information
3 people committed Jun 17, 2021
1 parent cdc178d commit 209aa94
Show file tree
Hide file tree
Showing 52 changed files with 1,495 additions and 753 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,36 @@ jobs:

- name: Run unit tests
run: yarn test

ovm-unit-tests:
name: Unit Tests
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12.x

- id: yarn-cache
run: echo "::set-output name=dir::$(yarn cache dir)"

- uses: actions/cache@v1
with:
path: ${{ steps.yarn-cache.outputs.dir }}
key: yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
yarn-
- name: Install dependencies
run: yarn install --frozen-lockfile

# This is required separately from yarn test because it generates the typechain definitions
- name: Compile
run: yarn compile:ovm

- name: Bring Optimism Up
run: yarn optimism-up

- name: Run unit tests
run: UPDATE_SNAPSHOT=1 yarn test:ovm
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,9 @@ artifacts/
cache/
crytic-export/
node_modules/
typechain/
typechain/
typechain-ovm/
optimism

artifacts-ovm/
cache-ovm/
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,26 @@ This repository contains the periphery smart contracts for the Uniswap V3 Protoc
For the lower level core contracts, see the [uniswap-v3-core](https://github.com/Uniswap/uniswap-v3-core)
repository.

## Testing

Because these contracts and tests are modified for OVM support, there are some changes that mean we can no longer simply run `yarn test` and `yarn test:ovm` and expect all tests to pass for both the EVM and OVM. There are a few reasons for this:

1. EVM vs. OVM contracts will use different amounts of gas, so the gas tests will fail
2. `PoolAddress.sol` has a hardcoded bytecode hash, but this hash will be different for EVM vs. OVM bytecode
3. In Uniswap V3 Core and Periphery contracts some logic was pulled out into library contracts to reduce contract size. The original EVM contracts had deterministic bytecode, so a bytecode hash can be easily hardcoded in `PoolAddress.sol`, but this is no longer true. The contracts now require linking libraries, and therefore the bytecode and bytecode hash is dependent on the library addresses, which are dependent on the deployer account and nonce

Therefore, we must follow the steps below to run EVM tests in this repo:

1. Run `UPDATE_SNAPSHOT=1 yarn test` which will ensure gas costs snapshots are updated (i.e. tests will not fail for gas cost reasons)

And to run OVM tests:

1. Run `yarn postinstall` to apply a patch that adds OVM mock contract support to Waffle
2. Run `UPDATE_SNAPSHOT=1 yarn test:ovm` which will ensure gas costs snapshots are updated (i.e. tests will not fail for gas cost reasons)
3. On subsequent test runs, run `yarn optimism-down && yarn optimism-up && UPDATE_SNAPSHOT=1 yarn test:ovm`. This is required so the deployer account nonce is reset to zero, which is necessary to get the above bytecode hash when deploying contracts

Both test commands (`yarn test` and `yarn test:ovm`) will automatically update the `POOL_INIT_CODE_HASH` in `PoolAddress.sol` as needed for testing.

## Bug bounty

This repository is subject to the Uniswap V3 bug bounty program,
Expand Down

0 comments on commit 209aa94

Please sign in to comment.