Skip to content

Commit 34868d0

Browse files
authored
Merge pull request #111 from stabilitydao/110-dev-curve-convex-farm
Curve Convex Farm
2 parents 3b5618b + 458291f commit 34868d0

17 files changed

+756
-98
lines changed

chains/PolygonLib.sol

Lines changed: 70 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import "../src/strategies/libs/ALMPositionNameLib.sol";
99
import "../src/interfaces/IFactory.sol";
1010
import "../src/interfaces/IPlatform.sol";
1111
import "../src/interfaces/ISwapper.sol";
12+
import "../src/integrations/convex/IConvexRewardPool.sol";
1213
import "../script/libs/DeployLib.sol";
1314
import "../script/libs/DeployAdapterLib.sol";
1415
import "../script/libs/DeployStrategyLib.sol";
@@ -37,6 +38,7 @@ library PolygonLib {
3738
address public constant TOKEN_oRETRO = 0x3A29CAb2E124919d14a6F735b6033a3AaD2B260F;
3839
address public constant TOKEN_CASH = 0x5D066D022EDE10eFa2717eD3D79f22F949F8C175;
3940
address public constant TOKEN_crvUSD = 0xc4Ce1D6F5D98D65eE25Cf85e9F2E9DcFEe6Cb5d6;
41+
address public constant TOKEN_CRV = 0x172370d5Cd63279eFa6d502DAB29171933a610AF;
4042

4143
// ERC21
4244
address public constant TOKEN_PM = 0xAA3e3709C79a133e56C17a7ded87802adF23083B;
@@ -72,6 +74,7 @@ library PolygonLib {
7274
address public constant POOL_QUICKSWAPV3_USDC_WETH = 0xa6AeDF7c4Ed6e821E67a6BfD56FD1702aD9a9719;
7375
address public constant POOL_QUICKSWAPV3_WMATIC_USDC = 0x6669B4706cC152F359e947BCa68E263A87c52634;
7476
address public constant POOL_QUICKSWAPV3_USDC_DAI = 0xBC8f3da0bd42E1F2509cd8671Ce7c7E5f7fd39c8;
77+
address public constant POOL_QUICKSWAPV3_CRV_WMATIC = 0x00A6177C6455A29B8dAa7144B2bEfc9F2147BB7E;
7578
address public constant POOL_KYBER_USDCe_USDT = 0x879664ce5A919727b3Ed4035Cf12F7F740E8dF00;
7679
address public constant POOL_KYBER_USDCe_DAI = 0x02A3E4184b145eE64A6Df3c561A3C0c6e2f23DFa;
7780
address public constant POOL_KYBER_KNC_USDCe = 0x4B440a7DE0Ab7041934d0c171849A76CC33234Fa;
@@ -84,6 +87,9 @@ library PolygonLib {
8487
address public constant POOL_RETRO_USDCe_CASH_100 = 0x619259F699839dD1498FFC22297044462483bD27;
8588
address public constant POOL_RETRO_CASH_RETRO_10000 = 0xb47A07966cE6812702C0567d03725F1b37E27877;
8689
address public constant POOL_CURVE_crvUSD_USDCe = 0x864490Cf55dc2Dee3f0ca4D06F5f80b2BB154a03;
90+
address public constant POOL_CURVE_crvUSD_USDT = 0xA70Af99bFF6b168327f9D1480e29173e757c7904;
91+
address public constant POOL_CURVE_crvUSD_DAI = 0x62c949ee985b125Ff2d7ddcf4Fe7AEcB0a040E2a;
92+
address public constant POOL_CURVE_crvUSD_USDC = 0x5225010A0AE133B357861782B0B865a48471b2C5;
8793

8894
// Gelato
8995
address public constant GELATO_AUTOMATE = 0x527a819db1eb0e34426297b03bae11F2f8B3A19E;
@@ -140,6 +146,13 @@ library PolygonLib {
140146
// Retro
141147
address public constant RETRO_QUOTER = 0xddc9Ef56c6bf83F7116Fad5Fbc41272B07ac70C1;
142148

149+
// Convex
150+
address public constant CONVEX_BOOSTER = 0xddc9Ef56c6bf83F7116Fad5Fbc41272B07ac70C1;
151+
address public constant CONVEX_REWARD_POOL_crvUSD_USDCe = 0xBFEE9F3E015adC754066424AEd535313dc764116;
152+
address public constant CONVEX_REWARD_POOL_crvUSD_USDT = 0xd2D8BEB901f90163bE4667A85cDDEbB7177eb3E3;
153+
address public constant CONVEX_REWARD_POOL_crvUSD_DAI = 0xaCb744c7e7C95586DB83Eda3209e6483Fb1FCbA4;
154+
address public constant CONVEX_REWARD_POOL_crvUSD_USDC = 0x11F2217fa1D5c44Eae310b9b985E2964FC47D8f9;
155+
143156
function runDeploy(bool showLog) internal returns (address platform) {
144157
//region ----- DeployPlatform -----
145158
uint[] memory buildingPrice = new uint[](3);
@@ -199,16 +212,12 @@ library PolygonLib {
199212
{
200213
(ISwapper.AddPoolData[] memory bcPools, ISwapper.AddPoolData[] memory pools) = routes();
201214
ISwapper.AddPoolData[] memory pools2 = routes2();
202-
ISwapper.AddPoolData[] memory pools3 = routes3();
203-
ISwapper.AddPoolData[] memory pools4 = routes4();
204215
ISwapper swapper = ISwapper(IPlatform(platform).swapper());
205216
swapper.addBlueChipsPools(bcPools, false);
206217
swapper.addPools(pools, false);
207218
swapper.addPools(pools2, false);
208-
swapper.addPools(pools3, false);
209-
swapper.addPools(pools4, false);
210219
// todo auto thresholds
211-
address[] memory tokenIn = new address[](8);
220+
address[] memory tokenIn = new address[](10);
212221
tokenIn[0] = TOKEN_USDCe;
213222
tokenIn[1] = TOKEN_USDT;
214223
tokenIn[2] = TOKEN_DAI;
@@ -217,7 +226,9 @@ library PolygonLib {
217226
tokenIn[5] = TOKEN_dQUICK;
218227
tokenIn[6] = TOKEN_USDC;
219228
tokenIn[7] = TOKEN_COMP;
220-
uint[] memory thresholdAmount = new uint[](8);
229+
tokenIn[8] = TOKEN_CRV;
230+
tokenIn[9] = TOKEN_crvUSD;
231+
uint[] memory thresholdAmount = new uint[](10);
221232
thresholdAmount[0] = 1e3;
222233
thresholdAmount[1] = 1e3;
223234
thresholdAmount[2] = 1e15;
@@ -226,6 +237,8 @@ library PolygonLib {
226237
thresholdAmount[5] = 1e16; // 1 dQuick ~= $0.05
227238
thresholdAmount[6] = 1e3;
228239
thresholdAmount[7] = 1e15;
240+
thresholdAmount[8] = 1e15;
241+
thresholdAmount[9] = 1e15;
229242
swapper.setThresholds(tokenIn, thresholdAmount);
230243
DeployLib.logSetupSwapper(platform, showLog);
231244
}
@@ -242,6 +255,7 @@ library PolygonLib {
242255
if (block.number > 54573098) {
243256
// Mar-12-2024 02:41:42 PM +UTC
244257
factory.addFarms(farms7());
258+
factory.addFarms(farms8());
245259
}
246260
DeployLib.logAddedFarms(address(factory), showLog);
247261
//endregion -- Add farms -----
@@ -266,6 +280,7 @@ library PolygonLib {
266280
DeployStrategyLib.deployStrategy(platform, StrategyIdLib.ICHI_QUICKSWAP_MERKL_FARM, true);
267281
DeployStrategyLib.deployStrategy(platform, StrategyIdLib.ICHI_RETRO_MERKL_FARM, true);
268282
DeployStrategyLib.deployStrategy(platform, StrategyIdLib.GAMMA_RETRO_MERKL_FARM, true);
283+
DeployStrategyLib.deployStrategy(platform, StrategyIdLib.CURVE_CONVEX_FARM, true);
269284
DeployLib.logDeployStrategies(platform, showLog);
270285
//endregion -- Deploy strategy logics -----
271286

@@ -386,61 +401,60 @@ library PolygonLib {
386401
//endregion -- Pools ----
387402
}
388403

389-
/// @notice New routes jan-2024
390404
function routes2() public pure returns (ISwapper.AddPoolData[] memory pools) {
391-
pools = new ISwapper.AddPoolData[](1);
405+
pools = new ISwapper.AddPoolData[](8);
392406
uint i;
407+
// New routes jan-2024
393408
pools[i++] = ISwapper.AddPoolData({
394409
pool: POOL_QUICKSWAPV3_USDCe_USDC,
395410
ammAdapterId: AmmAdapterIdLib.ALGEBRA,
396411
tokenIn: TOKEN_USDC,
397412
tokenOut: TOKEN_USDCe
398413
});
399-
}
400-
401-
/// @notice New routes jan-2024
402-
function routes3() public pure returns (ISwapper.AddPoolData[] memory pools) {
403-
pools = new ISwapper.AddPoolData[](2);
404-
uint i;
405414
pools[i++] = ISwapper.AddPoolData({
406415
pool: POOL_UNISWAPV3_WETH_COMP_3000,
407416
ammAdapterId: AmmAdapterIdLib.UNISWAPV3,
408417
tokenIn: TOKEN_COMP,
409418
tokenOut: TOKEN_WETH
410419
});
411-
412420
pools[i++] = ISwapper.AddPoolData({
413421
pool: POOL_UNISWAPV3_ICHI_WMATIC_100,
414422
ammAdapterId: AmmAdapterIdLib.UNISWAPV3,
415423
tokenIn: TOKEN_ICHI,
416424
tokenOut: TOKEN_WMATIC
417425
});
418-
}
419-
420-
// routes for RETRO strategies
421-
function routes4() public pure returns (ISwapper.AddPoolData[] memory pools) {
422-
pools = new ISwapper.AddPoolData[](3);
423-
uint i;
426+
// routes for RETRO strategies
424427
pools[i++] = ISwapper.AddPoolData({
425428
pool: POOL_RETRO_USDCe_RETRO_10000,
426429
ammAdapterId: AmmAdapterIdLib.UNISWAPV3,
427430
tokenIn: TOKEN_RETRO,
428431
tokenOut: TOKEN_USDCe
429432
});
430-
431433
pools[i++] = ISwapper.AddPoolData({
432434
pool: POOL_RETRO_oRETRO_RETRO_10000,
433435
ammAdapterId: AmmAdapterIdLib.UNISWAPV3,
434436
tokenIn: TOKEN_oRETRO,
435437
tokenOut: TOKEN_RETRO
436438
});
437-
438439
pools[i++] = ISwapper.AddPoolData({
439440
pool: POOL_RETRO_USDCe_CASH_100,
440441
ammAdapterId: AmmAdapterIdLib.UNISWAPV3,
441442
tokenIn: TOKEN_CASH,
442443
tokenOut: TOKEN_USDCe
443444
});
445+
// crvUSD
446+
pools[i++] = ISwapper.AddPoolData({
447+
pool: POOL_CURVE_crvUSD_USDCe,
448+
ammAdapterId: AmmAdapterIdLib.CURVE,
449+
tokenIn: TOKEN_crvUSD,
450+
tokenOut: TOKEN_USDCe
451+
});
452+
pools[i++] = ISwapper.AddPoolData({
453+
pool: POOL_QUICKSWAPV3_CRV_WMATIC,
454+
ammAdapterId: AmmAdapterIdLib.ALGEBRA,
455+
tokenIn: TOKEN_CRV,
456+
tokenOut: TOKEN_WMATIC
457+
});
444458
}
445459

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

725+
function farms8() public view returns (IFactory.Farm[] memory _farms) {
726+
_farms = new IFactory.Farm[](4);
727+
uint i;
728+
729+
// [34]
730+
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDCe, CONVEX_REWARD_POOL_crvUSD_USDCe);
731+
// [35]
732+
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDT, CONVEX_REWARD_POOL_crvUSD_USDT);
733+
// [36]
734+
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_DAI, CONVEX_REWARD_POOL_crvUSD_DAI);
735+
// [37]
736+
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDC, CONVEX_REWARD_POOL_crvUSD_USDC);
737+
}
738+
739+
function _makeCurveConvexFarm(address curvePool, address convexRewardPool) internal view returns (IFactory.Farm memory) {
740+
IFactory.Farm memory farm;
741+
uint rewardTokensLength = IConvexRewardPool(convexRewardPool).rewardLength();
742+
farm.status = 0;
743+
// pool address can be extracted from convexRewardPool here: curveGauge() -> lp_token()
744+
farm.pool = curvePool;
745+
farm.strategyLogicId = StrategyIdLib.CURVE_CONVEX_FARM;
746+
farm.rewardAssets = new address[](rewardTokensLength);
747+
for (uint i; i < rewardTokensLength; ++i) {
748+
IConvexRewardPool.RewardType memory r = IConvexRewardPool(convexRewardPool).rewards(i);
749+
farm.rewardAssets[i] = r.reward_token;
750+
}
751+
farm.addresses = new address[](1);
752+
farm.addresses[0] = convexRewardPool;
753+
farm.nums = new uint[](0);
754+
farm.ticks = new int24[](0);
755+
return farm;
756+
}
757+
711758
function _makeGammaQuickSwapMerklFarm(
712759
address hypervisor,
713760
uint preset
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.23;
3+
4+
import "forge-std/Script.sol";
5+
import "../src/core/proxy/Proxy.sol";
6+
import "../src/adapters/CurveAdapter.sol";
7+
import "../src/strategies/CurveConvexFarmStrategy.sol";
8+
9+
contract DeployStrategyCCFPolygon is Script {
10+
address public constant PLATFORM = 0xb2a0737ef27b5Cc474D24c779af612159b1c3e60;
11+
address public constant POOL_CURVE_crvUSD_USDCe = 0x864490Cf55dc2Dee3f0ca4D06F5f80b2BB154a03;
12+
address public constant POOL_CURVE_crvUSD_USDT = 0xA70Af99bFF6b168327f9D1480e29173e757c7904;
13+
address public constant POOL_CURVE_crvUSD_DAI = 0x62c949ee985b125Ff2d7ddcf4Fe7AEcB0a040E2a;
14+
address public constant POOL_CURVE_crvUSD_USDC = 0x5225010A0AE133B357861782B0B865a48471b2C5;
15+
address public constant POOL_QUICKSWAPV3_CRV_WMATIC = 0x00A6177C6455A29B8dAa7144B2bEfc9F2147BB7E;
16+
address public constant TOKEN_crvUSD = 0xc4Ce1D6F5D98D65eE25Cf85e9F2E9DcFEe6Cb5d6;
17+
address public constant TOKEN_CRV = 0x172370d5Cd63279eFa6d502DAB29171933a610AF;
18+
address public constant TOKEN_WMATIC = 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270;
19+
address public constant TOKEN_USDCe = 0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174;
20+
address public constant CONVEX_REWARD_POOL_crvUSD_USDCe = 0xBFEE9F3E015adC754066424AEd535313dc764116;
21+
address public constant CONVEX_REWARD_POOL_crvUSD_USDT = 0xd2D8BEB901f90163bE4667A85cDDEbB7177eb3E3;
22+
address public constant CONVEX_REWARD_POOL_crvUSD_DAI = 0xaCb744c7e7C95586DB83Eda3209e6483Fb1FCbA4;
23+
address public constant CONVEX_REWARD_POOL_crvUSD_USDC = 0x11F2217fa1D5c44Eae310b9b985E2964FC47D8f9;
24+
address public constant DEV = 0x88888887C3ebD4a33E34a15Db4254C74C75E5D4A;
25+
26+
function run() external {
27+
// prepare pools
28+
ISwapper swapper = ISwapper(IPlatform(PLATFORM).swapper());
29+
ISwapper.AddPoolData[] memory pools = new ISwapper.AddPoolData[](2);
30+
pools[0] = ISwapper.AddPoolData({
31+
pool: POOL_CURVE_crvUSD_USDCe,
32+
ammAdapterId: AmmAdapterIdLib.CURVE,
33+
tokenIn: TOKEN_crvUSD,
34+
tokenOut: TOKEN_USDCe
35+
});
36+
pools[1] = ISwapper.AddPoolData({
37+
pool: POOL_QUICKSWAPV3_CRV_WMATIC,
38+
ammAdapterId: AmmAdapterIdLib.ALGEBRA,
39+
tokenIn: TOKEN_CRV,
40+
tokenOut: TOKEN_WMATIC
41+
});
42+
43+
// prepare thresholds
44+
address[] memory tokenIn = new address[](2);
45+
tokenIn[0] = TOKEN_CRV;
46+
tokenIn[1] = TOKEN_crvUSD;
47+
uint[] memory thresholdAmount = new uint[](2);
48+
thresholdAmount[0] = 1e15;
49+
thresholdAmount[1] = 1e15;
50+
51+
// prepare farms
52+
IFactory factory = IFactory(IPlatform(PLATFORM).factory());
53+
IFactory.Farm[] memory _farms = new IFactory.Farm[](4);
54+
uint i;
55+
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDCe, CONVEX_REWARD_POOL_crvUSD_USDCe);
56+
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDT, CONVEX_REWARD_POOL_crvUSD_USDT);
57+
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_DAI, CONVEX_REWARD_POOL_crvUSD_DAI);
58+
_farms[i++] = _makeCurveConvexFarm(POOL_CURVE_crvUSD_USDC, CONVEX_REWARD_POOL_crvUSD_USDC);
59+
60+
// start deploy
61+
uint deployerPrivateKey = vm.envUint("PRIVATE_KEY");
62+
vm.startBroadcast(deployerPrivateKey);
63+
64+
// add AMM adapter
65+
Proxy proxy = new Proxy();
66+
proxy.initProxy(address(new CurveAdapter()));
67+
IPlatform(PLATFORM).addAmmAdapter(AmmAdapterIdLib.CURVE, address(proxy));
68+
69+
// deploy strategy implementation
70+
address implementation = address(new CurveConvexFarmStrategy());
71+
72+
// add routes and thresholds
73+
swapper.addPools(pools, false);
74+
swapper.setThresholds(tokenIn, thresholdAmount);
75+
76+
// add farms
77+
factory.addFarms(_farms);
78+
79+
// set config
80+
factory.setStrategyLogicConfig(
81+
IFactory.StrategyLogicConfig({
82+
id: StrategyIdLib.CURVE_CONVEX_FARM,
83+
implementation: implementation,
84+
deployAllowed: true,
85+
upgradeAllowed: true,
86+
farming: true,
87+
tokenId: type(uint).max
88+
}),
89+
DEV
90+
);
91+
92+
vm.stopBroadcast();
93+
}
94+
95+
function testDeployPolygon() external {}
96+
97+
function _makeCurveConvexFarm(
98+
address curvePool,
99+
address convexRewardPool
100+
) internal view returns (IFactory.Farm memory) {
101+
IFactory.Farm memory farm;
102+
uint rewardTokensLength = IConvexRewardPool(convexRewardPool).rewardLength();
103+
farm.status = 0;
104+
// pool address can be extracted from convexRewardPool here: curveGauge() -> lp_token()
105+
farm.pool = curvePool;
106+
farm.strategyLogicId = StrategyIdLib.CURVE_CONVEX_FARM;
107+
farm.rewardAssets = new address[](rewardTokensLength);
108+
for (uint i; i < rewardTokensLength; ++i) {
109+
IConvexRewardPool.RewardType memory r = IConvexRewardPool(convexRewardPool).rewards(i);
110+
farm.rewardAssets[i] = r.reward_token;
111+
}
112+
farm.addresses = new address[](1);
113+
farm.addresses[0] = convexRewardPool;
114+
farm.nums = new uint[](0);
115+
farm.ticks = new int24[](0);
116+
return farm;
117+
}
118+
}

script/DeployStrategyIRMF.Polygon.s.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ contract DeployStrategyIRMFPolygon is Script {
1212

1313
function run() external {
1414
IFactory factory = IFactory(IPlatform(PLATFORM).factory());
15-
ISwapper swapper = ISwapper(IPlatform(PLATFORM).swapper());
15+
// ISwapper swapper = ISwapper(IPlatform(PLATFORM).swapper());
1616

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

2525
// swapper routes
26-
swapper.addPools(PolygonLib.routes4(), false);
26+
// swapper.addPools(PolygonLib.routes4(), false);
2727

2828
vm.stopBroadcast();
2929
}

script/libs/DeployStrategyLib.sol

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import "../../src/strategies/DefiEdgeQuickSwapMerklFarmStrategy.sol";
1212
import "../../src/strategies/IchiQuickSwapMerklFarmStrategy.sol";
1313
import "../../src/strategies/IchiRetroMerklFarmStrategy.sol";
1414
import "../../src/strategies/GammaRetroMerklFarmStrategy.sol";
15+
import "../../src/strategies/CurveConvexFarmStrategy.sol";
1516
import "../../src/strategies/libs/StrategyDeveloperLib.sol";
1617

1718
library DeployStrategyLib {
@@ -54,6 +55,10 @@ library DeployStrategyLib {
5455
implementation = address(new GammaRetroMerklFarmStrategy());
5556
}
5657

58+
if (CommonLib.eq(id, StrategyIdLib.CURVE_CONVEX_FARM)) {
59+
implementation = address(new CurveConvexFarmStrategy());
60+
}
61+
5762
// nosemgrep
5863
require(implementation != address(0), "DeployStrategyLib: unknown strategy");
5964

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.23;
3+
4+
interface IBooster {
5+
/// @notice deposit lp tokens and stake
6+
function deposit(uint pid, uint amount) external returns(bool);
7+
8+
/// @notice deposit all lp tokens and stake
9+
function depositAll(uint pid) external returns(bool);
10+
11+
}

0 commit comments

Comments
 (0)