Skip to content

Commit 11fca7d

Browse files
authored
Merge pull request #433 from stabilitydao/431-almf-aave-leverage-merkl-farm-contract
431 almf aave leverage merkl farm contract
2 parents b826476 + 5d2890b commit 11fca7d

45 files changed

Lines changed: 6469 additions & 25 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@ jobs:
2727
with:
2828
version: stable
2929

30+
# Restore Foundry RPC cache to avoid hitting paid RPC endpoints on every CI run.
31+
# This cache stores responses from all networks (Ethereum, Arbitrum, Base, etc.)
32+
# and allows forge to reuse previously fetched block/state data.
33+
# Without this step, every CI run would re-query RPC providers from scratch,
34+
# quickly exhausting rate limits on paid RPC keys.
35+
- name: Restore RPC cache
36+
uses: actions/cache@v3
37+
with:
38+
path: ~/.foundry/cache/rpc
39+
key: rpc-cache
40+
restore-keys: rpc-cache
41+
3042
- name: Run forge build
3143
run: |
3244
forge --version

chains/EthereumLib.sol

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {StrategyDeveloperLib} from "../src/strategies/libs/StrategyDeveloperLib.
1616
import {CVault} from "../src/core/vaults/CVault.sol";
1717
import {VaultTypeLib} from "../src/core/libs/VaultTypeLib.sol";
1818
import {PriceReader, IPriceReader} from "../src/core/PriceReader.sol";
19+
import {AaveLeverageMerklFarmStrategy} from "../src/strategies/AaveLeverageMerklFarmStrategy.sol";
1920

