Skip to content

Commit

Permalink
Merge pull request #1 from yieldnest/feat/base-keeper
Browse files Browse the repository at this point in the history
Feat/base keeper
  • Loading branch information
MrDeadCe11 authored Jan 5, 2025
2 parents 0f0f132 + 68cebca commit 81eb4d3
Show file tree
Hide file tree
Showing 11 changed files with 476 additions and 0 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: CI

on:
push:
pull_request:
workflow_dispatch:

env:
FOUNDRY_PROFILE: ci

jobs:
check:
strategy:
fail-fast: true

name: Foundry project
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

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

- name: Show Forge version
run: |
forge --version
- name: Run Forge fmt
run: |
forge fmt --check
id: fmt

- name: Run Forge build
run: |
forge build --sizes --skip DeployFactory.sol
id: build

- name: Run Forge Unit tests
env:
FOUNDRY_PROFILE: default
run: |
forge test -vvv
id: test

- name: Run Forge Integration tests
env:
FOUNDRY_PROFILE: mainnet
BSCSCAN_API_KEY: invalid
run: |
forge test -vvv
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Compiler files
cache/
out/

# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/**/dry-run/
/coverage/
lcov.info

# Dotenv file
.env
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "lib/yieldnest-vault"]
path = lib/yieldnest-vault
url = https://github.com/yieldnest/yieldnest-vault
branch = eth-max-vault
9 changes: 9 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

main :; FOUNDRY_PROFILE=mainnet forge test -vvv
unit :; FOUNDRY_PROFILE=default forge test -vvv

# Coverage https://github.com/linux-test-project/lcov (brew install lcov)
cover :; forge coverage --watch --report lcov && genhtml lcov.info --branch-coverage --output-dir coverage
show :; npx http-server ./coverage

fmt :; FOUNDRY_PROFILE=default forge fmt && FOUNDRY_PROFILE=mainnet forge fmt
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Yieldnest Vault Keepers
58 changes: 58 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
test = "test/unit"
evm_version = "cancun"
optimizer = true
optimizer-runs = 200
solc_version = "0.8.24"
auto_detect_remappings = false
max-line-length = 120
ffi = true

[profile.mainnet]
src = "src"
out = "out"
libs = ["lib"]
test = "test/mainnet"
eth_rpc_url = "bnb_mainnet"
evm_version = "cancun"
solc_version = "0.8.24"
auto_detect_remappings = false
max-line-length = 120
ffi = true
fs_permissions = [
{ access = "read-write", path = "./deployments" },
{ access = "read", path = "./" },
]

[profile.testnet]
src = "src"
out = "out"
libs = ["lib"]
test = "test/mainnet"
eth_rpc_url = "bnb_testnet"
evm_version = "cancun"
solc_version = "0.8.24"
max-line-length = 120
auto_detect_remappings = false
ffi = true
fs_permissions = [
{ access = "read-write", path = "./deployments" },
{ access = "read", path = "./" },
]


[rpc_endpoints]
bnb_mainnet = "https://bnb-mainnet.g.alchemy.com/v2/1FX7IZKqADVmU4ew3b7WD6NYNK5Ui0N7"
bnb_testnet = "https://rpc.ankr.com/bsc_testnet_chapel"

[fmt]
sort_imports = true
line_length = 120
wrap_comments = true

[etherscan]
bnb_mainnet = { key = "${BSCSCAN_API_KEY}", url = "https://api.bscscan.com/api/" }
bnb_testnet = { key = "${BSCSCAN_API_KEY}", url = "https://api-testnet.bscscan.com/api/" }
1 change: 1 addition & 0 deletions lib/yieldnest-vault
Submodule yieldnest-vault added at 9a86e0
4 changes: 4 additions & 0 deletions remappings.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
lib/forge-std/src=./lib/yieldnest-vault/lib/forge-std/src
@openzeppelin/contracts=./lib/yieldnest-vault/lib/openzeppelin-contracts/contracts
lib/openzeppelin-contracts=./lib/yieldnest-vault/lib/openzeppelin-contracts
lib/openzeppelin-contracts-upgradeable=./lib/yieldnest-vault/lib/openzeppelin-contracts-upgradeable
103 changes: 103 additions & 0 deletions src/BaseKeeper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.24;

// import {IVault} from "lib/yieldnest-vault/src/interface/IVault.sol";

contract BaseKeeper {
uint256[] public initialRatios;
uint256[] public finalRatios;

// vault[0] is max vault and rest are underlying vaults
address[] public vaults;

struct Transfer {
uint256 from;
uint256 to;
uint256 amount;
}

function setData(uint256[] memory _initialRatios, uint256[] memory _finalRatios, address[] memory _vaults) public {
require(_initialRatios.length > 1, "Array length must be greater than 1");
require(_initialRatios.length == _finalRatios.length, "Array lengths must match");
require(_initialRatios.length == _vaults.length, "Array lengths must match");

initialRatios = _initialRatios;
finalRatios = _finalRatios;
vaults = _vaults;
}

function totalInitialRatios() public view returns (uint256) {
uint256 total = 0;
for (uint256 i = 0; i < initialRatios.length; i++) {
total += initialRatios[i];
}
return total;
}

function totalFinalRatios() public view returns (uint256) {
uint256 total = 0;
for (uint256 i = 0; i < finalRatios.length; i++) {
total += finalRatios[i];
}
return total;
}

function caculateSteps() public view returns (Transfer[] memory) {
uint256 length = initialRatios.length;
require(length > 1, "Array length must be greater than 1");
require(length == finalRatios.length, "Array lengths must match");
require(length == vaults.length, "Array lengths must match");

uint256 totalInitial = totalInitialRatios();
uint256 totalFinal = totalFinalRatios();
require(totalInitial == totalFinal, "Ratios must add up");

// address baseVault = vaults[0];
// uint256 totalAssets = IVault(baseVault).totalAssets();

uint256 totalAssets = 100; // for testing set to 100

uint256[] memory initialAmounts = new uint256[](length);
for (uint256 i = 0; i < length; i++) {
initialAmounts[i] = initialRatios[i] * totalAssets / totalInitial;
}

uint256[] memory finalAmounts = new uint256[](length);
for (uint256 i = 0; i < length; i++) {
finalAmounts[i] = finalRatios[i] * totalAssets / totalFinal;
}

int256[] memory diffs = new int256[](length);

// Calculate differences
for (uint256 i = 0; i < length; i++) {
diffs[i] = int256(initialAmounts[i]) - int256(finalAmounts[i]);
}

Transfer[] memory steps = new Transfer[](length);
uint256 stepIndex = 0;

for (uint256 i = 0; i < length; i++) {
if (diffs[i] > 0) {
for (uint256 j = 0; j < length; j++) {
if (diffs[j] < 0) {
uint256 transferAmount = uint256(diffs[i] > -diffs[j] ? -diffs[j] : diffs[i]);
steps[stepIndex++] = Transfer(i, j, transferAmount);

diffs[i] -= int256(transferAmount);
diffs[j] += int256(transferAmount);

if (diffs[i] == 0) break;
}
}
}
}

Transfer[] memory finalSteps = new Transfer[](stepIndex);
for (uint256 i = 0; i < stepIndex; i++) {
finalSteps[i] = steps[i];
}

return finalSteps;
}
}
8 changes: 8 additions & 0 deletions test/mainnet/sample.spec.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: BSD-3-Clause
pragma solidity ^0.8.24;

import "lib/forge-std/src/Test.sol";

contract SampleTest is Test {
function test_nothing() public {}
}
Loading

0 comments on commit 81eb4d3

Please sign in to comment.