Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
3429327
Beefy support
acamill Jan 10, 2023
fc34674
TMP changes
acamill Jan 12, 2023
cc7ae67
TMP changs 2
acamill Jan 12, 2023
cb4ef3b
Tmp 3
acamill Jan 12, 2023
ca4ce67
Add Beefy Curve adapter
WarTech9 Mar 18, 2023
a00cd60
Merge branch 'develop' into integration/beefy-vault
WarTech9 Mar 18, 2023
f3f8250
Merge branch 'develop' into integration/beefy-vault
WarTech9 Mar 23, 2023
de6aad5
Implement BeefyCurveAdapter
WarTech9 Mar 23, 2023
97aec04
Implement deposits and withdrawal from Curve
WarTech9 Mar 23, 2023
394c028
Merge branch 'deploys' into integration/beefy-vault
WarTech9 Mar 23, 2023
70c9660
deploy Curve adapter
WarTech9 Mar 23, 2023
de11b31
Use fixed length arrays when interacting with Curve pool
WarTech9 Mar 25, 2023
f9e276d
Scripts to add and remove liquidity
WarTech9 Mar 25, 2023
d709426
add strategy adapter to Beefy depository
WarTech9 Mar 26, 2023
c850f10
Remove liquidity from Curve by coin amount
WarTech9 Mar 27, 2023
8adc545
Merge branch 'deploys' into integration/beefy-vault
WarTech9 Apr 13, 2023
10e06c7
Add adapter integration to beefy depository
WarTech9 Apr 14, 2023
4a909b7
Deploy beefy depository
WarTech9 Apr 14, 2023
f6988a3
Beefy Curve 2 pool deployment
WarTech9 Apr 16, 2023
8dc52b0
Merge branch 'develop' into integration/beefy-vault
WarTech9 May 4, 2023
55c5c5a
Can mint and redeem with Beefy/Curve. Work needed on numbers
WarTech9 May 8, 2023
e1400ed
Inefficient redeem
WarTech9 May 14, 2023
140252e
Optimized Beefy/Curve mint and redeem
WarTech9 May 16, 2023
d5bb93c
Clean up unused functions in CurveAdapter
WarTech9 May 16, 2023
14f12df
add beefy depository mocks
WarTech9 Jul 23, 2023
efd2f16
Beefy deployments
WarTech9 Jul 23, 2023
9128417
add oz file
WarTech9 Jul 23, 2023
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
3,440 changes: 3,440 additions & 0 deletions .openzeppelin/unknown-42161.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions addresses/arbitrumone/beefy_depository_impl.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

{
"depositoryImpl": "0x56b9d976870784b9DEbd37b44B286f9D88f2f059"
}

6 changes: 6 additions & 0 deletions addresses/arbitrumone/beefy_wrapper_factory.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

{
"wrapperFactory" : "0x1D1089968172B853975865c711E848bdcb44E7CC"
}


8 changes: 8 additions & 0 deletions addresses/arbitrumone/core_beefy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

{
"controller": "0x7a348A49B696aEB427aB0c1643890663a270BaC3",
"router": "0x9b7301052fcaE3EdBa276F9429428aB568018F4B",
"uxd": "0x2856806C1C373F79D06897AE88948224458d035C"
}


6 changes: 6 additions & 0 deletions addresses/arbitrumone/curve_adapter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

{
"curveAdapter": "0x7f5F2c30fE331D305739Fb8D9997b72A07532d93"
}


3 changes: 2 additions & 1 deletion addresses/arbitrumone/depositories.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

{
"rageTrade": "0xE1C92575BC45974Afe332a70045Dbb364A13E518"
"rageTrade": "0xE1C92575BC45974Afe332a70045Dbb364A13E518",
"beefyFinance": "0x1c619B6859607e6C14933721FB81D22C9885ce7d"
}