2021
/// @dev Ethereum network [chainId: 1] data library
2122
/// EEEEEEEEEE TTTTTTTTTT HHH HHH EEEEEEEEEE RRRRRRRR EEEEEEEEEE UU UU M M
@@ -48,6 +49,7 @@ library EthereumLib {
4849
address public constant POOL_UNISWAPV3_COMP_WETH_3000 = 0xea4Ba4CE14fdd287f380b55419B1C5b6c3f22ab6;
4950
address public constant POOL_UNISWAPV3_SHFL_USDC_3000 = 0xD0A4c8A1a14530C7C9EfDaD0BA37E8cF4204d230;
5051
address public constant POOL_UNISWAPV3_WBTC_EBTC_500 = 0xEf9b4FddD861aa2F00eE039C323b7FAbd7AFE239;
52+
address public constant POOL_UNISWAPV3_WBTC_USDC_3000 = 0x99ac8cA7087fA4A2A1FB6357269965A2014ABc35;
5153

5254
// Oracles
5355
address public constant ORACLE_CHAINLINK_USDC_USD = 0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6;
@@ -136,6 +138,7 @@ library EthereumLib {
136138

137139
//region ----- Deploy strategy logics -----
138140
factory.setStrategyImplementation(StrategyIdLib.COMPOUND_FARM, address(new CompoundFarmStrategy()));
141+
factory.setStrategyImplementation(StrategyIdLib.AAVE_LEVERAGE_MERKL_FARM, address(new AaveLeverageMerklFarmStrategy()));
139142
LogDeployLib.logDeployStrategies(platform, showLog);
140143
//endregion
141144

@@ -158,14 +161,15 @@ library EthereumLib {
158161
//endregion
159162

160163
//region ----- Pools -----
161-
pools = new ISwapper.AddPoolData[](6);
164+
pools = new ISwapper.AddPoolData[](7);
162165
uint i;
163166
pools[i++] = _makePoolData(POOL_UNISWAPV3_USDC_WETH_500, AmmAdapterIdLib.UNISWAPV3, TOKEN_USDC, TOKEN_WETH);
164167
pools[i++] = _makePoolData(POOL_UNISWAPV3_WETH_weETH_500, AmmAdapterIdLib.UNISWAPV3, TOKEN_WETH, TOKEN_weETH);
165168
pools[i++] = _makePoolData(POOL_UNISWAPV3_wstETH_WETH_100, AmmAdapterIdLib.UNISWAPV3, TOKEN_wstETH, TOKEN_WETH);
166169
pools[i++] = _makePoolData(POOL_UNISWAPV3_COMP_WETH_3000, AmmAdapterIdLib.UNISWAPV3, TOKEN_COMP, TOKEN_WETH);
167170
pools[i++] = _makePoolData(POOL_UNISWAPV3_SHFL_USDC_3000, AmmAdapterIdLib.UNISWAPV3, TOKEN_SHFL, TOKEN_USDC);
168-
pools[i++] = _makePoolData(POOL_UNISWAPV3_WBTC_EBTC_500, AmmAdapterIdLib.UNISWAPV3, TOKEN_WBTC, TOKEN_EBTC);
171+
pools[i++] = _makePoolData(POOL_UNISWAPV3_WBTC_EBTC_500, AmmAdapterIdLib.UNISWAPV3, TOKEN_EBTC, TOKEN_WBTC);
172+
pools[i++] = _makePoolData(POOL_UNISWAPV3_WBTC_USDC_3000, AmmAdapterIdLib.UNISWAPV3, TOKEN_WBTC, TOKEN_USDC);
169173
//endregion
170174
}
171175

chains/plasma/PlasmaConstantsLib.sol

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,37 @@ library PlasmaConstantsLib {
3030

3131
// Balancer
3232
address public constant BALANCER_V3_ROUTER = 0x9dA18982a33FD0c7051B19F0d7C76F2d5E7e017c;
33+
address public constant POOL_BALANCER_V3_STABLE_WETH_WEETH = 0xda51975D78Cb172b46d7292cEC9fa9E74723eF3b;
34+
address public constant POOL_BALANCER_V3_STABLE_SUSDE_USDT0 = 0xd9c4e277c93374a9f8C877a9D06707a88092E8F0;
3335

3436
// Euler: todo we need new strategy
3537
/// @notice https://app.euler.finance/earn/0xe818ad0D20D504C55601b9d5e0E137314414dec4?network=plasma
3638
address public constant EULER_MERKL_USDT0_K3_CAPITAL = 0xe818ad0D20D504C55601b9d5e0E137314414dec4;
3739
address public constant EULER_MERKL_USDT0_RE7 = 0xa5EeD1615cd883dD6883ca3a385F525e3bEB4E79;
3840

3941
// AAVE
42+
address public constant AAVE_V3_ADDRESS_PROVIDER = 0x061D8e131F26512348ee5FA42e2DF1bA9d6505E9;
43+
address public constant AAVE_V3_POOL_DATA_PROVIDER = 0xf2D6E38B407e31E7E7e4a16E6769728b76c7419F;
4044
address public constant AAVE_V3_POOL = 0x925a2A7214Ed92428B5b1B090F80b25700095e12;
4145
address public constant AAVE_V3_POOL_USDT0 = 0x5D72a9d9A9510Cd8cBdBA12aC62593A58930a948;
46+
address public constant AAVE_V3_POOL_WETH = 0xf1aB7f60128924d69f6d7dE25A20eF70bBd43d07;
47+
address public constant AAVE_V3_POOL_SUSDE = 0xC1A318493fF07a68fE438Cee60a7AD0d0DBa300E;
48+
address public constant AAVE_V3_POOL_WEETH = 0xAf1a7a488c8348b41d5860C04162af7d3D38A996;
49+
address public constant AAVE_V3_POOL_USDE = 0x7519403E12111ff6b710877Fcd821D0c12CAF43A;
50+
51+
// DEX
52+
address internal constant POOL_OKU_TRADE_USDT0_WETH = 0xCe4Ac514CA6a9db357CcCc105B7848d7fd37445d;
53+
address internal constant POOL_CURVE_USDE_USDT0 = 0x2D84D79C852f6842AbE0304b70bBaA1506AdD457;
54+
address internal constant POOL_CURVE_SUSDE_USDT0 = 0x1E8D78e9b3f0152D54d32904B7933f1cFE439Df1;
55+
address internal constant POOL_WXPL_USDT0 = 0x8603C67B7Cc056ef6981a9C709854c53b699Fa66;
56+
// address internal constant POOL_USDE_USDT0 = 0x01b968C1b663C3921Da5BE3C99Ee3c9B89a40B54;
57+
58+
// Wrapped AAVE tokens
59+
address public constant TOKEN_WAPLAWETH = 0xa047fdFb3420A27a5f926735b475fE5a1E968786;
60+
address public constant TOKEN_WAPLAUSDT0 = 0xE0126F0c4451B2B917064A93040fd4770D6774b5;
61+
/// @notice aPlaUSDe, see https://app.merkl.xyz/opportunities/plasma/MULTILOG_DUTCH/0x0e4366ce92ab4e9b011f77234922b1a04a9b6ec8BORROW_BL
62+
address public constant TOKEN_WAPLAUSDE = 0x63dC02BB25E7BF7Eaa0E42E71D785a388AcD740b;
63+
64+
address public constant POOL_SOLIDLY_WETH_WEETH = 0x355705857c9548E71E866087b01bB5b0A1fd671b;
65+
4266
}

chains/plasma/PlasmaFarmMakerLib.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ library PlasmaFarmMakerLib {
2424
}
2525

2626
function testFarmMakerLib() external {}
27-
}
27+
}

