Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: use anvil for tests #197

Draft
wants to merge 24 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .github/workflows/foundry.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Foundry tests

on:
push:
branches:
- master
pull_request:

concurrency:
group: ${{github.workflow}}-${{github.ref}}
cancel-in-progress: true

jobs:
unit:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
architecture:
- "x64"
python-version:
- "3.10"
node_version:
- 16

steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive

- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
architecture: ${{ matrix.architecture }}

- name: Install Ape
uses: ApeWorX/github-action@v2.0
with:
python-version: '3.10'

- name: install vyper
run: pip install git+https://github.com/vyperlang/vyper

- name: Compile contracts
# Compile Ape contracts to get dependencies
run: ape compile --force --size

- name: Install Vyper
run: pip install vyper==0.3.7

- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node_version }}

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Foundry tests
run: forge test -vvv
2 changes: 1 addition & 1 deletion .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,4 @@ jobs:
run: pip install -r requirements.txt

- name: Run black
run: black --check --include "(tests|scripts)" .
run: black --check .
19 changes: 7 additions & 12 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,24 @@ jobs:
- uses: ApeWorX/github-action@v2.0
with:
python-version: '3.10'
ape-version-pin: "==0.6.3"
ape-plugins-list: 'solidity==0.6.0 vyper==0.6.1 hardhat==0.6.0'

- name: install vyper
run: pip install git+https://github.com/vyperlang/vyper
- name: Compile contracts
# TODO: Force recompiles until ape compile caching is fixed
run: ape compile --force --size

# Needed to use hardhat
- name: Setup node.js
uses: actions/setup-node@v1
with:
node-version: '14.x'

- name: Install hardhat
run: npm install hardhat
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: output current installation
run: pip freeze

- name: Run tests
run: ape test -s
- name: Run Ape tests
run: ape test
timeout-minutes: 15
env:
TOKENS_TO_TEST: ${{ matrix.tokens_to_test }}

