Skip to content

Commit

Permalink
skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
a17 committed Apr 11, 2024
1 parent e4de544 commit a1b806e
Showing 1 changed file with 275 additions and 0 deletions.
275 changes: 275 additions & 0 deletions src/strategies/CurveConvexFarmStrategy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import "./base/LPStrategyBase.sol";
import "./base/FarmingStrategyBase.sol";
import "./libs/StrategyIdLib.sol";
import "./libs/FarmMechanicsLib.sol";
import "../adapters/libs/AmmAdapterIdLib.sol";
import "../integrations/convex/IConvexRewardPool.sol";

/// @title Staking Curve LP to Convex
/// @author Alien Deployer (https://github.com/a17)
contract CurveConvexFarmStrategy is LPStrategyBase, FarmingStrategyBase {
using SafeERC20 for IERC20;

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

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

// keccak256(abi.encode(uint256(keccak256("erc7201:stability.CurveConvexFarmStrategy")) - 1)) & ~bytes32(uint256(0xff));
bytes32 private constant CURVE_CONVEX_FARM_STRATEGY_STORAGE_LOCATION =
0xe97e1b58b908486b9bee3f474a5533db9346238783d026373610f149c8ce1e00;

/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* DATA TYPES */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @custom:storage-location erc7201:stability.CurveConvexFarmStrategy
struct CurveConvexFarmStrategyStorage {
address booster;
uint pid;
}

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

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

Check warning on line 44 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L44

Added line #L44 was not covered by tests
}

IFactory.Farm memory farm = _getFarm(addresses[0], nums[0]);

Check warning on line 47 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L47

Added line #L47 was not covered by tests
if (farm.addresses.length != 1 || farm.nums.length != 0 || farm.ticks.length != 0) {
revert IFarmingStrategy.BadFarm();

Check warning on line 49 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L49

Added line #L49 was not covered by tests
}
CurveConvexFarmStrategyStorage storage $ = _getCurveConvexFarmStorage();
$.booster = IConvexRewardPool(farm.addresses[0]).convexBooster();
$.pid = IConvexRewardPool(farm.addresses[0]).convexPoolId();

Check warning on line 53 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L51-L53

Added lines #L51 - L53 were not covered by tests

__LPStrategyBase_init(

Check warning on line 55 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L55

Added line #L55 was not covered by tests
LPStrategyBaseInitParams({
id: StrategyIdLib.QUICKSWAP_STATIC_MERKL_FARM,
platform: addresses[0],
vault: addresses[1],
pool: farm.pool,
underlying: farm.addresses[0]
})
);

__FarmingStrategyBase_init(addresses[0], nums[0]);

Check warning on line 65 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L65

Added line #L65 was not covered by tests

address[] memory _assets = assets();
uint len = _assets.length;
for (uint i; i < len; ++i) {
IERC20(_assets[i]).forceApprove(farm.pool, type(uint).max);

Check warning on line 70 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L67-L70

Added lines #L67 - L70 were not covered by tests
}

IERC20(farm.pool).forceApprove($.booster, type(uint).max);

Check warning on line 73 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L73

Added line #L73 was not covered by tests
// console.logBytes32(keccak256(abi.encode(uint256(keccak256("erc7201:stability.CurveConvexFarmStrategy")) - 1)) & ~bytes32(uint256(0xff)));
}

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

/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId)
public
view
override(LPStrategyBase, FarmingStrategyBase)
returns (bool)
{
return super.supportsInterface(interfaceId);

Check warning on line 88 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L88

Added line #L88 was not covered by tests
}

/// @inheritdoc IFarmingStrategy
function canFarm() external view override returns (bool) {
IFactory.Farm memory farm = _getFarm();
return farm.status == 0;

Check warning on line 94 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L93-L94

Added lines #L93 - L94 were not covered by tests
}

/// @inheritdoc ILPStrategy
function ammAdapterId() public pure override returns (string memory) {
return AmmAdapterIdLib.CURVE;

Check warning on line 99 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L99

Added line #L99 was not covered by tests
}

/// @inheritdoc IStrategy
function getRevenue() external view returns (address[] memory __assets, uint[] memory amounts) {
__assets = new address[](0);
amounts = new uint[](0);

Check warning on line 105 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L104-L105

Added lines #L104 - L105 were not covered by tests
}

