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

Feat/v2 #167

Merged
merged 96 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
2c597e7
removed contracts that arent required for the audit
RedVeil Mar 28, 2024
97fe9c0
Merge branch 'main' into audit/24-03
RedVeil Apr 5, 2024
b3d42e0
Merge branch 'main' into audit/24-03
RedVeil Apr 5, 2024
2e93bd2
Add Pendle adapter - wip
Andreadinenno Apr 9, 2024
d12e712
Add Pendle base adapter and wstETH implementation
Andreadinenno Apr 10, 2024
6cd1014
Add harvest function and compound via Balancer. Add tests
Andreadinenno Apr 11, 2024
b4bdef6
Remove duplicate code
Andreadinenno Apr 11, 2024
fba2715
Format code
Andreadinenno Apr 11, 2024
364f369
Refactor adapter init
Andreadinenno Apr 12, 2024
f652c5f
Add USDe pendle adapter, tests. Minor optimizations
Andreadinenno Apr 12, 2024
dcd8074
Fix oracle rate issue
Andreadinenno Apr 15, 2024
197dcb2
Fix LRTs tests
Andreadinenno Apr 16, 2024
b273493
Add fee tier to all pendle markets. Add supply cap to USDe markets
Andreadinenno Apr 17, 2024
8b9e6ce
Merge branch 'main' into audit/24-03
RedVeil Apr 17, 2024
81a8577
wip - inital cleanup
RedVeil Apr 17, 2024
80f4e4a
wip - cleaned up BaseStrategy
RedVeil Apr 17, 2024
e018ae9
wip - added basic scripts, moved strategies
RedVeil Apr 17, 2024
e7d2fe8
wip - further cleanup
RedVeil Apr 18, 2024
8314a2d
init
RedVeil Apr 18, 2024
696da30
wip - brought in v2 testing
RedVeil Apr 18, 2024
2416ec2
wip - removed test utils
RedVeil Apr 18, 2024
6f46fdb
Underestimate total assets and handle floating amount
Andreadinenno Apr 22, 2024
c61cabc
Fix tests
Andreadinenno Apr 22, 2024
34898ad
Use pendle router static for total assets. Remove oracle support
Andreadinenno Apr 23, 2024
e9bf0ea
Fix tests
Andreadinenno Apr 23, 2024
098313b
wip - simplify tests
RedVeil Apr 23, 2024
3aa44c5
wip - setHarvestValues
RedVeil Apr 23, 2024
0f3a039
Aura Compounder and test fixed
RedVeil Apr 23, 2024
210b917
added balancer
RedVeil Apr 23, 2024
b673f07
added convex and curve tests
RedVeil Apr 25, 2024
762a99c
added WstETHLooper strategy test
RedVeil Apr 25, 2024
5c2439d
added gearbox test
RedVeil Apr 26, 2024
38194dd
added deploy scripts
RedVeil Apr 26, 2024
264aadd
deploy scripts added
RedVeil Apr 26, 2024
ac7dc99
added beefy
RedVeil Apr 26, 2024
b6d046d
added compound
RedVeil Apr 26, 2024
979ffc4
added compound
RedVeil Apr 26, 2024
4ffa4e7
updated vault deploy script
RedVeil Apr 27, 2024
b53a49b
deploy fee recipient script fixed
RedVeil Apr 30, 2024
a32228f
wip - test fixing part 1
RedVeil Apr 30, 2024
ef7692a
fixed looper init
RedVeil May 2, 2024
ef398bf
Generalise implementations
Andreadinenno May 2, 2024
47bbb37
test adjustments
RedVeil May 2, 2024
f13c63c
Dynamic reward tokens fetching
Andreadinenno May 3, 2024
3ee1c73
fixed convex test
RedVeil May 6, 2024
161e67a
curve working
RedVeil May 6, 2024
1604264
Switch to router v4 in tests. Edit fork block
Andreadinenno May 8, 2024
89a3891
removed log
RedVeil May 10, 2024
f6ea9d9
wip - simplify compounder
RedVeil May 13, 2024
8c3b4a9
moved fees from strategies to vault
RedVeil May 13, 2024
cca8667
wip - adding optional data to protocol deposits, added keeper, added …
RedVeil May 13, 2024
f6beaec
added harvest data to harvest
RedVeil May 14, 2024
f5cb7ca
Merge branch 'feat/v1.5-optionalData' into feat/v1.5-simplifyCompounder
RedVeil May 14, 2024
d376def
added balancerBaseCompounder
RedVeil May 14, 2024
586134c
lp compounder added
RedVeil May 14, 2024
ca99242
simplified curve folder
RedVeil May 14, 2024
d1f61ae
little fix
RedVeil May 14, 2024
4dd30a3
wip - add conversion slippage
RedVeil May 14, 2024
70cb63d
Merge pull request #169 from Popcorn-Limited/feat/v1.5-optionalData
RedVeil May 16, 2024
ac88fbc
Merge branch 'feat/v-1.5' into feat/v1.5-simplifyCompounder
RedVeil May 16, 2024
25d92e1
Merge pull request #170 from Popcorn-Limited/feat/v1.5-conversionStra…
RedVeil May 16, 2024
76f6b18
Merge pull request #168 from Popcorn-Limited/feat/v1.5-simplifyCompou…
RedVeil May 16, 2024
94d5f77
fixed build issues and updated tests
RedVeil May 16, 2024
8987e4c
removed warnings
RedVeil May 16, 2024
e89298a
fixed owner keeper modifier
RedVeil May 16, 2024
1020914
added additional tests
RedVeil May 16, 2024
5986824
wip - test fixing
RedVeil May 17, 2024
6b10723
added push funds test
RedVeil May 17, 2024
adc4db7
adjusted tests further
RedVeil May 22, 2024
a197519
fixed minor paladin audit issues
RedVeil May 22, 2024
14a0fb3
CompoundV2 test fixed
RedVeil May 22, 2024
afed540
wip
RedVeil May 24, 2024
89087ad
Propose issue fix
Andreadinenno May 24, 2024
c3c1b05
CurveGaugeSingleAsset test fixed
RedVeil May 27, 2024
2ba8719
Merge pull request #171 from Popcorn-Limited/curveSingleAsset-test-fixes
RedVeil May 27, 2024
4fdc6f2
cleanup and audit improvements
RedVeil May 27, 2024
b7a83d3
WIP port audit fixes over
Andreadinenno May 27, 2024
b808a77
Complete refactor to v1.5
Andreadinenno May 28, 2024
afc384a
fixed test + formatting
RedVeil May 28, 2024
16f36c3
Merge branch 'feat/v-1.5' into feat/pendle-adapter
RedVeil May 28, 2024
178d6fa
Complete porting to v.1.5 syntax
Andreadinenno May 29, 2024
7a255b8
Audit fixes and optimizations
Andreadinenno May 29, 2024
ac4456b
Override max withdraw test
Andreadinenno May 29, 2024
9be6b7e
updated pendle with slippage protection
RedVeil May 30, 2024
c813556
added tests for vaults without strategies
RedVeil May 30, 2024
5ebdc60
duplicate verification multistrat
RedVeil May 31, 2024
bb99404
Pendle M-03 fix
RedVeil Jun 6, 2024
6a6de72
Add peapods strategies using UniV2 and Balancer Lp compounder
Andreadinenno Jun 10, 2024
9afc7f8
Use rew tokens state variable. Use decimals in UniV2 compounder
Andreadinenno Jun 13, 2024
8e9b443
Merge pull request #172 from Popcorn-Limited/feat/peapods-strategy
RedVeil Jun 14, 2024
8d2b07d
Merge pull request #166 from Popcorn-Limited/feat/pendle-adapter
RedVeil Jun 14, 2024
9260ea2
paladin audit improvements
RedVeil Jun 14, 2024
1deba6b
Merge branch 'feat/v-1.5' into audit/24-03
RedVeil Jun 14, 2024
50e7238
cleanup imports + formatting
RedVeil Jun 14, 2024
b0d73a7
Merge pull request #175 from Popcorn-Limited/audit/24-03
RedVeil Jun 14, 2024
d4daa16
included latest audit improvements
RedVeil Jun 17, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
40 changes: 40 additions & 0 deletions audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Audit