5 changes: 4 additions & 1 deletion config/arbitrumgoerli.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export const config: ArbitrumConfig = {
}
},
contracts: {
RageGmxSeniorVault: "0x8E6E5759Da804E63aCbed35fBbF9d9f9b8eeD8f8"
RageGmxSeniorVault: "0x8E6E5759Da804E63aCbed35fBbF9d9f9b8eeD8f8",
BeefyVaultUsdcUsdt: "",
Curve2PoolUsdcUsdt: ""
},
addresses: {
Deployer: "0x3382Bb7214c109f12Ffe8aA9C39BAf7eDB991427",
Expand All @@ -21,6 +23,7 @@ export const config: ArbitrumConfig = {
},
tokens: {
USDC: "0x6775842AE82BF2F0f987b10526768Ad89d79536E",
USDT: "",
WETH: "0xe39Ab88f8A4777030A534146A9Ca3B52bd5D43A3"
},
layerZero: {
Expand Down
5 changes: 4 additions & 1 deletion config/arbitrumone.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export const config: ArbitrumConfig = {
}
},
contracts: {
RageGmxSeniorVault: "0xf9305009FbA7E381b3337b5fA157936d73c2CF36"
RageGmxSeniorVault: "0xf9305009FbA7E381b3337b5fA157936d73c2CF36",
BeefyVaultUsdcUsdt: "0xEc7c0205a6f426c2Cb1667d783B5B4fD2f875434",
Curve2PoolUsdcUsdt: "0x7f90122BF0700F9E7e1F688fe926940E8839F353",
},
addresses: {
Deployer: "0x96223b32A75a22de7c192A1b99366c7eD12c1649",
Expand All @@ -22,6 +24,7 @@ export const config: ArbitrumConfig = {
},
tokens: {
USDC: "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8",
USDT: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
WETH: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"
},
layerZero: {
Expand Down
7 changes: 5 additions & 2 deletions config/configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export interface LzConfig {
current: LzPair
ethereum: LzPair
optimism: LzPair
arbitrum: LzPair
arbitrum: LzPair
}

export interface GovernorParams {
Expand Down Expand Up @@ -75,10 +75,13 @@ export interface ArbitrumConfig {
}
tokens: {
USDC: string
USDT: string
WETH: string
},
contracts: {
RageGmxSeniorVault: string
RageGmxSeniorVault: string
BeefyVaultUsdcUsdt: string
Curve2PoolUsdcUsdt: string
},
layerZero: LzConfig
}
10 changes: 5 additions & 5 deletions config/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,10 @@ export interface CoreContracts {
uxd: string
}

export interface Depositories {
perpetualProtocol?: string
rageTrade?: string
}

export interface Depositories {
perpetualProtocol?: string;
rageTrade?: string
beefyFinance?: string
}

export interface GovernanceContracts {
Expand All @@ -34,4 +30,8 @@ export interface DepositoryImplContract {

export interface PerpPeriphery {
accountProxy: string;
}

export interface Adapters {
curveAdapter: string
}
2 changes: 1 addition & 1 deletion config/goerli.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ export const config: EthereumConfig = {
endpoint: "0x6aB5Ae6822647046626e83ee6dB8187151E1d5ab"
}
}
}
}
219 changes: 219 additions & 0 deletions contracts/external/beefy/BeefyVaultV7.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol";

import "./IStrategyV7.sol";

/**
* @dev Implementation of a vault to deposit funds for yield optimizing.
* This is the contract that receives funds and that users interface with.
* The yield optimizing strategy itself is implemented in a separate 'Strategy.sol' contract.
*/
contract BeefyVaultV7 is
ERC20Upgradeable,
OwnableUpgradeable,
ReentrancyGuardUpgradeable
{
using SafeERC20Upgradeable for IERC20Upgradeable;

struct StratCandidate {
address implementation;
uint256 proposedTime;
}

// The last proposed strategy to switch to.
StratCandidate public stratCandidate;
// The strategy currently in use by the vault.
IStrategyV7 public strategy;
// The minimum time it has to pass before a strat candidate can be approved.
uint256 public approvalDelay;

event NewStratCandidate(address implementation);
event UpgradeStrat(address implementation);

/**
* @dev Sets the value of {token} to the token that the vault will
* hold as underlying value. It initializes the vault's own 'moo' token.
* This token is minted when someone does a deposit. It is burned in order
* to withdraw the corresponding portion of the underlying assets.
* @param _strategy the address of the strategy.
* @param _name the name of the vault token.
* @param _symbol the symbol of the vault token.
* @param _approvalDelay the delay before a new strat can be approved.
*/
function initialize(
IStrategyV7 _strategy,
string memory _name,
string memory _symbol,
uint256 _approvalDelay
) public initializer {
__ERC20_init(_name, _symbol);
__Ownable_init();
__ReentrancyGuard_init();
strategy = _strategy;
approvalDelay = _approvalDelay;
}

function want() public view returns (IERC20Upgradeable) {
return IERC20Upgradeable(strategy.want());
}

/**
* @dev It calculates the total underlying value of {token} held by the system.
* It takes into account the vault contract balance, the strategy contract balance
* and the balance deployed in other contracts as part of the strategy.
*/
function balance() public view returns (uint256) {
return
want().balanceOf(address(this)) + IStrategyV7(strategy).balanceOf();
}

/**
* @dev Custom logic in here for how much the vault allows to be borrowed.
* We return 100% of tokens for now. Under certain conditions we might
* want to keep some of the system funds at hand in the vault, instead
* of putting them to work.
*/
function available() public view returns (uint256) {
return want().balanceOf(address(this));
}

/**
* @dev Function for various UIs to display the current value of one of our yield tokens.
* Returns an uint256 with 18 decimals of how much underlying asset one vault share represents.
*/
function getPricePerFullShare() public view returns (uint256) {
return totalSupply() == 0 ? 1e18 : (balance() * 1e18) / totalSupply();
}

/**
* @dev A helper function to call deposit() with all the sender's funds.
*/
function depositAll() external {
deposit(want().balanceOf(msg.sender));
}

/**
* @dev The entrypoint of funds into the system. People deposit with this function
* into the vault. The vault is then in charge of sending funds into the strategy.
*/
function deposit(uint256 _amount) public nonReentrant {
strategy.beforeDeposit();

uint256 _pool = balance();
want().safeTransferFrom(msg.sender, address(this), _amount);
earn();
uint256 _after = balance();
_amount = _after - _pool; // Additional check for deflationary tokens
uint256 shares = 0;
if (totalSupply() == 0) {
shares = _amount;
} else {
shares = (_amount * totalSupply()) / _pool;
}
_mint(msg.sender, shares);
}

/**
* @dev Function to send funds into the strategy and put them to work. It's primarily called
* by the vault's deposit() function.
*/
function earn() public {
uint256 _bal = available();
want().safeTransfer(address(strategy), _bal);
strategy.deposit();
}

/**
* @dev A helper function to call withdraw() with all the sender's funds.
*/
function withdrawAll() external {
withdraw(balanceOf(msg.sender));
}

/**
* @dev Function to exit the system. The vault will withdraw the required tokens
* from the strategy and pay up the token holder. A proportional number of IOU
* tokens are burned in the process.
*/
function withdraw(uint256 _shares) public {
uint256 r = (balance() * _shares) / totalSupply();
_burn(msg.sender, _shares);

uint256 b = want().balanceOf(address(this));
if (b < r) {
uint256 _withdraw = r - b;
strategy.withdraw(_withdraw);
uint256 _after = want().balanceOf(address(this));
uint256 _diff = _after - b;
if (_diff < _withdraw) {
r = b + _diff;
}
}

want().safeTransfer(msg.sender, r);
}

/**
* @dev Sets the candidate for the new strat to use with this vault.
* @param _implementation The address of the candidate strategy.
*/
function proposeStrat(address _implementation) public onlyOwner {
require(
address(this) == IStrategyV7(_implementation).vault(),
"Proposal not valid for this Vault"
);
require(
want() == IStrategyV7(_implementation).want(),
"Different want"
);
stratCandidate = StratCandidate({
implementation: _implementation,
proposedTime: block.timestamp
});

emit NewStratCandidate(_implementation);
}

/**
* @dev It switches the active strat for the strat candidate. After upgrading, the
* candidate implementation is set to the 0x00 address, and proposedTime to a time
* happening in +100 years for safety.
*/

function upgradeStrat() public onlyOwner {
require(
stratCandidate.implementation != address(0),
"There is no candidate"
);
require(
stratCandidate.proposedTime + approvalDelay < block.timestamp,
"Delay has not passed"
);

emit UpgradeStrat(stratCandidate.implementation);

strategy.retireStrat();
strategy = IStrategyV7(stratCandidate.implementation);
stratCandidate.implementation = address(0);
stratCandidate.proposedTime = 5000000000;

earn();
}

/**
* @dev Rescues random funds stuck that the strat can't handle.
* @param _token address of the token to rescue.
*/
function inCaseTokensGetStuck(address _token) external onlyOwner {
require(_token != address(want()), "!token");

uint256 amount = IERC20Upgradeable(_token).balanceOf(address(this));
IERC20Upgradeable(_token).safeTransfer(msg.sender, amount);
}
}
Loading