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

Tetu V2 3.0.0 #60

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 1 addition & 1 deletion contracts/interfaces/ISplitter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface ISplitter {

function withdrawToVault(uint256 amount) external;

function coverPossibleStrategyLoss(uint earned, uint lost) external;
function registerStrategyLoss(uint earned, uint lost) external;

function doHardWork() external;

Expand Down
6 changes: 3 additions & 3 deletions contracts/interfaces/IStrategyV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ interface IStrategyV2 {
/// @dev Usually, indicate that claimable rewards have reasonable amount.
function isReadyToHardWork() external view returns (bool);

/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emited
function withdrawAllToSplitter() external returns (uint strategyLoss);

/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emited
function withdrawToSplitter(uint amount) external returns (uint strategyLoss);

/// @notice Stakes everything the strategy holds into the reward pool.
/// @param amount_ Amount transferred to the strategy balance just before calling this function
/// @param updateTotalAssetsBeforeInvest_ Recalculate total assets amount before depositing.
/// It can be false if we know exactly, that the amount is already actual.
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emited
function investAll(
uint amount_,
bool updateTotalAssetsBeforeInvest_
Expand Down
4 changes: 1 addition & 3 deletions contracts/interfaces/IStrategyV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ interface IStrategyV3 is IStrategyV2 {
/// @dev {DEFAULT_PERFORMANCE_FEE} by default, FEE_DENOMINATOR is used
uint performanceFee;

/// @notice Ratio to split performance fee on toPerf + toInsurance, [0..100_000]
/// 100_000 - send full amount toPerf, 0 - send full amount toInsurance.
uint performanceFeeRatio;
uint __deprecated;

/// @dev Percent of profit for autocompound inside this strategy.
uint compoundRatio;
Expand Down
12 changes: 0 additions & 12 deletions contracts/interfaces/ITetuVaultV2.sol
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

import "./IVaultInsurance.sol";
import "./IERC20.sol";
import "./ISplitter.sol";

interface ITetuVaultV2 {

function splitter() external view returns (ISplitter);

function insurance() external view returns (IVaultInsurance);

function depositFee() external view returns (uint);

function withdrawFee() external view returns (uint);

function init(
address controller_,
IERC20 _asset,
Expand All @@ -27,8 +19,4 @@ interface ITetuVaultV2 {

function setSplitter(address _splitter) external;

function coverLoss(uint amount) external;

function initInsurance(IVaultInsurance _insurance) external;

}
15 changes: 0 additions & 15 deletions contracts/interfaces/IVaultInsurance.sol

This file was deleted.

1 change: 0 additions & 1 deletion contracts/lib/InterfaceIds.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ library InterfaceIds {
bytes4 public constant I_PLATFORM_VOTER = bytes4(keccak256("IPlatformVoter"));
bytes4 public constant I_VE_DISTRIBUTOR = bytes4(keccak256("IVeDistributor"));
bytes4 public constant I_TETU_CONVERTER = bytes4(keccak256("ITetuConverter"));
bytes4 public constant I_VAULT_INSURANCE = bytes4(keccak256("IVaultInsurance"));
bytes4 public constant I_STRATEGY_STRICT = bytes4(keccak256("IStrategyStrict"));
bytes4 public constant I_ERC4626 = bytes4(keccak256("IERC4626"));

Expand Down
15 changes: 7 additions & 8 deletions contracts/strategy/StrategyBaseV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ abstract contract StrategyBaseV2 is IStrategyV2, ControllableV3 {
/// amount_ Amount transferred to the strategy balance just before calling this function
/// @param updateTotalAssetsBeforeInvest_ Recalculate total assets amount before depositing.
/// It can be false if we know exactly, that the amount is already actual.
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function investAll(
uint /*amount_*/,
bool updateTotalAssetsBeforeInvest_
Expand All @@ -151,7 +151,7 @@ abstract contract StrategyBaseV2 is IStrategyV2, ControllableV3 {
}

/// @dev Withdraws all underlying assets to the vault
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function withdrawAllToSplitter() external override returns (uint strategyLoss) {
address _splitter = splitter;
address _asset = asset;
Expand All @@ -171,7 +171,7 @@ abstract contract StrategyBaseV2 is IStrategyV2, ControllableV3 {
}

/// @dev Withdraws some assets to the splitter
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function withdrawToSplitter(uint amount) external override returns (uint strategyLoss) {
address _splitter = splitter;
address _asset = asset;
Expand All @@ -187,8 +187,7 @@ abstract contract StrategyBaseV2 is IStrategyV2, ControllableV3 {
_asset,
balance,
expectedWithdrewUSD,
assetPrice,
_splitter
assetPrice
);
}

Expand All @@ -212,7 +211,7 @@ abstract contract StrategyBaseV2 is IStrategyV2, ControllableV3 {
/// @notice Deposit given amount to the pool.
/// @param updateTotalAssetsBeforeInvest_ Recalculate total assets amount before depositing.
/// It can be false if we know exactly, that the amount is already actual.
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function _depositToPool(
uint amount,
bool updateTotalAssetsBeforeInvest_
Expand All @@ -223,7 +222,7 @@ abstract contract StrategyBaseV2 is IStrategyV2, ControllableV3 {
/// @dev Withdraw given amount from the pool.
/// @return expectedWithdrewUSD Sum of USD value of each asset in the pool that was withdrawn, decimals of {asset}.
/// @return assetPrice Price of the strategy {asset}.
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function _withdrawFromPool(uint amount) internal virtual returns (
uint expectedWithdrewUSD,
uint assetPrice,
Expand All @@ -233,7 +232,7 @@ abstract contract StrategyBaseV2 is IStrategyV2, ControllableV3 {
/// @dev Withdraw all from the pool.
/// @return expectedWithdrewUSD Sum of USD value of each asset in the pool that was withdrawn, decimals of {asset}.
/// @return assetPrice Price of the strategy {asset}.
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function _withdrawAllFromPool() internal virtual returns (
uint expectedWithdrewUSD,
uint assetPrice,
Expand Down
23 changes: 9 additions & 14 deletions contracts/strategy/StrategyBaseV3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ abstract contract StrategyBaseV3 is IStrategyV3, ControllableV3 {
return baseState.performanceFee;
}

function performanceFeeRatio() external view returns (uint) {
return baseState.performanceFeeRatio;
}

function strategySpecificName() external view returns (string memory) {
return baseState.strategySpecificName;
}
Expand Down Expand Up @@ -122,8 +118,8 @@ abstract contract StrategyBaseV3 is IStrategyV3, ControllableV3 {
// *************************************************************

/// @notice Set performance fee, receiver and ratio
function setupPerformanceFee(uint fee_, address receiver_, uint ratio_) external {
StrategyLib2.setupPerformanceFee(baseState, fee_, receiver_, ratio_, controller());
function setupPerformanceFee(uint fee_, address receiver_) external {
StrategyLib2.setupPerformanceFee(baseState, fee_, receiver_, controller());
}

// *************************************************************
Expand All @@ -134,7 +130,7 @@ abstract contract StrategyBaseV3 is IStrategyV3, ControllableV3 {
/// amount_ Amount transferred to the strategy balance just before calling this function
/// @param updateTotalAssetsBeforeInvest_ Recalculate total assets amount before depositing.
/// It can be false if we know exactly, that the amount is already actual.
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function investAll(
uint /*amount_*/,
bool updateTotalAssetsBeforeInvest_
Expand All @@ -151,7 +147,7 @@ abstract contract StrategyBaseV3 is IStrategyV3, ControllableV3 {
}

/// @dev Withdraws all underlying assets to the vault
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function withdrawAllToSplitter() external override returns (uint strategyLoss) {
address _splitter = baseState.splitter;
address _asset = baseState.asset;
Expand All @@ -171,7 +167,7 @@ abstract contract StrategyBaseV3 is IStrategyV3, ControllableV3 {
}

/// @dev Withdraws some assets to the splitter
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function withdrawToSplitter(uint amount) external override returns (uint strategyLoss) {
address _splitter = baseState.splitter;
address _asset = baseState.asset;
Expand All @@ -187,8 +183,7 @@ abstract contract StrategyBaseV3 is IStrategyV3, ControllableV3 {
_asset,
balance,
expectedWithdrewUSD,
assetPrice,
_splitter
assetPrice
);
}

Expand All @@ -212,7 +207,7 @@ abstract contract StrategyBaseV3 is IStrategyV3, ControllableV3 {
/// @notice Deposit given amount to the pool.
/// @param updateTotalAssetsBeforeInvest_ Recalculate total assets amount before depositing.
/// It can be false if we know exactly, that the amount is already actual.
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function _depositToPool(
uint amount,
bool updateTotalAssetsBeforeInvest_
Expand All @@ -223,7 +218,7 @@ abstract contract StrategyBaseV3 is IStrategyV3, ControllableV3 {
/// @dev Withdraw given amount from the pool.
/// @return expectedWithdrewUSD Sum of USD value of each asset in the pool that was withdrawn, decimals of {asset}.
/// @return assetPrice Price of the strategy {asset}.
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function _withdrawFromPool(uint amount) internal virtual returns (
uint expectedWithdrewUSD,
uint assetPrice,
Expand All @@ -233,7 +228,7 @@ abstract contract StrategyBaseV3 is IStrategyV3, ControllableV3 {
/// @dev Withdraw all from the pool.
/// @return expectedWithdrewUSD Sum of USD value of each asset in the pool that was withdrawn, decimals of {asset}.
/// @return assetPrice Price of the strategy {asset}.
/// @return strategyLoss Loss should be covered from Insurance
/// @return strategyLoss Loss should be checked and emitted
function _withdrawAllFromPool() internal virtual returns (
uint expectedWithdrewUSD,
uint assetPrice,
Expand Down
18 changes: 7 additions & 11 deletions contracts/strategy/StrategyLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ library StrategyLib {
// *************************************************************

/// @dev Denominator for fee calculation.
uint internal constant FEE_DENOMINATOR = 100_000;
uint internal constant DENOMINATOR = 100_000;

uint internal constant CHECK_WITHDRAW_IMPACT_TOLERANCE = 1_000;

// *************************************************************
// EVENTS
Expand All @@ -37,16 +39,14 @@ library StrategyLib {
string internal constant DENIED = "SB: Denied";
string internal constant TOO_HIGH = "SB: Too high";
string internal constant WRONG_VALUE = "SB: Wrong value";
/// @dev Denominator for compound ratio
uint internal constant COMPOUND_DENOMINATOR = 100_000;

// *************************************************************
// CHECKS AND EMITS
// *************************************************************

function _checkCompoundRatioChanged(address controller, uint oldValue, uint newValue) external {
onlyPlatformVoter(controller);
require(newValue <= COMPOUND_DENOMINATOR, TOO_HIGH);
require(newValue <= DENOMINATOR, TOO_HIGH);
emit CompoundRatioChanged(oldValue, newValue);
}

Expand Down Expand Up @@ -110,17 +110,14 @@ library StrategyLib {
address _asset,
uint balanceBefore,
uint expectedWithdrewUSD,
uint assetPrice,
address _splitter
uint assetPrice
) public view returns (uint balance) {
balance = IERC20(_asset).balanceOf(address(this));
if (assetPrice != 0 && expectedWithdrewUSD != 0) {

uint withdrew = balance > balanceBefore ? balance - balanceBefore : 0;
uint withdrewUSD = withdrew * assetPrice / 1e18;
uint priceChangeTolerance = ITetuVaultV2(ISplitter(_splitter).vault()).withdrawFee();
uint difference = expectedWithdrewUSD > withdrewUSD ? expectedWithdrewUSD - withdrewUSD : 0;
require(difference * FEE_DENOMINATOR / expectedWithdrewUSD <= priceChangeTolerance, TOO_HIGH);
require(difference * DENOMINATOR / expectedWithdrewUSD < CHECK_WITHDRAW_IMPACT_TOLERANCE, TOO_HIGH);
}
}

Expand Down Expand Up @@ -148,8 +145,7 @@ library StrategyLib {
_asset,
balanceBefore,
expectedWithdrewUSD,
assetPrice,
_splitter
assetPrice
);

if (balance != 0) {
Expand Down
30 changes: 12 additions & 18 deletions contracts/strategy/StrategyLib2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ library StrategyLib2 {
// *************************************************************

/// @dev Denominator for fee calculation.
uint internal constant FEE_DENOMINATOR = 100_000;
uint internal constant DENOMINATOR = 100_000;
/// @notice 10% of total profit is sent to {performanceReceiver} before compounding
uint internal constant DEFAULT_PERFORMANCE_FEE = 10_000;
address internal constant DEFAULT_PERF_FEE_RECEIVER = 0x9Cc199D4353b5FB3e6C8EEBC99f5139e0d8eA06b;
/// @dev Denominator for compound ratio
uint internal constant COMPOUND_DENOMINATOR = 100_000;
uint internal constant CHECK_WITHDRAW_IMPACT_TOLERANCE = 1_000;

// *************************************************************
// ERRORS
Expand All @@ -44,7 +43,7 @@ library StrategyLib2 {
event InvestAll(uint balance);
event WithdrawAllToSplitter(uint amount);
event WithdrawToSplitter(uint amount, uint sent, uint balance);
event PerformanceFeeChanged(uint fee, address receiver, uint ratio);
event PerformanceFeeChanged(uint fee, address receiver);

// *************************************************************
// CHECKS AND EMITS
Expand All @@ -61,12 +60,11 @@ library StrategyLib2 {
emit InvestAll(assetBalance);
}

function _checkSetupPerformanceFee(address controller, uint fee_, address receiver_, uint ratio_) internal {
function _checkSetupPerformanceFee(address controller, uint fee_, address receiver_) internal {
onlyGovernance(controller);
require(fee_ <= FEE_DENOMINATOR, TOO_HIGH);
require(fee_ <= DENOMINATOR, TOO_HIGH);
require(receiver_ != address(0), WRONG_VALUE);
require(ratio_ <= FEE_DENOMINATOR, TOO_HIGH);
emit PerformanceFeeChanged(fee_, receiver_, ratio_);
emit PerformanceFeeChanged(fee_, receiver_);
}

// *************************************************************
Expand All @@ -75,7 +73,7 @@ library StrategyLib2 {

function _changeCompoundRatio(IStrategyV3.BaseState storage baseState, address controller, uint newValue) external {
onlyPlatformVoterOrGov(controller);
require(newValue <= COMPOUND_DENOMINATOR, TOO_HIGH);
require(newValue <= DENOMINATOR, TOO_HIGH);

uint oldValue = baseState.compoundRatio;
baseState.compoundRatio = newValue;
Expand Down Expand Up @@ -129,11 +127,10 @@ library StrategyLib2 {
require(IControllable(splitter_).isController(controller_), WRONG_VALUE);
}

function setupPerformanceFee(IStrategyV3.BaseState storage baseState, uint fee_, address receiver_, uint ratio_, address controller_) external {
_checkSetupPerformanceFee(controller_, fee_, receiver_, ratio_);
function setupPerformanceFee(IStrategyV3.BaseState storage baseState, uint fee_, address receiver_, address controller_) external {
_checkSetupPerformanceFee(controller_, fee_, receiver_);
baseState.performanceFee = fee_;
baseState.performanceReceiver = receiver_;
baseState.performanceFeeRatio = ratio_;
}

/// @notice Calculate withdrawn amount in USD using the {assetPrice}.
Expand All @@ -146,17 +143,15 @@ library StrategyLib2 {
address _asset,
uint balanceBefore,
uint expectedWithdrewUSD,
uint assetPrice,
address _splitter
uint assetPrice
) public view returns (uint balance) {
balance = IERC20(_asset).balanceOf(address(this));
if (assetPrice != 0 && expectedWithdrewUSD != 0) {

uint withdrew = balance > balanceBefore ? balance - balanceBefore : 0;
uint withdrewUSD = withdrew * assetPrice / 1e18;
uint priceChangeTolerance = ITetuVaultV2(ISplitter(_splitter).vault()).withdrawFee();
uint difference = expectedWithdrewUSD > withdrewUSD ? expectedWithdrewUSD - withdrewUSD : 0;
require(difference * FEE_DENOMINATOR / expectedWithdrewUSD <= priceChangeTolerance, TOO_HIGH);
require(difference * DENOMINATOR / expectedWithdrewUSD < CHECK_WITHDRAW_IMPACT_TOLERANCE, TOO_HIGH);
}
}

Expand Down Expand Up @@ -184,8 +179,7 @@ library StrategyLib2 {
_asset,
balanceBefore,
expectedWithdrewUSD,
assetPrice,
_splitter
assetPrice
);

if (balance != 0) {
Expand Down
Loading
Loading