/// @inheritdoc IStrategy
function initVariants(address platform_)
public
view
returns (string[] memory variants, address[] memory addresses, uint[] memory nums, int24[] memory ticks)
{
IAmmAdapter _ammAdapter = IAmmAdapter(IPlatform(platform_).ammAdapter(keccak256(bytes(ammAdapterId()))).proxy);
addresses = new address[](0);
ticks = new int24[](0);

Check warning on line 116 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L114-L116

Added lines #L114 - L116 were not covered by tests

IFactory.Farm[] memory farms = IFactory(IPlatform(platform_).factory()).farms();
uint len = farms.length;

Check warning on line 119 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L118-L119

Added lines #L118 - L119 were not covered by tests
//slither-disable-next-line uninitialized-local
uint localTtotal;

Check warning on line 121 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L121

Added line #L121 was not covered by tests
// nosemgrep
for (uint i; i < len; ++i) {

Check warning on line 123 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L123

Added line #L123 was not covered by tests
// nosemgrep
IFactory.Farm memory farm = farms[i];

Check warning on line 125 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L125

Added line #L125 was not covered by tests
// nosemgrep
if (farm.status == 0 && CommonLib.eq(farm.strategyLogicId, strategyLogicId())) {
++localTtotal;

Check warning on line 128 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L128

Added line #L128 was not covered by tests
}

Check notice

Code scanning / Semgrep OSS

Semgrep Finding: rules.solidity.performance.use-nested-if Note

Using nested is cheaper than using && multiple check combinations.
There are more advantages, such as easier to read code and better coverage reports.
}

variants = new string[](localTtotal);
nums = new uint[](localTtotal);
localTtotal = 0;

Check warning on line 134 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L132-L134

Added lines #L132 - L134 were not covered by tests
// nosemgrep
for (uint i; i < len; ++i) {

Check warning on line 136 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L136

Added line #L136 was not covered by tests
// nosemgrep
IFactory.Farm memory farm = farms[i];

Check warning on line 138 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L138

Added line #L138 was not covered by tests
// nosemgrep
if (farm.status == 0 && CommonLib.eq(farm.strategyLogicId, strategyLogicId())) {
nums[localTtotal] = i;

Check warning on line 141 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L141

Added line #L141 was not covered by tests
//slither-disable-next-line calls-loop
variants[localTtotal] = _generateDescription(farm, _ammAdapter);
++localTtotal;

Check warning on line 144 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L143-L144

Added lines #L143 - L144 were not covered by tests
}

Check notice

Code scanning / Semgrep OSS

Semgrep Finding: rules.solidity.performance.use-nested-if Note

Using nested is cheaper than using && multiple check combinations.
There are more advantages, such as easier to read code and better coverage reports.
}
}

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

Check warning on line 151 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L151

Added line #L151 was not covered by tests
}

/// @inheritdoc IStrategy
function getAssetsProportions() external view returns (uint[] memory proportions) {
ILPStrategy.LPStrategyBaseStorage storage $lp = _getLPStrategyBaseStorage();
proportions = $lp.ammAdapter.getProportions($lp.pool);

Check warning on line 157 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L156-L157

Added lines #L156 - L157 were not covered by tests
}

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

Check warning on line 162 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L162

Added line #L162 was not covered by tests
}

Check warning

Code scanning / Slither

Too many digits Warning


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

Check warning on line 167 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L167

Added line #L167 was not covered by tests
}

/// @inheritdoc IStrategy
function description() external view returns (string memory) {
IFarmingStrategy.FarmingStrategyBaseStorage storage $f = _getFarmingStrategyBaseStorage();
ILPStrategy.LPStrategyBaseStorage storage $lp = _getLPStrategyBaseStorage();
IFactory.Farm memory farm = IFactory(IPlatform(platform()).factory()).farm($f.farmId);
return _generateDescription(farm, $lp.ammAdapter);

Check warning on line 175 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L172-L175

Added lines #L172 - L175 were not covered by tests
}

/// @inheritdoc IStrategy
function isHardWorkOnDepositAllowed() external pure returns (bool allowed) {
allowed = true;

Check warning on line 180 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L180

Added line #L180 was not covered by tests
}

/// @inheritdoc IStrategy
function isReadyForHardWork() external view returns (bool) {
return true;

Check warning on line 185 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L185

Added line #L185 was not covered by tests
}

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

Check warning on line 190 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L190

Added line #L190 was not covered by tests
}

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

/// @inheritdoc StrategyBase
function _depositAssets(uint[] memory amounts, bool claimRevenue) internal override returns (uint value) {
}

/// @inheritdoc StrategyBase
function _depositUnderlying(uint amount) internal override returns (uint[] memory amountsConsumed) {
}

/// @inheritdoc StrategyBase
function _withdrawAssets(uint value, address receiver) internal override returns (uint[] memory amountsOut) {
}

/// @inheritdoc StrategyBase
function _withdrawUnderlying(uint amount, address receiver) internal override {
}

/// @inheritdoc StrategyBase
function _claimRevenue()
internal
view
override
returns (
address[] memory __assets,
uint[] memory __amounts,
address[] memory __rewardAssets,
uint[] memory __rewardAmounts
)
{
}

/// @inheritdoc StrategyBase
function _compound() internal override {
}

/// @inheritdoc StrategyBase
function _previewDepositAssets(uint[] memory amountsMax)
internal
view
override(StrategyBase, LPStrategyBase)
returns (uint[] memory amountsConsumed, uint value)
{
}

/// @inheritdoc StrategyBase
function _previewDepositUnderlying(uint amount) internal view override returns (uint[] memory amountsConsumed) {
}

/// @inheritdoc StrategyBase
function _assetsAmounts() internal view override returns (address[] memory assets_, uint[] memory amounts_) {
}

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

function _generateDescription(
IFactory.Farm memory farm,
IAmmAdapter _ammAdapter
) internal view returns (string memory) {
//slither-disable-next-line calls-loop
return string.concat(

Check warning on line 257 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L257

Added line #L257 was not covered by tests
"Earn ",
//slither-disable-next-line calls-loop
CommonLib.implode(CommonLib.getSymbols(farm.rewardAssets), ", "),
" on Convex by ",
//slither-disable-next-line calls-loop
CommonLib.implode(CommonLib.getSymbols(_ammAdapter.poolTokens(farm.pool)), "-"),
" Curve LP"
);
}

function _getCurveConvexFarmStorage() internal pure returns (CurveConvexFarmStrategyStorage storage $) {
//slither-disable-next-line assembly
assembly {
$.slot := CURVE_CONVEX_FARM_STRATEGY_STORAGE_LOCATION

Check warning on line 271 in src/strategies/CurveConvexFarmStrategy.sol

View check run for this annotation

Codecov / codecov/patch

src/strategies/CurveConvexFarmStrategy.sol#L271

Added line #L271 was not covered by tests
}
}

}

0 comments on commit a1b806e

Please sign in to comment.