## General
Besides test fixes we refactored the strategy contracts significantly.
What was previously Adapters is now called strategies.
The delegatecalls to external strategies are removed. All logic is now in the strategy contract itself.
The `harvest`-function is now permissioned. We added a keeper role. `harvest` can be called by `keeper` or `owner`. Aura, Balancer use shared inherited contracts stored in `./src/peripheral` same with Curve and Convex contracts.
Fees are moved from the strategies to the MultiStrategyVault.
Additionally strategies can now have a toggle `autoDeposit`. This changes if users deposit directly into the underlying protocol of a strategy or simply send the funds into the strategy itself.
Two new functions have been added `pushFunds` and `pullFunds` these allow the `owner` to deposit or withdraw funds from the underlying protocol. These functions can be used in conjunction with `autoDeposit` to control slippage that users may suffer better. Both functions allow the `owner` to send arbitrary data to the call which can be used for slippage protection or other safety features.
We also removed the Gearbox Strategies from the audit since they still need more work and additionally dont provide anything useful after the recent GearboxV3 leverage feature.

## Ignored Issues
### Issue 1 - Governance Privileges
We will ignore this issue since its an issue of setup and configuration. Now with more permissioned functions in strategies this becomes a bigger issue and must be taken care of in the contract setup.

### Issue 4 - The implementation of the proxies can be initialized
Its not entirely clear yet if we will simply construct and init strategies or create factories so we will add `_disableInitializers()` if it becomes necessary

