Skip to content

Commit

Permalink
build: setup repo
Browse files Browse the repository at this point in the history
  • Loading branch information
Schlagonia committed Jun 8, 2023
1 parent c3bc6c3 commit 7c4ad2e
Show file tree
Hide file tree
Showing 33 changed files with 1,687 additions and 41 deletions.
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ETH_RPC_URL=
FTM_RPC_URL=https://rpcapi.fantom.network
ARBI_RPC_URL=https://arb1.arbitrum.io/rpc
GC_RPC_URL=https://xdai.poanetwork.dev
BSC_RPC_URL=https://bsc-dataseed.binance.org
MATIC_RPC_URL=
ETHERSCAN_API_KEY=
58 changes: 58 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Lint

on:
push:
branches:
- master
pull_request:

jobs:

solidity:
runs-on: ubuntu-latest

steps:
- name: Check out github repository
uses: actions/checkout@v2
with:
fetch-depth: 1

- name: Setup node.js
uses: actions/setup-node@v1
with:
node-version: '16.x'

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

- name: Restore yarn cache
uses: actions/cache@v2
id: yarn-cache
with:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
${{ runner.os }}-yarn-
- name: Install node.js dependencies
run: yarn --frozen-lockfile

- name: Run formater check on *.sol and *.json
run: yarn format:check

- name: run linter check on *.sol file
run: yarn lint

commits:
runs-on: ubuntu-latest

steps:
- name: Check out github repository
uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Run commitlint
uses: wagoid/commitlint-github-action@v2
11 changes: 8 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
name: test

on: workflow_dispatch
on:
push:
branches:
- master
- develop
pull_request:

env:
FOUNDRY_PROFILE: ci
Expand Down Expand Up @@ -30,5 +35,5 @@ jobs:

- name: Run Forge tests
run: |
forge test -vvv
id: test
forge test -vvv --fork-url ${{ secrets.ETH_RPC_URL }} --etherscan-api-key ${{ secrets.ETHERSCAN_API_KEY }}
id: test
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ docs/

# Dotenv file
.env

.vscode/
node_modules/
.gas-snapshot
18 changes: 18 additions & 0 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"extends": "solhint:recommended",
"plugins": [],
"rules": {
"compiler-version": ["error", "0.8.18"],
"code-complexity": "warn",
"const-name-snakecase": "warn",
"function-max-lines": "warn",
"func-visibility": ["warn", { "ignoreConstructors": true }],
"max-line-length": ["warn", 160],
"avoid-suicide": "error",
"avoid-sha3": "warn",
"not-rely-on-time": "off",
"private-vars-leading-underscore": "off",
"reason-string": ["warn", { "maxLength": 64 }],
"no-console": "off"
}
}
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-include .env

# deps
update:; forge update
build :; forge build
size :; forge build --sizes

# storage inspection
inspect :; forge inspect ${contract} storage-layout --pretty

FORK_URL := ${ETH_RPC_URL}

# local tests without fork
test :; forge test -vv --fork-url ${FORK_URL} --etherscan-api-key ${ETHERSCAN_API_KEY}
trace :; forge test -vvv --fork-url ${FORK_URL} --etherscan-api-key ${ETHERSCAN_API_KEY}
gas :; forge test --fork-url ${FORK_URL} --etherscan-api-key ${ETHERSCAN_API_KEY} --gas-report
test-contract :; forge test -vv --match-contract $(contract) --fork-url ${FORK_URL} --etherscan-api-key ${ETHERSCAN_API_KEY}
test-contract-gas :; forge test --gas-report --match-contract ${contract} --fork-url ${FORK_URL} --etherscan-api-key ${ETHERSCAN_API_KEY}
trace-contract :; forge test -vvv --match-contract $(contract) --fork-url ${FORK_URL} --etherscan-api-key ${ETHERSCAN_API_KEY}
test-test :; forge test -vv --match-test $(test) --fork-url ${FORK_URL} --etherscan-api-key ${ETHERSCAN_API_KEY}
trace-test :; forge test -vvv --match-test $(test) --fork-url ${FORK_URL} --etherscan-api-key ${ETHERSCAN_API_KEY}

clean :; forge clean
snapshot :; forge snapshot
52 changes: 52 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Tokenized Strategy Periphery Contract

This repo contains the option contracts that can be used for any Yearn V3 tokenized strategy to make strategy development even easier.

## Apr Oracle
add stuff

## Swapper helper contracts
say stuff

## HealthCheck
more stuff

## Report Triggers
Good stuff

## How to start

