Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions chains/avalanche/AvalancheConstantsLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ library AvalancheConstantsLib {
address public constant TOKEN_AUSD = 0x00000000eFE302BEAA2b3e6e1b18d08D69a9012a;
address public constant TOKEN_xBTC = 0x6eAf19b2FC24552925dB245F9Ff613157a7dbb4C;
address public constant TOKEN_savBTS = 0x649342c6bff544d82DF1B2bA3C93e0C22cDeBa84;
address public constant TOKEN_savUSDC = 0x06d47F3fb376649c3A9Dafe069B3D6E35572219E;
address public constant TOKEN_savUSD = 0x06d47F3fb376649c3A9Dafe069B3D6E35572219E;
address public constant TOKEN_avUSD = 0x24dE8771bC5DdB3362Db529Fc3358F2df3A0E346;
address public constant TOKEN_sUSDp = 0x9D92c21205383651610f90722131655A5B8ED3E0;
address public constant TOKEN_USDp = 0x9eE1963f05553eF838604Dd39403be21ceF26AA4;


// Oracles
address public constant ORACLE_CHAINLINK_USDC_USD = 0xF096872672F44d6EBA71458D74fe67F9a77a23B9;
Expand Down Expand Up @@ -52,18 +56,43 @@ library AvalancheConstantsLib {
address public constant AAVE_V3_POOL = 0x794a61358D6845594F94dc1DB02A252b5b4814aD;
address public constant AAVE_aAvaUSDC = 0x625E7708f30cA75bfd92586e17077590C60eb4cD;

// Balancer
address public constant BEETS_VAULT = 0xBA12222222228d8Ba445958a75a0704d566BF2C8;
address public constant BEETS_VAULT_V3 = 0xbA1333333333a1BA1108E8412f11850A5C319bA9;
address public constant BEETS_V3_ROUTER = 0xF39CA6ede9BF7820a952b52f3c94af526bAB9015;

address public constant BEETS_STABLE_POOL_USDp_GAMI_USDC = 0x1fED8401C145f64dA567881d272D0DF233118dCa;

// DEX
address public constant POOL_PHARAOH_V3_AVUSD_USDC = 0xc9bFC3cDA285a75B32d5B787618128dB963dE675;
address public constant POOL_PHARAOH_V3_USDT_USDC = 0x9bFE3108Cc16D17a9Ec65545a0f50B2CA1C970c0;
address public constant POOL_ALGEBRA_SAVUSD_USDC = 0x86364634157b4247c1dD54c5945832eAF691Af79;

// Silo
address public constant SILO_LENS = 0x319f7155cC65F693E84689535aFb1343C704C0B8;
address public constant SILO_VAULT_USDC_125 = 0xE0345f66318F482aCCcd67244A921C7FDC410957;
address public constant SILO_VAULT_BTCb_130 = 0x7437ac81457Fa98fFB2d0C8f9943ecfE4813e2f1;
address public constant SILO_VAULT_BTCb_121 = 0xD8a26DFEba3E9B558Bd79d10722636Dfb4dc2bF4;
address public constant SILO_VAULT_USDC_142 = 0x606fe9a70338e798a292CA22C1F28C829F24048E;
address public constant SILO_VAULT_USDC_129 = 0x672b77f0538b53Dc117C9dDfEb7377A678d321a6;
address public constant SILO_VAULT_142_USDC = 0x606fe9a70338e798a292CA22C1F28C829F24048E;
address public constant SILO_VAULT_142_SAVUSDC = 0xDcFFACBed111BA9d59b5e96A85934Db91117BDD9;
address public constant SILO_VAULT_129_USDC = 0x672b77f0538b53Dc117C9dDfEb7377A678d321a6;
address public constant SILO_VAULT_153_USDC = 0x2775631eA39d8d6e9A89C299387Ea55CfFC18b0b;
address public constant SILO_VAULT_153_SUSDP = 0x69F3B55E4001214EA54319cDCdD4e2Ae904440Af;

address public constant SILO_MANAGED_VAULT_GAMI_USDC = 0x1F0570a081FeE0e4dF6eAC470f9d2D53CDEDa1c5;

address public constant SILO_MANAGED_VAULT_USDC_MEV = 0x4dc1ce9b9f9EF00c144BfAD305f16c62293dC0E8;
address public constant SILO_MANAGED_VAULT_BTCb_MEV = 0x1f8E769B5B6010B2C2BBCd68629EA1a0a0Eda7E3;
address public constant SILO_MANAGED_VAULT_AUSD_VARLAMOURE = 0x3d7B0c3997E48fA3FC96cd057d1fb4E5F891835B;
address public constant SILO_MANAGED_VAULT_USDt_VARLAMOURE = 0x6c09bfdc1df45D6c4Ff78Dc9F1C13aF29eB335d4;

// Liquidity book - https://github.com/lfj-gg
// Router and quoter are taken for the savUSDC-pool: 0x7a5b4e301fc2b148cefe57257a236eb845082797
address public constant LB_LFJ_ROUTER_V2 = 0x18556DA13313f3532c54711497A8FedAC273220E;
address public constant LB_LFJ_QUOTER_V2 = 0x9A550a522BBaDFB69019b0432800Ed17855A51C3;
address public constant POOL_LB_LFJ_LBPAIR_savUSDC_avUSD = 0xb768091A8e6FFCdc215767937Bd9fb039CB06577;
address public constant POOL_LB_LFJ_LBPAIR_avUSDC_USDC = 0xBe36F03F83D773dd05CaA41EA0891Fd92ba3Ed6c;

// ---------------------------------- LayerZero-v2 https://docs.layerzero.network/v2/deployments/chains/avalanche
uint32 public constant LAYER_ZERO_V2_ENDPOINT_ID = 30106;
address public constant LAYER_ZERO_V2_ENDPOINT = 0x1a44076050125825900e736c501f859c50fE728c;
Expand Down
12 changes: 10 additions & 2 deletions chains/avalanche/AvalancheLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {ChainlinkAdapter} from "../../src/adapters/ChainlinkAdapter.sol";
import {DeployAdapterLib} from "../../script/libs/DeployAdapterLib.sol";
import {EulerMerklFarmStrategy} from "../../src/strategies/EulerMerklFarmStrategy.sol";
import {EulerStrategy} from "../../src/strategies/EulerStrategy.sol";
import {IBalancerAdapter} from "../../src/interfaces/IBalancerAdapter.sol";
import {IFactory} from "../../src/interfaces/IFactory.sol";
import {IPlatformDeployer} from "../../src/interfaces/IPlatformDeployer.sol";
import {IPlatform} from "../../src/interfaces/IPlatform.sol";
Expand All @@ -23,6 +24,7 @@ import {SiloStrategy} from "../../src/strategies/SiloStrategy.sol";
import {StrategyDeveloperLib} from "../../src/strategies/libs/StrategyDeveloperLib.sol";
import {StrategyIdLib} from "../../src/strategies/libs/StrategyIdLib.sol";
import {VaultTypeLib} from "../../src/core/libs/VaultTypeLib.sol";
import {SiloAdvancedLeverageStrategy} from "../../src/strategies/SiloAdvancedLeverageStrategy.sol";

/// @dev Avalanche network [chainId: 43114] deploy library
// ,---, ,--, ,---,
Expand Down Expand Up @@ -82,6 +84,11 @@ library AvalancheLib {
//region ----- Deploy AMM adapters -----
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.UNISWAPV3);
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.ALGEBRA_V4);
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.ALGEBRA);
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.ERC_4626);
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.BALANCER_V3_STABLE);
IBalancerAdapter(IPlatform(platform).ammAdapter(keccak256(bytes(AmmAdapterIdLib.BALANCER_V3_STABLE))).proxy).setupHelpers(AvalancheConstantsLib.BEETS_V3_ROUTER);
DeployAdapterLib.deployAmmAdapter(platform, AmmAdapterIdLib.LBLFJ_V2);
//endregion -- Deploy AMM adapters ----