### Issue 10 - Missing parameters in the NewStrategiesProposed event
We will keep these events simple. The proposed strategies can be read when reading the contract state.

### Issue 13 - _protocolWithdraw should be called after _burn
While the issue might be correct if the underlying protocol is attackable via reentrancy we need to call `_protocolWithdraw` before `_burn` so we can use `totalSupply` and asset or share conversions in `_protocolWithdraw` without any issues.

## Improvement Explanations

### wstETH Looper contract
Other than the fixing the issues reported in the audit, different improvements have been added to the contract logic, especially in the `_protocolWithdraw` flow, where few edge cases would fail. For example:
- Withdrawing `totalAssets - 1`: the `debtToRepay` was underestimated and so the tx would have reverted since not enough debt was repaid before withdrawing in order to keep the CDP collateralised.
We decided to refactor the `debtToRepay` amount by using the `ratio` of collateral being withdrawn with respect to the total (minus debt and slippage), applying the same ratio to the debt calculation.

- Withdrawing `totalAssets` would revert with `ERC4626ExceededMaxWithdraw` error for 1 Wei. Probably being a rounding mismatch between our contract and OZ base ones, `totalAssets` was patched by returning 1 wei less than the calculated amount (when that is greater than 0).

- `_swapToWETH_` function, called in order to repay the flashLoan, where part of the pulled `wstETH` collateral is swapped to `WETH`. Since the flash loan would fail if the received `WETH` amount is lower than the repayment amount, we need to apply a buffer that would account for eventual slippage.
That naturally would lead to having some extra `ETH` floating in the contract after the swap, which is restaked into `wstETH` in order to have the sufficient amount the user is withdrawing.