- name: Run Foundry tests
run: forge test -vvv
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
pyenv.cfg
vyper_git_commithash.txt
bin/
lib/
cache/
out/
share/
build/
include/
Expand All @@ -17,3 +18,5 @@ venv/
.vscode
yarn.lock
env
cache/
out/
6 changes: 6 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
[submodule "lib/erc4626-tests"]
path = lib/erc4626-tests
url = https://github.com/a16z/erc4626-tests
2 changes: 1 addition & 1 deletion .solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@
"not-rely-on-time": "off",
"private-vars-leading-underscore": "warn",
"reason-string": ["warn", { "maxLength": 64 }],
"yearn/underscore-function-args": "error"
"yearn/underscore-function-args": "off"
}
}
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@ This repository runs on [ApeWorx](https://www.apeworx.io/). A python based devel

You will need:
- Python 3.8 or later
- Vyper 0.3.7
- [Vyper 0.3.7](https://docs.vyperlang.org/en/stable/installing-vyper.html)
- [Foundry](https://book.getfoundry.sh/getting-started/installation)
- Linux or macOS
- Windows: Install Windows Subsystem Linux (WSL) with Python 3.8 or later
- [Hardhat](https://hardhat.org/) installed globally

## Installation

Fork the repository and clone onto your local device

```
git clone https://github.com/user/yearn-vaults-v3
git clone --recursive https://github.com/user/yearn-vaults-v3
cd yearn-vaults-v3
```

Expand Down Expand Up @@ -60,8 +60,14 @@ and test smart contracts with:
ape test
```

To run the Foundry tests

NOTE: You will need to first compile with Ape before running foundry tests.
```
forge test
```


### To make a contribution please follow the [guidelines](https://github.com/yearn/yearn-vaults-v3/bloc/master/CONTRIBUTING.md)

See the ApeWorx [documentation](https://docs.apeworx.io/ape/stable/) and [github](https://github.com/ApeWorX/ape) for more information.

You will need hardhat to run the test `yarn`
2 changes: 1 addition & 1 deletion TECH_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ This responsibility is taken by callers with DEBT_MANAGER role

This role can increase or decrease strategies specific debt.

The vault sends and receives funds to/from strategies. The function updateDebt(strategy, target_debt) will set the current_debt of the strategy to target_debt (if possible)
The vault sends and receives funds to/from strategies. The function update_debt(strategy, target_debt, max_loss) will set the current_debt of the strategy to target_debt (if possible)

If the strategy currently has less debt than the target_debt, the vault will send funds to it.

Expand Down
20 changes: 11 additions & 9 deletions ape-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,29 @@ name: yearn-v3

plugins:
- name: solidity
version: 0.6.0
- name: vyper
version: 0.6.1
- name: hardhat
version: 0.6.0
- name: foundry

default_ecosystem: ethereum

foundry:
base_fee: 0
priority_fee: 0

dependencies:
- name: openzeppelin
github: OpenZeppelin/openzeppelin-contracts
version: 4.7.3
ref: 4.9.5
- name: tokenized-strategy
github: yearn/tokenized-strategy
branch: master
ref: dev_302
contracts_folder: src

solidity:
import_remapping:
- "@openzeppelin/contracts=openzeppelin/v4.7.3"
- "@tokenized-strategy=tokenized-strategy/master"
- "@openzeppelin/contracts=openzeppelin/v4.9.5"
- "@tokenized-strategy=tokenized-strategy/dev_302"

ethereum:
local:
default_provider: hardhat
default_provider: foundry
62 changes: 36 additions & 26 deletions contracts/VaultFactory.vy
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
This vault Factory can be used by anyone wishing to deploy their own
ERC4626 compliant Yearn V3 Vault of the same API version.

The factory uses the Blueprint (ERC-5202) standard to handle the
deployment of any new vaults off of the immutable address stored
at `VAULT_BLUEPRINT`. This allows the vaults to be deployed and
initialized fully on-chain with their init byte code, thus not
requiring any delegatecall patterns or post deployment initialization.
The factory clones new vaults from its specific `VAULT_ORIGINAL`
immutable address set on creation of the factory.

The deployments are done through create2 with a specific `salt`
that is derived from a combination of the deployer's address,
the underlying asset used, as well as the name and symbol specified.
Expand All @@ -33,6 +31,15 @@

from vyper.interfaces import ERC20

interface IVault:
def initialize(
asset: address,
name: String[64],
symbol: String[32],
role_manager: address,
profit_max_unlock_time: uint256
): nonpayable

event NewVault:
vault_address: indexed(address)
asset: indexed(address)
Expand Down Expand Up @@ -68,13 +75,13 @@ struct PFConfig:
fee_recipient: address

# Identifier for this version of the vault.
API_VERSION: constant(String[28]) = "3.0.1"
API_VERSION: constant(String[28]) = "3.0.2"

# The max amount the protocol fee can be set to.
MAX_FEE_BPS: constant(uint16) = 5_000 # 50%

# The address that all newly deployed vaults are based from.
VAULT_BLUEPRINT: immutable(address)
VAULT_ORIGINAL: immutable(address)

# State of the Factory. If True no new vaults can be deployed.
shutdown: public(bool)
Expand All @@ -95,21 +102,21 @@ custom_protocol_fee: public(HashMap[address, uint16])
use_custom_protocol_fee: public(HashMap[address, bool])

@external
def __init__(name: String[64], vault_blueprint: address, governance: address):
def __init__(name: String[64], vault_original: address, governance: address):
self.name = name
VAULT_BLUEPRINT = vault_blueprint
VAULT_ORIGINAL = vault_original
self.governance = governance

@external
def deploy_new_vault(
asset: ERC20,
asset: address,
name: String[64],
symbol: String[32],
role_manager: address,
profit_max_unlock_time: uint256
) -> address:
"""
@notice Deploys a new vault base on the bLueprint.
@notice Deploys a new clone of the original vault.
@param asset The asset to be used for the vault.
@param name The name of the new vault.
@param symbol The symbol of the new vault.
Expand All @@ -120,29 +127,32 @@ def deploy_new_vault(
# Make sure the factory is not shutdown.
assert not self.shutdown, "shutdown"

# Deploy the new vault using the blueprint.
vault_address: address = create_from_blueprint(
VAULT_BLUEPRINT,
asset,
name,
symbol,
role_manager,
profit_max_unlock_time,
code_offset=3,
salt=keccak256(_abi_encode(msg.sender, asset.address, name, symbol))
# Clone a new version of the vault using create2.
vault_address: address = create_minimal_proxy_to(
VAULT_ORIGINAL,
value=0,
salt=keccak256(_abi_encode(msg.sender, asset, name, symbol))
)

IVault(vault_address).initialize(
asset,
name,
symbol,
role_manager,
profit_max_unlock_time,
)

log NewVault(vault_address, asset.address)
log NewVault(vault_address, asset)
return vault_address

@view
@external
def vault_blueprint()-> address:
def vault_original()-> address:
"""
@notice Get the address of the vault blueprint
@return The address of the vault blueprint
@notice Get the address of the vault to clone from
@return The address of the original vault.
"""
return VAULT_BLUEPRINT
return VAULT_ORIGINAL

@view
@external
Expand Down
Loading
Loading