### Requirements
First you will need to install [Foundry](https://book.getfoundry.sh/getting-started/installation).
NOTE: If you are on a windows machine it is recommended to use [WSL](https://learn.microsoft.com/en-us/windows/wsl/install)

### Fork this repository

git clone --recursive https://github.com/user/tokenized-strategy-periphery

cd tokenized-strategy-periphery

yarn


### Set your environment Variables

Sign up for [Infura](https://infura.io/) and generate an API key and copy your RPC url. Store it in the `ETH_RPC_URL` environment variable.
NOTE: you can use other services.

Use .env file
1. Make a copy of `.env.example`
2. Add the values for `ETH_RPC_URL`, `ETHERSCAN_API_KEY` and other example vars
NOTE: If you set up a global environment variable, that will take precedence.


### Build the project.

```sh
make build
```

Run tests
```sh
make test
```
7 changes: 7 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,11 @@ src = 'src'
out = 'out'
libs = ['lib']

remappings = [
'forge-std/=lib/forge-std/src/',
'@openzeppelin/=lib/openzeppelin-contracts/',
"@tokenized-strategy/=lib/tokenized-strategy/src/",
"@yearn-vaults/=lib/yearn-vaults-v3/contracts/"
]

# See more config options https://github.com/foundry-rs/foundry/tree/master/config
17 changes: 17 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "yearn_base_strategy",
"devDependencies": {
"prettier": "^2.5.1",
"prettier-plugin-solidity": "^1.0.0-beta.19",
"pretty-quick": "^3.1.3",
"solc": "0.8.18",
"solhint": "^3.3.7",
"solhint-plugin-prettier": "^0.0.5"
},
"scripts": {
"format": "prettier --write 'src/**/*.(sol|json)'",
"format:check": "prettier --check 'src/**/*.*(sol|json)'",
"lint": "solhint 'src/**/*.sol'",
"lint:fix": "solhint --fix 'src/**/*.sol'"
}
}
4 changes: 4 additions & 0 deletions remapping.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@openzeppelin/=lib/openzeppelin-contracts/
forge-std/=lib/forge-std/src/
@tokenized-strategy/=lib/tokenized-strategy/src/
@yearn-vaults/=lib/yearn-vaults-v3/contracts/
81 changes: 81 additions & 0 deletions src/AprOracle/AprOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.18;

import {IStrategy} from "../interfaces/IStrategy.sol";

interface IVault {
function totalAssets() external view returns (uint256);

function profitUnlockingRate() external view returns (uint256);

function fullProfitUnlockDate() external view returns (uint256);

function convertToAssets(uint256) external view returns (uint256);
}

interface IOracle {
function aprAfterDebtChange(
address _asset,
int256 _delta
) external view returns (uint256);
}

contract AprOacle {
mapping(address => address) public oracles;

uint256 internal constant MAX_BPS_EXTENDED = 1_000_000_000_000;
uint256 internal constant SECONDS_PER_YEAR = 31_556_952;

function getExpectedApr(
address _strategy,
int256 _debtChange
) public view returns (uint256) {
address oracle = oracles[_strategy];

// Will revert if a oracle is not set.
return IOracle(oracle).aprAfterDebtChange(_strategy, _debtChange);
}

function weightedApr(address _strategy) external view returns (uint256) {
return
IStrategy(_strategy).totalAssets() * getExpectedApr(_strategy, 0);
}

function setOracle(address _strategy, address _oracle) external {
require(msg.sender == IStrategy(_strategy).management(), "!authorized");

oracles[_strategy] = _oracle;
}

/**
* @notice Get the expected APR for a V3 vault or strategy.
* @dev This returns the expected APR based off the current
* rate of profit unlocking for either a vault or strategy.
*
* Will return 0 if there is no profit unlocking or no assets.
*
* @param _vault The address of the vault or strategy.
* @return apr The expected current apr expressed as 1e18.
*/
function getVaultApr(address _vault) external view returns (uint256 apr) {
IVault vault = IVault(_vault);

// Need the total assets in the vault.
uint256 assets = vault.totalAssets();

// No apr if there are no assets.
if (assets == 0) return 0;

// We need to get the amount of assets that are unlocking per second.
// `profitUnlockingRate` is in shares so we convert it to assets.
uint256 assetUnlockingRate = vault.convertToAssets(
vault.profitUnlockingRate()
);

// APR = assets unlocking per second * seconds per year / the total assets.
apr =
(1e18 * assetUnlockingRate * SECONDS_PER_YEAR) /
MAX_BPS_EXTENDED /
assets;
}
}
31 changes: 31 additions & 0 deletions src/AprOracle/AprOracleBase.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.18;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

abstract contract AprOracleBase is Ownable {
string public name;

constructor(string memory _name) {
name = _name;
}

/**
* @notice Will return the expected Apr of a strategy post a debt change.
* @dev _delta is a signed integer so that it can also repersent a debt
* decrease.
*
* _delta will be == 0 to get the current apr.
*
* This will potentially be called during non-view functions so gas
* effeciency should be taken into account.
*
* @param _strategy The strategy to get the apr for.
* @param _delta The difference in debt.
* @return . The expected apr for the strategy.
*/
function aprAfterDebtChange(
address _strategy,
int256 _delta
) external view virtual returns (uint256);
}
14 changes: 0 additions & 14 deletions src/Counter.sol

This file was deleted.

Loading

0 comments on commit 7c4ad2e

Please sign in to comment.