Apart from that, we added measures to make sure eventual dust balance in the contract is accounted for and used at the first useful interaction, in particular:
- `wstETH` floating balance held by the strategy: immediately deposited and added as collateral in the `_redepositAsset` function, triggered when the `adjustLeverage` is called.
- `ETH` floating balance: taken into account before taking a flashLoan to increase the leverage, is similarly deposited as collateral.
357 changes: 357 additions & 0 deletions backup.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[profile.default]
libs = ['node_modules', "lib"]
fs_permissions = [{ access = "read-write", path = "./"}]
fs_permissions = [{ access = "read", path = "./"}]
verbosity = 2
fuzz_runs = 256
fuzz_max_global_rejects = 100000000
Expand Down
46 changes: 22 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,28 @@
{
"scripts": {
"anvil": "./script/anvil.sh",
"fund:usdc": "./script/fundUsdc.sh",
"fund:eCrv": "./script/fundECrv.sh",
"fund:pop": "./script/fundPop.sh",
"popStaking:fundOptimism": "./script/fundOpStaking.sh",
"demodata:vault": "forge script ./script/VaultDemoData.s.sol --rpc-url http://localhost:8545 --broadcast",
"deploy:vaultSystem": "forge script ./script/DeployVaultSystem.s.sol --rpc-url https://arb-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:feeRecipient": "forge script ./script/DeployFeeRecipientProxy.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy": "./script/deploy.sh",
"vault:ragequit": "forge script ./script/SetRageQuit.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:proposeAdapter": "forge script ./script/ProposeAdapter.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:swapAdapter": "forge script ./script/SwapAdapter.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:deploy": "forge script ./script/DeployVault.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:deployAdapter": "forge script ./script/DeployAdapter.s.sol --rpc-url https://arb-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:addTemplate": "forge script ./script/AddTemplate.s.sol --rpc-url https://arb-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:proposeVaultFees": "forge script ./script/ProposeVaultFees.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:setPermission": "forge script ./script/SetPermission.s.sol --rpc-url https://opt-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:initializeStrategy": "forge script ./script/InitializeStrategy.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:initializeVault": "forge script ./script/InitializeVault.s.sol --rpc-url https://arb-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:deployMultiStrategyVault": "forge script ./script/DeployMultiStrategyVault.s.sol --rpc-url https://arb-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"vault:setHarvestValues": "forge script ./script/SetHarvestValues.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"fees:move": "forge script ./script/MoveFees.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"verify": "./script/verifyContract.sh",
"verifyContractValues":"./script/verifyContractValues.sh",
"allocateFunds": "forge script ./script/AllocateFunds.s.sol --rpc-url https://arb-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast"
"allocateFunds": "forge script ./script/AllocateFunds.s.sol --rpc-url https://arb-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:vault": "forge script ./script/deploy/DeployMultiStrategyVault.s.sol --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:AaveV3Depositor": "forge script ./script/deploy/aave/AaveV3Depositor.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:AuraCompounder": "forge script ./script/deploy/aura/AuraCompounder.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:BalancerCompounder": "forge script ./script/deploy/balancer/BalancerCompounder.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:BeefyDepositor": "forge script ./script/deploy/beefy/BeefyDepositor.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:CompoundV2Depositor": "forge script ./script/deploy/compound/v2/CompoundV2Depositor.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:CompoundV3Depositor": "forge script ./script/deploy/compound/v3/CompoundV3Depositor.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:ConvexCompounder": "forge script ./script/deploy/convex/ConvexCompounder.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:CurveGaugeCompounder": "forge script ./script/deploy/curve/CurveGaugeCompounder.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:CurveGaugeSingleAssetCompounder": "forge script ./script/deploy/curve/CurveGaugeSingleAssetCompounder.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:GearboxLeverageAave": "forge script ./script/deploy/gearbox/leverageFarm/GearboxLeverageAave.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:GearboxLeverageBalancer": "forge script ./script/deploy/gearbox/leverageFarm/GearboxLeverageBalancer.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:GearboxLeverageCompound": "forge script ./script/deploy/gearbox/leverageFarm/GearboxLeverageCompound.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:GearboxLeverageConvexBaseRewardPool": "forge script ./script/deploy/gearbox/leverageFarm/GearboxLeverageConvexBaseRewardPool.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:GearboxLeverageConvexBooster": "forge script ./script/deploy/gearbox/leverageFarm/GearboxLeverageConvexBooster.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:GearboxLeverageCurve": "forge script ./script/deploy/gearbox/leverageFarm/GearboxLeverageCurve.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:GearboxLeverageLido": "forge script ./script/deploy/gearbox/leverageFarm/GearboxLeverageLido.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:GearboxLeverageWstETH": "forge script ./script/deploy/gearbox/leverageFarm/GearboxLeverageWstETH.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:GearboxLeverageYearn": "forge script ./script/deploy/gearbox/leverageFarm/GearboxLeverageYearn.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:IonDepositor": "forge script ./script/deploy/ion/IonDepositor.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast",
"deploy:WstETHLooper": "forge script ./script/deploy/lido/WstETHLooper.s.sol:DeployStrategy --rpc-url https://eth-mainnet.g.alchemy.com/v2/KsuP431uPWKR3KFb-K_0MT1jcwpUnjAg --broadcast"
},
"dependencies": {}
}
51 changes: 0 additions & 51 deletions script/AddTemplate.s.sol

This file was deleted.

2 changes: 0 additions & 2 deletions script/AllocateFunds.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ pragma solidity ^0.8.15;

import {Script} from "forge-std/Script.sol";
import {MultiStrategyVault, IERC4626, IERC20, Allocation} from "../src/vaults/MultiStrategyVault.sol";
import {IPermissionRegistry, Permission} from "../src/interfaces/vault/IPermissionRegistry.sol";
import {VaultController, IAdapter, VaultInitParams, VaultMetadata, IERC4626, IERC20} from "../src/vault/VaultController.sol";

contract AllocateFunds is Script {
Allocation[] internal allocations;
Expand Down
36 changes: 0 additions & 36 deletions script/DeployAdapter.s.sol

This file was deleted.

21 changes: 0 additions & 21 deletions script/DeployFeeRecipientProxy.s.sol

This file was deleted.

60 changes: 0 additions & 60 deletions script/DeployMultiStrategyVault.s.sol

This file was deleted.

Loading
Loading