Skip to content

Commit

Permalink
silo strategy initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
0xhokugava committed Feb 6, 2025
1 parent be267d7 commit 6892f32
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 5 deletions.
3 changes: 3 additions & 0 deletions chains/SonicLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {ALMPositionNameLib} from "../src/strategies/libs/ALMPositionNameLib.sol"
import {ALMLib} from "../src/strategies/libs/ALMLib.sol";
import {GammaUniswapV3MerklFarmStrategy} from "../src/strategies/GammaUniswapV3MerklFarmStrategy.sol";
import {SiloFarmStrategy} from "../src/strategies/SiloFarmStrategy.sol";
import {SiloStrategy} from "../src/strategies/SiloStrategy.sol";
import {ISiloIncentivesController} from "../src/integrations/silo/ISiloIncentivesController.sol";
import {IGaugeV3} from "../src/integrations/shadow/IGaugeV3.sol";
import {ALMShadowFarmStrategy} from "../src/strategies/ALMShadowFarmStrategy.sol";
Expand Down Expand Up @@ -224,6 +225,7 @@ library SonicLib {
// Silo
address public constant SILO_GAUGE_wS_008 = 0x0dd368Cd6D8869F2b21BA3Cb4fd7bA107a2e3752;
address public constant SILO_GAUGE_wS_020 = 0x2D3d269334485d2D876df7363e1A50b13220a7D8;
address public constant SILO_VAULT_USDC_20 = 0x322e1d5384aa4ED66AeCa770B95686271de61dc3;

// Gamma
address public constant GAMMA_UNISWAPV3_UNIPROXY = 0xcD5A60eb030300661cAf97244aE98e1D5A70f2c8;
Expand Down Expand Up @@ -342,6 +344,7 @@ library SonicLib {
_addStrategyLogic(factory, StrategyIdLib.GAMMA_UNISWAPV3_MERKL_FARM, address(new GammaUniswapV3MerklFarmStrategy()), true);
_addStrategyLogic(factory, StrategyIdLib.SILO_FARM, address(new SiloFarmStrategy()), true);
_addStrategyLogic(factory, StrategyIdLib.ALM_SHADOW_FARM, address(new ALMShadowFarmStrategy()), true);
_addStrategyLogic(factory, StrategyIdLib.SILO, address(new SiloStrategy()), false);
LogDeployLib.logDeployStrategies(platform, showLog);
//endregion

Expand Down
4 changes: 2 additions & 2 deletions src/strategies/SiloFarmStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contract SiloFarmStrategy is FarmingStrategyBase {
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

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

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INITIALIZATION */
Expand Down Expand Up @@ -127,7 +127,7 @@ contract SiloFarmStrategy is FarmingStrategyBase {

/// @inheritdoc IFarmingStrategy
function farmMechanics() external pure returns (string memory) {
return FarmMechanicsLib.CLASSIC;
return FarmMechanicsLib.AUTO;
}

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
Expand Down
117 changes: 117 additions & 0 deletions src/strategies/SiloStrategy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import "./base/ERC4626StrategyBase.sol";
import "./libs/StrategyIdLib.sol";
import "../integrations/silo/ISiloIncentivesController.sol";
import "../integrations/silo/ISilo.sol";

/// @title Earns APR by lending assets on Silo V2
/// @author 0xhokugava (https://github.com/0xhokugava)
contract SiloStrategy is ERC4626StrategyBase {
using SafeERC20 for IERC20;
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* CONSTANTS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

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

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INITIALIZATION */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @inheritdoc IStrategy
function initialize(address[] memory addresses, uint[] memory nums, int24[] memory ticks) public initializer {
if (addresses.length != 3 || nums.length != 0 || ticks.length != 0) {
revert IControllable.IncorrectInitParams();
}
__ERC4626StrategyBase_init(StrategyIdLib.SILO, addresses[0], addresses[1], addresses[2]);
}

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* VIEW FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @inheritdoc IStrategy
function strategyLogicId() public pure override returns (string memory) {
return StrategyIdLib.SILO;
}

/// @inheritdoc IStrategy
function extra() external pure returns (bytes32) {
return CommonLib.bytesToBytes32(abi.encodePacked(bytes3(0x00d395), bytes3(0x000000)));
}

Check warning

Code scanning / Slither

Too many digits Warning


/// @inheritdoc IStrategy
function description() external view returns (string memory) {
StrategyBaseStorage storage $base = _getStrategyBaseStorage();
return _genDesc($base._underlying);
}

/// @inheritdoc IStrategy
function getSpecificName() external pure override returns (string memory, bool) {
return ("", false);
}

/// @inheritdoc IStrategy
function supportedVaultTypes() external pure override returns (string[] memory types) {
types = new string[](1);
types[0] = VaultTypeLib.COMPOUNDING;
}

/// @inheritdoc IStrategy
function initVariants(address platform_)
public
view
returns (string[] memory variants, address[] memory addresses, uint[] memory nums, int24[] memory ticks)
{}

/// @inheritdoc IStrategy
function isHardWorkOnDepositAllowed() external pure returns (bool) {
return true;
}

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* STRATEGY BASE */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @inheritdoc ERC4626StrategyBase
//slither-disable-next-line unused-return
function _depositAssets(uint[] memory amounts, bool) internal override returns (uint value) {
StrategyBaseStorage storage $base = _getStrategyBaseStorage();
address u = $base._underlying;
ERC4626StrategyBaseStorage storage $ = _getERC4626StrategyBaseStorage();
if ($.lastSharePrice == 0) {
$.lastSharePrice = _getSharePrice(u);
}
ISilo siloVault = ISilo(u);
value = siloVault.deposit(amounts[0], address(this), ISilo.CollateralType.Collateral);
}

/// @inheritdoc ERC4626StrategyBase
//slither-disable-next-line unused-return
function _withdrawAssets(
address[] memory,
uint value,
address receiver
) internal virtual override returns (uint[] memory amountsOut) {
amountsOut = new uint[](1);
StrategyBaseStorage storage $base = _getStrategyBaseStorage();
amountsOut[0] = ISilo($base._underlying).withdraw(value, receiver, address(this), ISilo.CollateralType.Collateral);
}

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* INTERNAL LOGIC */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

function _genDesc(address silo) internal view returns (string memory) {
return string.concat(
"Earn ",
// CommonLib.implode(CommonLib.getSymbols(silo), ", "),
" and supply APR by lending ",
IERC20Metadata(ISilo(silo).asset()).symbol(),
" to Silo V2"
);
}
}
7 changes: 4 additions & 3 deletions src/strategies/base/ERC4626StrategyBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.8.23;

import "@openzeppelin/contracts/interfaces/IERC4626.sol";
import "./StrategyBase.sol";
import {console} from "forge-std/console.sol";

/// @notice Hold ERC4626 vault shares, emit APR and collect fees
/// @author Alien Deployer (https://github.com/a17)
Expand All @@ -14,7 +15,7 @@ abstract contract ERC4626StrategyBase is StrategyBase {
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @dev Version of ERC4626StrategyBase implementation
string public constant VERSION_ERC4626_STRATEGY_BASE = "1.0.0";
string public constant VERSION_ERC4626_STRATEGY_BASE = "1.0.1";

// keccak256(abi.encode(uint256(keccak256("erc7201:stability.ERC4626StrategyBase")) - 1)) & ~bytes32(uint256(0xff));
bytes32 private constant ERC4626_STRATEGY_BASE_STORAGE_LOCATION =
Expand Down Expand Up @@ -93,7 +94,7 @@ abstract contract ERC4626StrategyBase is StrategyBase {
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @inheritdoc StrategyBase
function _depositAssets(uint[] memory amounts, bool) internal override returns (uint value) {
function _depositAssets(uint[] memory amounts, bool) internal virtual override returns (uint value) {
StrategyBaseStorage storage $base = _getStrategyBaseStorage();
address u = $base._underlying;
value = IERC4626(u).deposit(amounts[0], address(this));
Expand Down Expand Up @@ -168,7 +169,7 @@ abstract contract ERC4626StrategyBase is StrategyBase {
address[] memory,
uint value,
address receiver
) internal override returns (uint[] memory amountsOut) {
) internal virtual override returns (uint[] memory amountsOut) {
amountsOut = new uint[](1);
StrategyBaseStorage storage __$__ = _getStrategyBaseStorage();
amountsOut[0] = IERC4626(__$__._underlying).redeem(value, receiver, address(this));
Expand Down
3 changes: 3 additions & 0 deletions src/strategies/libs/StrategyDeveloperLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ library StrategyDeveloperLib {
if (CommonLib.eq(strategyId, StrategyIdLib.ALM_SHADOW_FARM)) {
return 0x88888887C3ebD4a33E34a15Db4254C74C75E5D4A;
}
if (CommonLib.eq(strategyId, StrategyIdLib.SILO)) {
return 0xa12C4Bbe4D6eD65285f05328Bca4462Bf4808E53;
}
return address(0);
}
}
1 change: 1 addition & 0 deletions src/strategies/libs/StrategyIdLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ library StrategyIdLib {
string internal constant SWAPX_FARM = "SwapX Farm";
string internal constant SILO_FARM = "Silo Farm";
string internal constant ALM_SHADOW_FARM = "ALM Shadow Farm";
string internal constant SILO = "Silo";
}
27 changes: 27 additions & 0 deletions test/strategies/SILO.Sonic.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import "../base/chains/SonicSetup.sol";
import "../base/UniversalTest.sol";

contract SiloStrategyTest is SonicSetup, UniversalTest {
constructor() {
vm.selectFork(vm.createFork(vm.envString("SONIC_RPC_URL")));
vm.rollFork(6548098); // Feb-04-2025 03:31:56 PM +UTC
}

function testSiFSonic() public universalTest {
_addStrategy(SonicLib.SILO_VAULT_USDC_20);
}

function _addStrategy(address siloVault) internal {
strategies.push(
Strategy({
id: StrategyIdLib.SILO,
pool: address(0),
farmId: type(uint).max,
underlying: siloVault
})
);
}
}

0 comments on commit 6892f32

Please sign in to comment.