Skip to content

Commit

Permalink
Merge pull request #111 from stabilitydao/110-dev-curve-convex-farm
Browse files Browse the repository at this point in the history
Curve Convex Farm
  • Loading branch information
DevTeaLeaf authored Apr 13, 2024
2 parents 3b5618b + 458291f commit 34868d0
Show file tree
Hide file tree
Showing 17 changed files with 756 additions and 98 deletions.
93 changes: 70 additions & 23 deletions chains/PolygonLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import "../src/strategies/libs/ALMPositionNameLib.sol";
import "../src/interfaces/IFactory.sol";
import "../src/interfaces/IPlatform.sol";
import "../src/interfaces/ISwapper.sol";
import "../src/integrations/convex/IConvexRewardPool.sol";
import "../script/libs/DeployLib.sol";
import "../script/libs/DeployAdapterLib.sol";
import "../script/libs/DeployStrategyLib.sol";
Expand Down Expand Up @@ -37,6 +38,7 @@ library PolygonLib {
address public constant TOKEN_oRETRO = 0x3A29CAb2E124919d14a6F735b6033a3AaD2B260F;
address public constant TOKEN_CASH = 0x5D066D022EDE10eFa2717eD3D79f22F949F8C175;
address public constant TOKEN_crvUSD = 0xc4Ce1D6F5D98D65eE25Cf85e9F2E9DcFEe6Cb5d6;
address public constant TOKEN_CRV = 0x172370d5Cd63279eFa6d502DAB29171933a610AF;

// ERC21
address public constant TOKEN_PM = 0xAA3e3709C79a133e56C17a7ded87802adF23083B;
Expand Down Expand Up @@ -72,6 +74,7 @@ library PolygonLib {
address public constant POOL_QUICKSWAPV3_USDC_WETH = 0xa6AeDF7c4Ed6e821E67a6BfD56FD1702aD9a9719;
address public constant POOL_QUICKSWAPV3_WMATIC_USDC = 0x6669B4706cC152F359e947BCa68E263A87c52634;
address public constant POOL_QUICKSWAPV3_USDC_DAI = 0xBC8f3da0bd42E1F2509cd8671Ce7c7E5f7fd39c8;
address public constant POOL_QUICKSWAPV3_CRV_WMATIC = 0x00A6177C6455A29B8dAa7144B2bEfc9F2147BB7E;
address public constant POOL_KYBER_USDCe_USDT = 0x879664ce5A919727b3Ed4035Cf12F7F740E8dF00;
address public constant POOL_KYBER_USDCe_DAI = 0x02A3E4184b145eE64A6Df3c561A3C0c6e2f23DFa;
address public constant POOL_KYBER_KNC_USDCe = 0x4B440a7DE0Ab7041934d0c171849A76CC33234Fa;
Expand All @@ -84,6 +87,9 @@ library PolygonLib {
address public constant POOL_RETRO_USDCe_CASH_100 = 0x619259F699839dD1498FFC22297044462483bD27;
address public constant POOL_RETRO_CASH_RETRO_10000 = 0xb47A07966cE6812702C0567d03725F1b37E27877;
address public constant POOL_CURVE_crvUSD_USDCe = 0x864490Cf55dc2Dee3f0ca4D06F5f80b2BB154a03;
address public constant POOL_CURVE_crvUSD_USDT = 0xA70Af99bFF6b168327f9D1480e29173e757c7904;
address public constant POOL_CURVE_crvUSD_DAI = 0x62c949ee985b125Ff2d7ddcf4Fe7AEcB0a040E2a;
address public constant POOL_CURVE_crvUSD_USDC = 0x5225010A0AE133B357861782B0B865a48471b2C5;

// Gelato
address public constant GELATO_AUTOMATE = 0x527a819db1eb0e34426297b03bae11F2f8B3A19E;
Expand Down Expand Up @@ -140,6 +146,13 @@ library PolygonLib {
// Retro
address public constant RETRO_QUOTER = 0xddc9Ef56c6bf83F7116Fad5Fbc41272B07ac70C1;

// Convex
address public constant CONVEX_BOOSTER = 0xddc9Ef56c6bf83F7116Fad5Fbc41272B07ac70C1;
address public constant CONVEX_REWARD_POOL_crvUSD_USDCe = 0xBFEE9F3E015adC754066424AEd535313dc764116;
address public constant CONVEX_REWARD_POOL_crvUSD_USDT = 0xd2D8BEB901f90163bE4667A85cDDEbB7177eb3E3;
address public constant CONVEX_REWARD_POOL_crvUSD_DAI = 0xaCb744c7e7C95586DB83Eda3209e6483Fb1FCbA4;
address public constant CONVEX_REWARD_POOL_crvUSD_USDC = 0x11F2217fa1D5c44Eae310b9b985E2964FC47D8f9;

function runDeploy(bool showLog) internal returns (address platform) {
//region ----- DeployPlatform -----
uint[] memory buildingPrice = new uint[](3);
Expand Down Expand Up @@ -199,16 +212,12 @@ library PolygonLib {
{
(ISwapper.AddPoolData[] memory bcPools, ISwapper.AddPoolData[] memory pools) = routes();
ISwapper.AddPoolData[] memory pools2 = routes2();
ISwapper.AddPoolData[] memory pools3 = routes3();
ISwapper.AddPoolData[] memory pools4 = routes4();
ISwapper swapper = ISwapper(IPlatform(platform).swapper());
swapper.addBlueChipsPools(bcPools, false);
swapper.addPools(pools, false);
swapper.addPools(pools2, false);
swapper.addPools(pools3, false);
swapper.addPools(pools4, false);
// todo auto thresholds
address[] memory tokenIn = new address[](8);
address[] memory tokenIn = new address[](10);
tokenIn[0] = TOKEN_USDCe;
tokenIn[1] = TOKEN_USDT;
tokenIn[2] = TOKEN_DAI;
Expand All @@ -217,7 +226,9 @@ library PolygonLib {
tokenIn[5] = TOKEN_dQUICK;
tokenIn[6] = TOKEN_USDC;
tokenIn[7] = TOKEN_COMP;
uint[] memory thresholdAmount = new uint[](8);
tokenIn[8] = TOKEN_CRV;
tokenIn[9] = TOKEN_crvUSD;
uint[] memory thresholdAmount = new uint[](10);
thresholdAmount[0] = 1e3;
thresholdAmount[1] = 1e3;
thresholdAmount[2] = 1e15;
Expand All @@ -226,6 +237,8 @@ library PolygonLib {
thresholdAmount[5] = 1e16; // 1 dQuick ~= $0.05
thresholdAmount[6] = 1e3;
thresholdAmount[7] = 1e15;
thresholdAmount[8] = 1e15;
thresholdAmount[9] = 1e15;
swapper.setThresholds(tokenIn, thresholdAmount);
DeployLib.logSetupSwapper(platform, showLog);
}
Expand All @@ -242,6 +255,7 @@ library PolygonLib {
if (block.number > 54573098) {
// Mar-12-2024 02:41:42 PM +UTC
factory.addFarms(farms7());
factory.addFarms(farms8());
}
DeployLib.logAddedFarms(address(factory), showLog);
//endregion -- Add farms -----
Expand All @@ -266,6 +280,7 @@ library PolygonLib {
DeployStrategyLib.deployStrategy(platform, StrategyIdLib.ICHI_QUICKSWAP_MERKL_FARM, true);
DeployStrategyLib.deployStrategy(platform, StrategyIdLib.ICHI_RETRO_MERKL_FARM, true);
DeployStrategyLib.deployStrategy(platform, StrategyIdLib.GAMMA_RETRO_MERKL_FARM, true);
DeployStrategyLib.deployStrategy(platform, StrategyIdLib.CURVE_CONVEX_FARM, true);
DeployLib.logDeployStrategies(platform, showLog);
//endregion -- Deploy strategy logics -----

Expand Down Expand Up @@ -386,61 +401,60 @@ library PolygonLib {
//endregion -- Pools ----
}

/// @notice New routes jan-2024
function routes2() public pure returns (ISwapper.AddPoolData[] memory pools) {
pools = new ISwapper.AddPoolData[](1);
pools = new ISwapper.AddPoolData[](8);
uint i;
// New routes jan-2024
pools[i++] = ISwapper.AddPoolData({
pool: POOL_QUICKSWAPV3_USDCe_USDC,
ammAdapterId: AmmAdapterIdLib.ALGEBRA,
tokenIn: TOKEN_USDC,
tokenOut: TOKEN_USDCe
});
}

/// @notice New routes jan-2024
function routes3() public pure returns (ISwapper.AddPoolData[] memory pools) {
pools = new ISwapper.AddPoolData[](2);
uint i;
pools[i++] = ISwapper.AddPoolData({
pool: POOL_UNISWAPV3_WETH_COMP_3000,
ammAdapterId: AmmAdapterIdLib.UNISWAPV3,
tokenIn: TOKEN_COMP,
tokenOut: TOKEN_WETH
});

pools[i++] = ISwapper.AddPoolData({
pool: POOL_UNISWAPV3_ICHI_WMATIC_100,
ammAdapterId: AmmAdapterIdLib.UNISWAPV3,
tokenIn: TOKEN_ICHI,
tokenOut: TOKEN_WMATIC
});
}

// routes for RETRO strategies
function routes4() public pure returns (ISwapper.AddPoolData[] memory pools) {
pools = new ISwapper.AddPoolData[](3);
uint i;
// routes for RETRO strategies
pools[i++] = ISwapper.AddPoolData({
pool: POOL_RETRO_USDCe_RETRO_10000,
ammAdapterId: AmmAdapterIdLib.UNISWAPV3,
tokenIn: TOKEN_RETRO,
tokenOut: TOKEN_USDCe
});

pools[i++] = ISwapper.AddPoolData({
pool: POOL_RETRO_oRETRO_RETRO_10000,
ammAdapterId: AmmAdapterIdLib.UNISWAPV3,
tokenIn: TOKEN_oRETRO,
tokenOut: TOKEN_RETRO
});

pools[i++] = ISwapper.AddPoolData({
pool: POOL_RETRO_USDCe_CASH_100,
ammAdapterId: AmmAdapterIdLib.UNISWAPV3,
tokenIn: TOKEN_CASH,
tokenOut: TOKEN_USDCe
});
// crvUSD
pools[i++] = ISwapper.AddPoolData({
pool: POOL_CURVE_crvUSD_USDCe,
ammAdapterId: AmmAdapterIdLib.CURVE,
tokenIn: TOKEN_crvUSD,
tokenOut: TOKEN_USDCe
});
pools[i++] = ISwapper.AddPoolData({
pool: POOL_QUICKSWAPV3_CRV_WMATIC,
ammAdapterId: AmmAdapterIdLib.ALGEBRA,
tokenIn: TOKEN_CRV,
tokenOut: TOKEN_WMATIC
});
}

function farms() public view returns (IFactory.Farm[] memory _farms) {
Expand Down Expand Up @@ -708,6 +722,39 @@ library PolygonLib {
_farms[i++] = _makeGammaQuickSwapMerklFarm(GAMMA_QUICKSWAP_WMATIC_USDC_NARROW, ALMPositionNameLib.NARROW);
}

function farms8() public view returns (IFactory.Farm[] memory _farms) {
_farms = new IFactory.Farm[](4);
uint i;

// [34]
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDCe, CONVEX_REWARD_POOL_crvUSD_USDCe);
// [35]
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDT, CONVEX_REWARD_POOL_crvUSD_USDT);
// [36]
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_DAI, CONVEX_REWARD_POOL_crvUSD_DAI);
// [37]
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDC, CONVEX_REWARD_POOL_crvUSD_USDC);
}

function _makeCurveConvexFarm(address curvePool, address convexRewardPool) internal view returns (IFactory.Farm memory) {
IFactory.Farm memory farm;
uint rewardTokensLength = IConvexRewardPool(convexRewardPool).rewardLength();
farm.status = 0;
// pool address can be extracted from convexRewardPool here: curveGauge() -> lp_token()
farm.pool = curvePool;
farm.strategyLogicId = StrategyIdLib.CURVE_CONVEX_FARM;
farm.rewardAssets = new address[](rewardTokensLength);
for (uint i; i < rewardTokensLength; ++i) {
IConvexRewardPool.RewardType memory r = IConvexRewardPool(convexRewardPool).rewards(i);
farm.rewardAssets[i] = r.reward_token;
}
farm.addresses = new address[](1);
farm.addresses[0] = convexRewardPool;
farm.nums = new uint[](0);
farm.ticks = new int24[](0);
return farm;
}

function _makeGammaQuickSwapMerklFarm(
address hypervisor,
uint preset
Expand Down
118 changes: 118 additions & 0 deletions script/DeployStrategyCCF.Polygon.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import "forge-std/Script.sol";
import "../src/core/proxy/Proxy.sol";
import "../src/adapters/CurveAdapter.sol";
import "../src/strategies/CurveConvexFarmStrategy.sol";

contract DeployStrategyCCFPolygon is Script {
address public constant PLATFORM = 0xb2a0737ef27b5Cc474D24c779af612159b1c3e60;
address public constant POOL_CURVE_crvUSD_USDCe = 0x864490Cf55dc2Dee3f0ca4D06F5f80b2BB154a03;
address public constant POOL_CURVE_crvUSD_USDT = 0xA70Af99bFF6b168327f9D1480e29173e757c7904;
address public constant POOL_CURVE_crvUSD_DAI = 0x62c949ee985b125Ff2d7ddcf4Fe7AEcB0a040E2a;
address public constant POOL_CURVE_crvUSD_USDC = 0x5225010A0AE133B357861782B0B865a48471b2C5;
address public constant POOL_QUICKSWAPV3_CRV_WMATIC = 0x00A6177C6455A29B8dAa7144B2bEfc9F2147BB7E;
address public constant TOKEN_crvUSD = 0xc4Ce1D6F5D98D65eE25Cf85e9F2E9DcFEe6Cb5d6;
address public constant TOKEN_CRV = 0x172370d5Cd63279eFa6d502DAB29171933a610AF;
address public constant TOKEN_WMATIC = 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270;
address public constant TOKEN_USDCe = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174;
address public constant CONVEX_REWARD_POOL_crvUSD_USDCe = 0xBFEE9F3E015adC754066424AEd535313dc764116;
address public constant CONVEX_REWARD_POOL_crvUSD_USDT = 0xd2D8BEB901f90163bE4667A85cDDEbB7177eb3E3;
address public constant CONVEX_REWARD_POOL_crvUSD_DAI = 0xaCb744c7e7C95586DB83Eda3209e6483Fb1FCbA4;
address public constant CONVEX_REWARD_POOL_crvUSD_USDC = 0x11F2217fa1D5c44Eae310b9b985E2964FC47D8f9;
address public constant DEV = 0x88888887C3ebD4a33E34a15Db4254C74C75E5D4A;

function run() external {
// prepare pools
ISwapper swapper = ISwapper(IPlatform(PLATFORM).swapper());
ISwapper.AddPoolData[] memory pools = new ISwapper.AddPoolData[](2);
pools[0] = ISwapper.AddPoolData({
pool: POOL_CURVE_crvUSD_USDCe,
ammAdapterId: AmmAdapterIdLib.CURVE,
tokenIn: TOKEN_crvUSD,
tokenOut: TOKEN_USDCe
});
pools[1] = ISwapper.AddPoolData({
pool: POOL_QUICKSWAPV3_CRV_WMATIC,
ammAdapterId: AmmAdapterIdLib.ALGEBRA,
tokenIn: TOKEN_CRV,
tokenOut: TOKEN_WMATIC
});

// prepare thresholds
address[] memory tokenIn = new address[](2);
tokenIn[0] = TOKEN_CRV;
tokenIn[1] = TOKEN_crvUSD;
uint[] memory thresholdAmount = new uint[](2);
thresholdAmount[0] = 1e15;
thresholdAmount[1] = 1e15;

// prepare farms
IFactory factory = IFactory(IPlatform(PLATFORM).factory());
IFactory.Farm[] memory _farms = new IFactory.Farm[](4);
uint i;
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDCe, CONVEX_REWARD_POOL_crvUSD_USDCe);
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDT, CONVEX_REWARD_POOL_crvUSD_USDT);
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_DAI, CONVEX_REWARD_POOL_crvUSD_DAI);
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDC, CONVEX_REWARD_POOL_crvUSD_USDC);

// start deploy
uint deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);

// add AMM adapter
Proxy proxy = new Proxy();
proxy.initProxy(address(new CurveAdapter()));
IPlatform(PLATFORM).addAmmAdapter(AmmAdapterIdLib.CURVE, address(proxy));

// deploy strategy implementation
address implementation = address(new CurveConvexFarmStrategy());

// add routes and thresholds
swapper.addPools(pools, false);
swapper.setThresholds(tokenIn, thresholdAmount);

// add farms
factory.addFarms(_farms);

// set config
factory.setStrategyLogicConfig(
IFactory.StrategyLogicConfig({
id: StrategyIdLib.CURVE_CONVEX_FARM,
implementation: implementation,
deployAllowed: true,
upgradeAllowed: true,
farming: true,
tokenId: type(uint).max
}),
DEV
);

vm.stopBroadcast();
}

function testDeployPolygon() external {}

function _makeCurveConvexFarm(
address curvePool,
address convexRewardPool
) internal view returns (IFactory.Farm memory) {
IFactory.Farm memory farm;
uint rewardTokensLength = IConvexRewardPool(convexRewardPool).rewardLength();
farm.status = 0;
// pool address can be extracted from convexRewardPool here: curveGauge() -> lp_token()
farm.pool = curvePool;
farm.strategyLogicId = StrategyIdLib.CURVE_CONVEX_FARM;
farm.rewardAssets = new address[](rewardTokensLength);
for (uint i; i < rewardTokensLength; ++i) {
IConvexRewardPool.RewardType memory r = IConvexRewardPool(convexRewardPool).rewards(i);
farm.rewardAssets[i] = r.reward_token;
}
farm.addresses = new address[](1);
farm.addresses[0] = convexRewardPool;
farm.nums = new uint[](0);
farm.ticks = new int24[](0);
return farm;
}
}
4 changes: 2 additions & 2 deletions script/DeployStrategyIRMF.Polygon.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ contract DeployStrategyIRMFPolygon is Script {

function run() external {
IFactory factory = IFactory(IPlatform(PLATFORM).factory());
ISwapper swapper = ISwapper(IPlatform(PLATFORM).swapper());
// ISwapper swapper = ISwapper(IPlatform(PLATFORM).swapper());

uint deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);
Expand All @@ -23,7 +23,7 @@ contract DeployStrategyIRMFPolygon is Script {
factory.addFarms(PolygonLib.farms4());

// swapper routes
swapper.addPools(PolygonLib.routes4(), false);
// swapper.addPools(PolygonLib.routes4(), false);

vm.stopBroadcast();
}
Expand Down
5 changes: 5 additions & 0 deletions script/libs/DeployStrategyLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import "../../src/strategies/DefiEdgeQuickSwapMerklFarmStrategy.sol";
import "../../src/strategies/IchiQuickSwapMerklFarmStrategy.sol";
import "../../src/strategies/IchiRetroMerklFarmStrategy.sol";
import "../../src/strategies/GammaRetroMerklFarmStrategy.sol";
import "../../src/strategies/CurveConvexFarmStrategy.sol";
import "../../src/strategies/libs/StrategyDeveloperLib.sol";

library DeployStrategyLib {
Expand Down Expand Up @@ -54,6 +55,10 @@ library DeployStrategyLib {
implementation = address(new GammaRetroMerklFarmStrategy());
}

if (CommonLib.eq(id, StrategyIdLib.CURVE_CONVEX_FARM)) {
implementation = address(new CurveConvexFarmStrategy());
}

// nosemgrep
require(implementation != address(0), "DeployStrategyLib: unknown strategy");

Expand Down
11 changes: 11 additions & 0 deletions src/integrations/convex/IBooster.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

interface IBooster {
/// @notice deposit lp tokens and stake
function deposit(uint pid, uint amount) external returns(bool);

/// @notice deposit all lp tokens and stake
function depositAll(uint pid) external returns(bool);

}
Loading

0 comments on commit 34868d0

Please sign in to comment.