chains/plasma/PlasmaLib.sol

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {Proxy} from "../../src/core/proxy/Proxy.sol";
1818
import {StrategyDeveloperLib} from "../../src/strategies/libs/StrategyDeveloperLib.sol";
1919
import {StrategyIdLib} from "../../src/strategies/libs/StrategyIdLib.sol";
2020
import {VaultTypeLib} from "../../src/core/libs/VaultTypeLib.sol";
21+
import {AaveLeverageMerklFarmStrategy} from "../../src/strategies/AaveLeverageMerklFarmStrategy.sol";
2122

2223
library PlasmaLib {
2324
function platformDeployParams() internal pure returns (IPlatformDeployer.DeployPlatformParams memory p) {
@@ -57,6 +58,10 @@ library PlasmaLib {
5758
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.BALANCER_V3_RECLAMM);
5859
IBalancerAdapter(IPlatform(platform).ammAdapter(keccak256(bytes(AmmAdapterIdLib.BALANCER_V3_RECLAMM))).proxy)
5960
.setupHelpers(PlasmaConstantsLib.BALANCER_V3_ROUTER);
61+
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.UNISWAPV3);
62+
IBalancerAdapter(DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.BALANCER_V3_STABLE)).setupHelpers(PlasmaConstantsLib.BALANCER_V3_ROUTER);
63+
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.CURVE);
64+
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.ERC_4626);
6065
//endregion -- Deploy AMM adapters ----
6166

6267
//region ----- Setup Swapper -----
@@ -73,14 +78,15 @@ library PlasmaLib {
7378

7479
//region ----- Deploy strategies -----
7580
factory.setStrategyImplementation(StrategyIdLib.AAVE_MERKL_FARM, address(new AaveMerklFarmStrategy()));
81+
factory.setStrategyImplementation(StrategyIdLib.AAVE_LEVERAGE_MERKL_FARM, address(new AaveLeverageMerklFarmStrategy()));
7682
//endregion
7783

7884
//region ----- Add DeX aggregators -----
7985
//endregion
8086
}
8187

