Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions chains/sonic/SonicConstantsLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ library SonicConstantsLib {
address public constant VAULT_C_USDC_SiMF_Greenhouse = 0x9443C25624c8ab74FaDE003bC76D2aC35244b925;
address public constant VAULT_C_WMETAUSD_USDC_121 = 0xe965c5114F689BF9184D9300F3af4A378c6934A9;
address public constant VAULT_C_WMETAUSD_scUSD_125 = 0x58D310a1A490f0daa86608998E08852630000151;
address public constant VAULT_C_WMETAS_wS_128 = 0xD44E7413134Ad3909c793C52cd242d99271f6570;

// metascUSD
address public constant VAULT_C_scUSD_S_46 = 0x14d17757e88Df8f59069fFa573570A50ed652866;
Expand Down
25 changes: 25 additions & 0 deletions src/integrations/silo/ISilo.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ interface ISilo is IERC4626 {
Collateral
}

/// @dev There are 3 types of accounting in the system: for non-borrowable collateral deposit called "protected",
/// for borrowable collateral deposit called "collateral" and for borrowed tokens called "debt". System does
/// identical calculations for each type of accounting but it uses different data. To avoid code duplication
/// this enum is used to decide which data should be read.
enum AssetType {
Protected, // default
Collateral,
Debt
}

/// @notice Implements IERC4626.deposit for protected (non-borrowable) collateral and collateral
/// @dev Reverts for debt asset type
function deposit(uint _assets, address _receiver, CollateralType collateralType) external returns (uint shares);
Expand Down Expand Up @@ -68,4 +78,19 @@ interface ISilo is IERC4626 {
function maxRepay(address _borrower) external view returns (uint assets);

function getLiquidity() external view returns (uint256 liquidity);

/// @notice Implements IERC4626.maxRedeem for protected (non-borrowable) collateral and collateral
/// @dev Reverts for debt asset type
function maxRedeem(address _owner, CollateralType _collateralType) external view returns (uint256 maxShares);

/// @notice Implements IERC4626.maxWithdraw for protected (non-borrowable) collateral and collateral
/// @dev Reverts for debt asset type
function maxWithdraw(address _owner, CollateralType _collateralType) external view returns (uint256 maxAssets);

/// @notice Calculates the maximum number of shares that can be repaid for a given borrower
/// @param _borrower Address of the borrower
/// @return shares The maximum number of shares that can be repaid for the borrower
function maxRepayShares(address _borrower) external view returns (uint256 shares);

function convertToAssets(uint256 _shares, AssetType _assetType) external view returns (uint256 assets);
}
9 changes: 7 additions & 2 deletions src/strategies/CompoundV2Strategy.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {console} from "forge-std/console.sol";
import {CommonLib} from "../core/libs/CommonLib.sol";
import {IComptroller} from "../integrations/compoundv2/IComptroller.sol";
import {IControllable} from "../interfaces/IControllable.sol";
Expand All @@ -21,6 +22,8 @@ import {VaultTypeLib} from "../core/libs/VaultTypeLib.sol";

/// @title Earns APR by lending assets on Compound V2 protocol.
/// @author dvpublic (https://github.com/dvpublic)
/// Change log:
/// - 1.0.1: maxWithdrawAssets allows to withdraw 99.5% of the available liquidity only
contract CompoundV2Strategy is StrategyBase {
using SafeERC20 for IERC20;

Expand All @@ -29,7 +32,7 @@ contract CompoundV2Strategy is StrategyBase {
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @inheritdoc IControllable
string public constant VERSION = "1.0.0";
string public constant VERSION = "1.0.1";

// keccak256(abi.encode(uint256(keccak256("erc7201:stability.CompoundV2Strategy")) - 1)) & ~bytes32(uint256(0xff));
bytes32 private constant COMPOUND_V2_STRATEGY_STORAGE_LOCATION =
Expand Down Expand Up @@ -183,6 +186,7 @@ contract CompoundV2Strategy is StrategyBase {

/// @inheritdoc IStrategy
function maxWithdrawAssets() public view override returns (uint[] memory amounts) {
console.log("CompoundV2Strategy.maxWithdrawAssets");
address _underlying = _getStrategyBaseStorage()._underlying;
address asset = IVToken(_underlying).underlying();

Expand All @@ -193,9 +197,10 @@ contract CompoundV2Strategy is StrategyBase {
uint cTokenBalance = IVToken(_underlying).balanceOf(address(this)); // 8 decimals
uint exchangeRate = IVToken(_underlying).exchangeRateStored(); // underlying decimals * 1e18 / 1e8
uint underlyingBalance = _tokensToAmount(cTokenBalance, exchangeRate);
uint totalReserves = IVToken(_underlying).totalReserves();

amounts = new uint[](1);
amounts[0] = Math.min(underlyingBalance, availableLiquidity);
amounts[0] = Math.min(underlyingBalance, (availableLiquidity - totalReserves) * 995 / 1000); // 99.5% of the available liquidity
}

/// @notice IStrategy
Expand Down
51 changes: 45 additions & 6 deletions src/strategies/SiloALMFStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {IWrappedMetaVault} from "../interfaces/IWrappedMetaVault.sol";

/// @title Silo V2 advanced leverage Merkl farm strategy
/// Changelog:
/// 1.2.0: Change deposit type to "non-borrowable collateral deposit", add reDeposit
/// 1.1.0: Each write operation caches prices of MetaUSD - #348
/// 1.0.1: Use new version of setLastBlockDefenseDisabledTx
/// 1.0.0: Initial version - #330
Expand All @@ -61,7 +62,7 @@ contract SiloALMFStrategy is
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @inheritdoc IControllable
string public constant VERSION = "1.1.0";
string public constant VERSION = "1.2.0";

//region ----------------------------------- Initialization
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
Expand Down Expand Up @@ -148,25 +149,25 @@ contract SiloALMFStrategy is
) external {
// Flash loan is performed upon deposit and withdrawal
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage();
SiloALMFLib.receiveFlashLoanBalancerV2(platform(), $, tokens, amounts, feeAmounts);
SiloALMFLib2.receiveFlashLoanBalancerV2(platform(), $, tokens, amounts, feeAmounts);
}

/// @inheritdoc IBalancerV3FlashCallback
function receiveFlashLoanV3(address token, uint amount, bytes memory /*userData*/ ) external {
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage();
SiloALMFLib.receiveFlashLoanV3(platform(), $, token, amount);
SiloALMFLib2.receiveFlashLoanV3(platform(), $, token, amount);
}

/// @inheritdoc IUniswapV3FlashCallback
function uniswapV3FlashCallback(uint fee0, uint fee1, bytes calldata userData) external {
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage();
SiloALMFLib.uniswapV3FlashCallback(platform(), $, fee0, fee1, userData);
SiloALMFLib2.uniswapV3FlashCallback(platform(), $, fee0, fee1, userData);
}

/// @inheritdoc IAlgebraFlashCallback
function algebraFlashCallback(uint fee0, uint fee1, bytes calldata userData) external {
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage();
SiloALMFLib.uniswapV3FlashCallback(platform(), $, fee0, fee1, userData);
SiloALMFLib2.uniswapV3FlashCallback(platform(), $, fee0, fee1, userData);
}
//endregion ----------------------------------- Flash loan

Expand Down Expand Up @@ -202,7 +203,7 @@ contract SiloALMFStrategy is

/// @inheritdoc IStrategy
function getSpecificName() external view override returns (string memory, bool) {
return SiloALMFLib.getSpecificName(_getLeverageLendingBaseStorage());
return SiloALMFLib2.getSpecificName(_getLeverageLendingBaseStorage());
}

/// @inheritdoc ILeverageLendingStrategy
Expand Down Expand Up @@ -266,6 +267,8 @@ contract SiloALMFStrategy is
function _rebalanceDebt(uint newLtv) internal override returns (uint resultLtv) {
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage();

require(!isPaused(), SiloALMFLib.Paused());

SiloALMFLib.prepareWriteOp(platform(), $.collateralAsset);
resultLtv = SiloALMFLib.rebalanceDebt(platform(), newLtv, $);
SiloALMFLib.unprepareWriteOp(platform(), $.collateralAsset);
Expand Down Expand Up @@ -299,6 +302,8 @@ contract SiloALMFStrategy is
{
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage();

require(!isPaused(), SiloALMFLib.Paused());

SiloALMFLib.prepareWriteOp(platform(), $.collateralAsset);
__assets = assets();
(__amounts, __rewardAssets, __rewardAmounts) =
Expand All @@ -324,6 +329,8 @@ contract SiloALMFStrategy is
StrategyBaseStorage storage $base = _getStrategyBaseStorage();
address[] memory _assets = assets();

require(!isPaused(), SiloALMFLib.Paused());

SiloALMFLib.prepareWriteOp(platform(), $.collateralAsset);
value = SiloALMFLib.depositAssets($, $base, amounts[0], _assets[0]);
SiloALMFLib.unprepareWriteOp(platform(), $.collateralAsset);
Expand All @@ -334,6 +341,8 @@ contract SiloALMFStrategy is
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage();
StrategyBaseStorage storage $base = _getStrategyBaseStorage();

require(!isPaused(), SiloALMFLib.Paused());

SiloALMFLib.prepareWriteOp(platform(), $.collateralAsset);
amountsOut = SiloALMFLib.withdrawAssets(platform(), $, $base, value, receiver);
SiloALMFLib.unprepareWriteOp(platform(), $.collateralAsset);
Expand Down Expand Up @@ -389,4 +398,34 @@ contract SiloALMFStrategy is
}

//endregion ----------------------------------- FarmingStrategy

//region ----------------------------------- Additional temporally functions
function isPaused() public view returns (bool) {
// todo probably we need flag Paused in the storage
return totalCollateralToRedeposit() != 0;
}

/// @dev True if there is no deposit of "collateral type"
function totalCollateralToRedeposit() public view returns (uint) {
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage();
return SiloALMFLib.totalCollateralToRedeposit($.lendingVault);
}

/// @notice Withdraw {value_} of Collateral and re-deposit it as Protected collateral
/// @dev To cover losses put amount of collateral on the strategy balance and call redeposit(1)
/// @param amount_ Amount of collateral to withdraw
/// @param opKind_ 0 - withdraw, 1 - deposit
function reDeposit(uint opKind_, uint amount_) external onlyOperator {
address _platform = platform();
LeverageLendingBaseStorage storage $ = _getLeverageLendingBaseStorage();
address collateralAsset = $.collateralAsset;

require(totalCollateralToRedeposit() != 0 || opKind_ != 0, IControllable.TooLowValue(0));

SiloALMFLib.prepareWriteOp(_platform, collateralAsset);
SiloALMFLib.reDeposit($, amount_, opKind_);
SiloALMFLib.unprepareWriteOp(_platform, collateralAsset);
}

//endregion ----------------------------------- Additional temporally functions
}
Loading
Loading