//region ----- Setup Swapper -----
Expand Down Expand Up @@ -129,6 +136,7 @@ library AvalancheLib {
factory.setStrategyImplementation(StrategyIdLib.EULER_MERKL_FARM, address(new EulerMerklFarmStrategy()));
factory.setStrategyImplementation(StrategyIdLib.SILO_MANAGED_MERKL_FARM, address(new SiloManagedMerklFarmStrategy()));
factory.setStrategyImplementation(StrategyIdLib.SILO_MERKL_FARM, address(new SiloMerklFarmStrategy()));
factory.setStrategyImplementation(StrategyIdLib.SILO_ADVANCED_LEVERAGE, address(new SiloAdvancedLeverageStrategy()));
//endregion

//region ----- Add DeX aggregators -----
Expand Down Expand Up @@ -196,9 +204,9 @@ library AvalancheLib {
_farms[i++] = AvalancheFarmMakerLib._makeSiloManagedMerklFarm(AvalancheConstantsLib.SILO_MANAGED_VAULT_USDt_VARLAMOURE); // 7

_farms[i++] = AvalancheFarmMakerLib._makeSiloMerklFarm(AvalancheConstantsLib.SILO_VAULT_BTCb_130, AvalancheConstantsLib.TOKEN_WAVAX, address(0), true); // 8
_farms[i++] = AvalancheFarmMakerLib._makeSiloMerklFarm(AvalancheConstantsLib.SILO_VAULT_USDC_142, AvalancheConstantsLib.TOKEN_WAVAX, address(0), true); // 9
_farms[i++] = AvalancheFarmMakerLib._makeSiloMerklFarm(AvalancheConstantsLib.SILO_VAULT_142_USDC, AvalancheConstantsLib.TOKEN_WAVAX, address(0), true); // 9
_farms[i++] = AvalancheFarmMakerLib._makeSiloMerklFarm(AvalancheConstantsLib.SILO_VAULT_BTCb_121, AvalancheConstantsLib.TOKEN_WAVAX, address(0), true); // 10
_farms[i++] = AvalancheFarmMakerLib._makeSiloMerklFarm(AvalancheConstantsLib.SILO_VAULT_USDC_129, AvalancheConstantsLib.TOKEN_WAVAX, address(0), true); // 11
_farms[i++] = AvalancheFarmMakerLib._makeSiloMerklFarm(AvalancheConstantsLib.SILO_VAULT_129_USDC, AvalancheConstantsLib.TOKEN_WAVAX, address(0), true); // 11
}

function _makePoolData(
Expand Down
30 changes: 18 additions & 12 deletions script/libs/DeployAdapterLib.sol
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import {Proxy} from "../../src/core/proxy/Proxy.sol";
import {AmmAdapterIdLib} from "../../src/adapters/libs/AmmAdapterIdLib.sol";
import {UniswapV3Adapter} from "../../src/adapters/UniswapV3Adapter.sol";
import "../../src/adapters/LbAdapterLFJV2.sol";
import {AlgebraAdapter} from "../../src/adapters/AlgebraAdapter.sol";
import {KyberAdapter} from "../../src/adapters/KyberAdapter.sol";
import {CurveAdapter} from "../../src/adapters/CurveAdapter.sol";
import {AlgebraV4Adapter} from "../../src/adapters/AlgebraV4Adapter.sol";
import {AmmAdapterIdLib} from "../../src/adapters/libs/AmmAdapterIdLib.sol";
import {BalancerComposableStableAdapter} from "../../src/adapters/BalancerComposableStableAdapter.sol";
import {BalancerV3ReClammAdapter} from "../../src/adapters/BalancerV3ReClammAdapter.sol";
import {BalancerV3StableAdapter} from "../../src/adapters/BalancerV3StableAdapter.sol";
import {BalancerWeightedAdapter} from "../../src/adapters/BalancerWeightedAdapter.sol";
import {SolidlyAdapter} from "../../src/adapters/SolidlyAdapter.sol";
import {AlgebraV4Adapter} from "../../src/adapters/AlgebraV4Adapter.sol";
import {CurveAdapter} from "../../src/adapters/CurveAdapter.sol";
import {ERC4626Adapter} from "../../src/adapters/ERC4626Adapter.sol";
import {BalancerV3StableAdapter} from "../../src/adapters/BalancerV3StableAdapter.sol";
import {PendleAdapter} from "../../src/adapters/PendleAdapter.sol";
import {MetaVaultAdapter} from "../../src/adapters/MetaVaultAdapter.sol";
import {IPlatform} from "../../src/interfaces/IPlatform.sol";
import {IAmmAdapter} from "../../src/interfaces/IAmmAdapter.sol";
import {BalancerV3ReClammAdapter} from "../../src/adapters/BalancerV3ReClammAdapter.sol";
import {IPlatform} from "../../src/interfaces/IPlatform.sol";
import {KyberAdapter} from "../../src/adapters/KyberAdapter.sol";
import {MetaVaultAdapter} from "../../src/adapters/MetaVaultAdapter.sol";
import {PendleAdapter} from "../../src/adapters/PendleAdapter.sol";
import {Proxy} from "../../src/core/proxy/Proxy.sol";
import {SolidlyAdapter} from "../../src/adapters/SolidlyAdapter.sol";
import {UniswapV3Adapter} from "../../src/adapters/UniswapV3Adapter.sol";
import {LbAdapterLFJV2} from "../../src/adapters/LbAdapterLFJV2.sol";

library DeployAdapterLib {
function deployAmmAdapter(address platform, string memory id) internal returns (address) {
Expand Down Expand Up @@ -80,6 +82,10 @@ library DeployAdapterLib {
proxy.initProxy(address(new BalancerV3ReClammAdapter()));
}

if (eq(id, AmmAdapterIdLib.LBLFJ_V2)) {
proxy.initProxy(address(new LbAdapterLFJV2()));
}

require(proxy.implementation() != address(0), string.concat("Unknown AmmAdapter:", id));
IAmmAdapter(address(proxy)).init(platform);
IPlatform(platform).addAmmAdapter(id, address(proxy));
Expand Down
157 changes: 157 additions & 0 deletions src/adapters/LbAdapterLFJV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {AmmAdapterIdLib} from "./libs/AmmAdapterIdLib.sol";
import {ConstantsLib} from "../core/libs/ConstantsLib.sol";
import {Controllable, IControllable, IERC165} from "../core/base/Controllable.sol";
import {IAmmAdapter} from "../interfaces/IAmmAdapter.sol";
import {SafeERC20, IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ILbPairV2} from "../integrations/lblfgv2/ILbPairV2.sol";
import {IERC20Metadata} from "../../lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol";

/// @title Adapter for Liquidity Book (DLMM) as implemented by LFJ, see https://github.com/lfj-gg
/// @author omriss (https://github.com/omriss)
contract LbAdapterLFJV2 is Controllable, IAmmAdapter {
using SafeERC20 for IERC20;

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

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

error IncorrectTokens();
error InsufficientOutputAmount(uint amountInLeft);

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

/// @inheritdoc IAmmAdapter
function init(address platform_) external initializer {
__Controllable_init(platform_);
}

//region ------------------------------------ User actions
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* USER ACTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @inheritdoc IAmmAdapter
//slither-disable-next-line reentrancy-events
function swap(
address pool,
address tokenIn,
address tokenOut,
address recipient,
uint priceImpactTolerance
) external {
ILbPairV2 pair = ILbPairV2(pool);

// --------------- token-out balance before swap (to calculate actual amountOut after swap)
uint balanceBefore = IERC20(tokenOut).balanceOf(recipient);

// --------------- verify that provided tokens are correct
address tokenX = pair.getTokenX();
require(_isValid(pair, tokenIn, tokenOut, tokenX), IncorrectTokens());

// --------------- input amount should be sent on balance of the pair contract before swap call
uint amount = IERC20(tokenIn).balanceOf(address(this));
IERC20(tokenIn).safeTransfer(pool, amount);

// --------------- ensure that there is enough output amount in the pair
(uint128 amountInLeft, uint128 price,) = pair.getSwapOut(uint128(amount), tokenIn == tokenX);
require(amountInLeft == 0, InsufficientOutputAmount(amountInLeft));

// --------------- perform the swap
pair.swap(tokenX == tokenIn, recipient);

// --------------- actual amount out received by the recipient
uint balanceAfter = IERC20(tokenOut).balanceOf(recipient);
uint amountOut = balanceAfter > balanceBefore ? balanceAfter - balanceBefore : 0;

// --------------- verify that price impact is within the tolerance limit
uint priceImpact = (price - amountOut) * ConstantsLib.DENOMINATOR / price;
if (priceImpact >= priceImpactTolerance) {
revert(string(abi.encodePacked("!PRICE ", Strings.toString(priceImpact))));
}

emit SwapInPool(pool, tokenIn, tokenOut, recipient, priceImpactTolerance, amount, amountOut);
}
Comment on lines +44 to +82

Check warning

Code scanning / Slither

Dangerous strict equalities Medium

Comment on lines +44 to +82
Comment on lines +44 to +82

Check warning

Code scanning / Slither

Unused return Medium


//endregion ---------------------------------- User actions

//region ------------------------------------ View functions
/*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
/* VIEW FUNCTIONS */
/*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

/// @inheritdoc IAmmAdapter
function ammAdapterId() external pure returns (string memory) {
return AmmAdapterIdLib.LBLFJ_V2;
}

/// @inheritdoc IAmmAdapter
function poolTokens(address pool) public view returns (address[] memory tokens) {
tokens = new address[](2);
tokens[0] = ILbPairV2(pool).getTokenX();
tokens[1] = ILbPairV2(pool).getTokenY();
}

/// @inheritdoc IAmmAdapter
function getLiquidityForAmounts(address, uint[] memory) external pure returns (uint, uint[] memory) {
revert("Not supported");
}

/// @inheritdoc IAmmAdapter
function getProportions(address) external pure returns (uint[] memory) {
revert("Not supported");
}

/// @inheritdoc IAmmAdapter
function getPrice(address pool, address tokenIn, address tokenOut, uint amount) public view returns (uint price) {
address tokenX = ILbPairV2(pool).getTokenX();
if (_isValid(ILbPairV2(pool), tokenIn, tokenOut, tokenX)) {
if (amount == 0) {
amount = 10 ** IERC20Metadata(tokenIn).decimals();
}
(uint128 amountInLeft, uint128 amountOut,) = ILbPairV2(pool).getSwapOut(uint128(amount), tokenIn == tokenX);

// todo how to handle following case without reverting?
require(amountInLeft == 0, InsufficientOutputAmount(amountInLeft));

price = amountOut;
}

return price;
}
Comment on lines +114 to +129

/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view override(Controllable, IERC165) returns (bool) {
return interfaceId == type(IAmmAdapter).interfaceId || super.supportsInterface(interfaceId);
}

//endregion -------------------------------- View functions

/// @inheritdoc IAmmAdapter
function getTwaPrice(
address,
/*pool*/
address,
/*tokenIn*/
address,
/*tokenOut*/
uint,
/*amount*/
uint32 /*period*/
) external pure returns (uint) {
revert("Not supported");
}

function _isValid(ILbPairV2 pair, address tokenIn, address tokenOut, address tokenX) internal view returns (bool) {
address tokenY = pair.getTokenY();
return (tokenX == tokenIn && tokenY == tokenOut) || (tokenY == tokenIn && tokenX == tokenOut);
}
}
1 change: 1 addition & 0 deletions src/adapters/libs/AmmAdapterIdLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ library AmmAdapterIdLib {
string public constant BALANCER_V3_RECLAMM = "BalancerV3ReCLAMM";
string public constant BRUNCH = "Brunch";
string public constant AAVE_V3 = "AaveV3";
string public constant LBLFJ_V2 = "LbLFJV2";
}
Loading
Loading