8288
function routes() public pure returns (ISwapper.AddPoolData[] memory pools) {
83-
pools = new ISwapper.AddPoolData[](2);
89+
pools = new ISwapper.AddPoolData[](6);
8490
uint i;
8591
pools[i++] = _makePoolData(
8692
PlasmaConstantsLib.POOL_BALANCER_V3_RECLAMM_WXPL_USDT0,
@@ -94,6 +100,30 @@ library PlasmaLib {
94100
PlasmaConstantsLib.TOKEN_WXPL,
95101
PlasmaConstantsLib.TOKEN_USDT0
96102
);
103+
pools[i++] = _makePoolData(
104+
PlasmaConstantsLib.POOL_OKU_TRADE_USDT0_WETH,
105+
AmmAdapterIdLib.UNISWAPV3,
106+
PlasmaConstantsLib.TOKEN_WETH,
107+
PlasmaConstantsLib.TOKEN_USDT0
108+
);
109+
pools[i++] = _makePoolData(
110+
PlasmaConstantsLib.POOL_BALANCER_V3_STABLE_WETH_WEETH,
111+
AmmAdapterIdLib.BALANCER_V3_STABLE,
112+
PlasmaConstantsLib.TOKEN_WEETH,
113+
PlasmaConstantsLib.TOKEN_WAPLAWETH
114+
);
115+
pools[i++] = _makePoolData(
116+
PlasmaConstantsLib.POOL_CURVE_SUSDE_USDT0,
117+
AmmAdapterIdLib.CURVE,
118+
PlasmaConstantsLib.TOKEN_SUSDE,
119+
PlasmaConstantsLib.TOKEN_USDT0
120+
);
121+
pools[i++] = _makePoolData(
122+
PlasmaConstantsLib.POOL_CURVE_USDE_USDT0,
123+
AmmAdapterIdLib.CURVE,
124+
PlasmaConstantsLib.TOKEN_USDE,
125+
PlasmaConstantsLib.TOKEN_USDT0
126+
);
97127
}
98128

99129
function farms() public pure returns (IFactory.Farm[] memory _farms) {
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.28;
3+
4+
import {StrategyIdLib} from "../../src/strategies/libs/StrategyIdLib.sol";
5+
import {IFactory} from "../../src/interfaces/IFactory.sol";
6+
import {SiloManagedMerklFarmStrategy} from "../../src/strategies/SiloManagedMerklFarmStrategy.sol";
7+
8+
/// @notice Shared implementation of farms
9+
library SharedFarmMakerLib {
10+
/// @notice Creates Aave Leverage Merkl Farm configuration
11+
/// @param aTokenCollateral Address of aToken used as collateral
12+
/// @param aTokenBorrow Address of aToken used as borrowed asset
13+
/// @param flashLoanVault Address of the vault used for flash loans
14+
/// @param rewardAssets Array of reward token addresses
15+
/// @param minTargetLtv Minimum target loan-to-value ratio (LTV) for leverage management, 85_00 = 0.85
16+
/// @param maxTargetLtv Maximum target loan-to-value ratio (LTV) for leverage management, 85_00 = 0.85
17+
/// @param flashLoanKind Type of flash loan to be used (see ILeverageLendingStrategy.FlashLoanKind)
18+
/// @param eModeCategoryId EMode category ID for the farm (optional, can be 0)
19+
/// @param revenueBaseAssetIndex Index of the asset for share price calculations. 0 - collateral asset, 1 - borrow asset
20+
function _makeAaveLeverageMerklFarm(
21+
address aTokenCollateral,
22+
address aTokenBorrow,
23+
address flashLoanVault,
24+
address[] memory rewardAssets,
25+
uint minTargetLtv,
26+
uint maxTargetLtv,
27+
uint flashLoanKind,
28+
uint8 eModeCategoryId,
29+
uint8 revenueBaseAssetIndex
30+
) internal pure returns (IFactory.Farm memory) {
31+
IFactory.Farm memory farm;
32+
farm.status = 0;
33+
farm.strategyLogicId = StrategyIdLib.AAVE_LEVERAGE_MERKL_FARM;
34+
farm.rewardAssets = rewardAssets;
35+
36+
farm.addresses = new address[](3);
37+
farm.addresses[0] = aTokenCollateral;
38+
farm.addresses[1] = aTokenBorrow;
39+
farm.addresses[2] = flashLoanVault;
40+
41+
farm.nums = new uint[](5);
42+
farm.nums[0] = minTargetLtv;
43+
farm.nums[1] = maxTargetLtv;
44+
farm.nums[2] = flashLoanKind;
45+
farm.nums[3] = eModeCategoryId;
46+
farm.nums[4] = revenueBaseAssetIndex;
47+
48+
return farm;
49+
}
50+
51+
}

chains/sonic/SonicConstantsLib.sol

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,13 @@ library SonicConstantsLib {
533533
address public constant BRUNCH_GEN2_ATOKEN_SBUSD = 0xeB9bB589C12A0433B274760E657D549a6973C787;
534534
address public constant BRUNCH_GEN2_ATOKEN_USDC = 0x958d930E61bdaebbBc0270D88FdBAEE9A13Dc6fd;
535535

536+
// -------------------------- STBL-USDC isolated market
537+
address public constant STABILITY_STBL_USDC_MARKET_ADDRESS_PROVIDER = 0x234888531C4a6AFeF6935DD7DB9F9D5325b68715;
538+
address public constant STABILITY_STBL_USDC_MARKET_POOL = 0xb0A06303085aB2F73212C8846CA5388Da5697c31;
539+
address public constant STABILITY_STBL_USDC_MARKET_TOKEN_STBL = 0x00886bC6a12d8D5ad0ef51e041a8AB37A0E59251;
540+
address public constant STABILITY_STBL_USDC_MARKET_TOKEN_USDC = 0x46b2E96725F03873Cb586a7f84c22545F2835F31;
541+
542+
536543
// -------------------------- Shadow
537544
// address public constant SHADOW_NFT = 0x12E66C8F215DdD5d48d150c8f46aD0c6fB0F4406;
538545
address public constant SHADOW_ROUTER = 0x1D368773735ee1E678950B7A97bcA2CafB330CDc;

chains/sonic/SonicLib.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import {IPriceAggregator} from "../../src/interfaces/IPriceAggregator.sol";
4646
import {EulerMerklFarmStrategy} from "../../src/strategies/EulerMerklFarmStrategy.sol";
4747
import {SiloManagedMerklFarmStrategy} from "../../src/strategies/SiloManagedMerklFarmStrategy.sol";
4848
import {SiloMerklFarmStrategy} from "../../src/strategies/SiloMerklFarmStrategy.sol";
49+
import {AaveLeverageMerklFarmStrategy} from "../../src/strategies/AaveLeverageMerklFarmStrategy.sol";
4950

5051
/// @dev Sonic network [chainId: 146] data library
5152
// _____ _
@@ -245,6 +246,7 @@ library SonicLib {
245246
factory.setStrategyImplementation(StrategyIdLib.COMPOUND_V2, address(new CompoundV2Strategy()));
246247
factory.setStrategyImplementation(StrategyIdLib.SILO_MANAGED_MERKL_FARM, address(new SiloManagedMerklFarmStrategy()));
247248
factory.setStrategyImplementation(StrategyIdLib.SILO_MERKL_FARM, address(new SiloMerklFarmStrategy()));
249+
factory.setStrategyImplementation(StrategyIdLib.AAVE_LEVERAGE_MERKL_FARM, address(new AaveLeverageMerklFarmStrategy()));
248250
LogDeployLib.logDeployStrategies(platform, showLog);
249251
//endregion
250252

guides/AllDeployments.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@
9999
### Periphery
100100

101101
* **Frontend** `0x70e804364175e23F1c30dFa03BFb19d936E5E81c` [plasmascan](https://plasmascan.to/address/0x70e804364175e23F1c30dFa03BFb19d936E5E81c)
102+
* **UpgradeHelper** `0x932D7bd758214fDF58f7824c09503D9FcD36C089` [plasmascan](https://plasmascan.to/address/0x932D7bd758214fDF58f7824c09503D9FcD36C089)
103+
104+
### AMM adapters
105+
* **BalancerV3ReCLAMM** `0x54Ea393aAc117d67B913F1cC63Df143761519A63` [plasmascan](https://plasmascan.to/address/0x54Ea393aAc117d67B913F1cC63Df143761519A63)
106+
* **BalancerV3Stable** `0xc73DBCFFADd43F87c0a37d39FA1460F5D80E3bca` [plasmascan](https://plasmascan.to/address/0xc73DBCFFADd43F87c0a37d39FA1460F5D80E3bca)
107+
* **Curve** `0xF93Ee7e1B1C5679974a004ce59DBdECEcB45475e` [plasmascan](https://plasmascan.to/address/0xF93Ee7e1B1C5679974a004ce59DBdECEcB45475e)
108+
* **ERC4626** `0x63f83f6807C77FA33ccA12D9422B912C78f6F8ed` [plasmascan](https://plasmascan.to/address/0x63f83f6807C77FA33ccA12D9422B912C78f6F8ed)
109+
* **UniswapV3** `0xd901ceCbcD3493C98c9569ea7a41295a180333de` [plasmascan](https://plasmascan.to/address/0xd901ceCbcD3493C98c9569ea7a41295a180333de)
110+
* **Solidly** `0x35CcD976BD574fEa00b97d58095bB8e90D26a455` [plasmascan](https://plasmascan.to/address/0x35CcD976BD574fEa00b97d58095bB8e90D26a455)
102111

103112

104113
## Polygon [137]

0 commit comments

Comments
 (0)