Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changeset/brave-lions-swim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@exactly/protocol": patch
---

✨ adapter: use morpho flash loans
72 changes: 38 additions & 34 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ DebtManagerTest:testFloatingToFixedRollHigherThanAvailableLiquidityWithSlippage(
DebtManagerTest:testFloatingToFixedRollHigherThanAvailableLiquidityWithSlippageWithThreePools() (gas: 2818426)
DebtManagerTest:testFloatingToFixedRollWithAccurateSlippage() (gas: 1732739)
DebtManagerTest:testFloatingToFixedRollWithAccurateSlippageWithPreviousPosition() (gas: 1954939)
DebtManagerTest:testFuzzRolls(uint8[4],uint8[4],uint256[4],uint40[4],uint8[4]) (runs: 256, μ: 8031714, ~: 8129987)
DebtManagerTest:testFuzzRolls(uint8[4],uint8[4],uint256[4],uint40[4],uint8[4]) (runs: 256, μ: 8000226, ~: 8068563)
DebtManagerTest:testLateFixedRoll() (gas: 1454770)
DebtManagerTest:testLateFixedRollWithThreeLoops() (gas: 2043936)
DebtManagerTest:testLateFixedToFloatingRoll() (gas: 1449634)
Expand Down Expand Up @@ -165,13 +165,17 @@ FirewallTest:test_allow_reverts_whenNotOriginalAllower() (gas: 171661)
FirewallTest:test_disallow_disallows_whenAllowedAndOriginalAllower() (gas: 116906)
FirewallTest:test_disallow_disallows_whenAllowedAndOriginalAllowerRoleIsRevoked() (gas: 217133)
FirewallTest:test_disallow_reverts_whenAllowedAndNotOriginalAllower() (gas: 171638)
FlashLoanAdapterTest:test_consumeAdapter() (gas: 2334825)
FlashLoanAdapterTest:test_consumeAdapter_withWToken() (gas: 8860215)
FlashLoanAdapterTest:test_flashLoan_reverts_whenAmountsLengthNotOne() (gas: 32678)
FlashLoanAdapterTest:test_flashLoan_reverts_whenTokensLengthNotOne() (gas: 32591)
FlashLoanAdapterTest:test_setWToken_emitsWTokenSet() (gas: 80696)
FlashLoanAdapterTest:test_setWToken_reverts_whenNotAdmin() (gas: 66649)
FlashLoanAdapterTest:test_setWToken_sets_whenAdmin() (gas: 82048)
FlashLoanAdapterTest:test_flashLoan_forwardsArguments() (gas: 135720)
FlashLoanAdapterTest:test_flashLoan_lends_fullBalance_usdc() (gas: 228513)
FlashLoanAdapterTest:test_flashLoan_lends_fullBalance_weth() (gas: 180042)
FlashLoanAdapterTest:test_flashLoan_lends_usdc(uint256) (runs: 256, μ: 246067, ~: 246305)
FlashLoanAdapterTest:test_flashLoan_lends_whenCallerIsNotRecipient() (gas: 228715)
FlashLoanAdapterTest:test_flashLoan_reverts_whenAmountsLengthNotOne() (gas: 35030)
FlashLoanAdapterTest:test_flashLoan_reverts_whenOverAvailable() (gas: 84243)
FlashLoanAdapterTest:test_flashLoan_reverts_whenTokensLengthNotOne() (gas: 35731)
FlashLoanAdapterTest:test_flashLoan_reverts_whenZeroAmount() (gas: 44160)
FlashLoanAdapterTest:test_onMorphoFlashLoan_reverts_whenNotMorpho() (gas: 327385)
FlashLoanAdapterTest:test_rollFixed_rolls_withDebtRoller() (gas: 4580555)
InstallmentsRouterTest:testAmountsLength() (gas: 36806)
InstallmentsRouterTest:testBorrowETHToAnotherReceiver() (gas: 801220)
InstallmentsRouterTest:testBorrowETHWithPermit() (gas: 1239104)
Expand All @@ -194,18 +198,18 @@ IntegrationPreviewerTest:test_fixedRepayPosition_beforeMaturity() (gas: 579991)
IntegrationPreviewerTest:test_fixedRepayPosition_maxUint() (gas: 79468)
IntegrationPreviewerTest:test_fixedRepayPosition_saturatedFallback() (gas: 63069)
IntegrationPreviewerTest:test_healthFactor() (gas: 463879)
IntegrationPreviewerTest:test_previewDeposit_(uint256) (runs: 256, μ: 1590393, ~: 1594456)
IntegrationPreviewerTest:test_previewDeposit_(uint256) (runs: 256, μ: 1590434, ~: 1594456)
IntegrationPreviewerTest:test_previewHealthFactor() (gas: 5805294)
IntegrationPreviewerTest:test_previewWithdraw_(uint256) (runs: 256, μ: 1649847, ~: 1654116)
IntegrationPreviewerTest:test_previewWithdraw_(uint256) (runs: 256, μ: 1649893, ~: 1654116)
InterestRateModelTest:testFixedBorrowRate() (gas: 2088868)
InterestRateModelTest:testFixedRateRevertAlreadyMatured() (gas: 2083135)
InterestRateModelTest:testFixedRateRevertUtilizationExceeded() (gas: 2097203)
InterestRateModelTest:testFloatingBorrowRate() (gas: 2082456)
InterestRateModelTest:testFuzzFixedRateGrowth(uint256,uint256,uint256,uint256) (runs: 256, μ: 2109079, ~: 2105195)
InterestRateModelTest:testFuzzFixedRateTimeSensitivity(uint256,uint256,uint256) (runs: 256, μ: 2117002, ~: 2117161)
InterestRateModelTest:testFuzzReferenceLegacyRateFixed(uint32,uint256,uint256[2],uint256[2],uint256,uint256,uint256) (runs: 256, μ: 12909428, ~: 13130610)
InterestRateModelTest:testFuzzReferenceRateFixed(uint256,uint256,uint256,uint256,uint256,uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,uint256)) (runs: 256, μ: 2384608, ~: 2386846)
InterestRateModelTest:testFuzzReferenceRateFloating(uint256,uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 256, μ: 2324354, ~: 2324970)
InterestRateModelTest:testFuzzFixedRateGrowth(uint256,uint256,uint256,uint256) (runs: 256, μ: 2108931, ~: 2105195)
InterestRateModelTest:testFuzzFixedRateTimeSensitivity(uint256,uint256,uint256) (runs: 256, μ: 2116999, ~: 2117161)
InterestRateModelTest:testFuzzReferenceLegacyRateFixed(uint32,uint256,uint256[2],uint256[2],uint256,uint256,uint256) (runs: 256, μ: 12921605, ~: 13130650)
InterestRateModelTest:testFuzzReferenceRateFixed(uint256,uint256,uint256,uint256,uint256,uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,uint256)) (runs: 256, μ: 2384629, ~: 2386937)
InterestRateModelTest:testFuzzReferenceRateFloating(uint256,uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 256, μ: 2324337, ~: 2325007)
InterestRateModelTest:testMinTimeToMaturity() (gas: 2107232)
InterestRateModelTest:testRevertMaxUtilizationLowerThanWad() (gas: 268402)
MarketTest:testAccountLiquidityAdjustedDebt() (gas: 654260)
Expand Down Expand Up @@ -540,8 +544,8 @@ StakedEXATest:invariantNoDuplicatedReward() (runs: 10, calls: 5000, reverts: 0)
StakedEXATest:invariantRewardsUpOnly() (runs: 10, calls: 5000, reverts: 0)
StakedEXATest:invariantShareValueIsOne() (runs: 10, calls: 5000, reverts: 0)
StakedEXATest:testAlreadyListedError() (gas: 43677)
StakedEXATest:testAvgIndex(uint256[3],uint256[2]) (runs: 256, μ: 1321279, ~: 1370843)
StakedEXATest:testAvgStartTime(uint256[3],uint256[2]) (runs: 256, μ: 1249345, ~: 1298909)
StakedEXATest:testAvgIndex(uint256[3],uint256[2]) (runs: 256, μ: 1321490, ~: 1370842)
StakedEXATest:testAvgStartTime(uint256[3],uint256[2]) (runs: 256, μ: 1249556, ~: 1298908)
StakedEXATest:testBalanceOfDeposit(uint80) (runs: 256, μ: 331003, ~: 339807)
StakedEXATest:testBalanceOfWithdraw(uint256) (runs: 256, μ: 82393, ~: 82407)
StakedEXATest:testCanChangeRewardsDurationWhenDisabled() (gas: 176331)
Expand All @@ -550,12 +554,12 @@ StakedEXATest:testClaimAndUnstake() (gas: 1622618)
StakedEXATest:testClaimAndWithdrawAfterRefTime() (gas: 1029325)
StakedEXATest:testClaimBeforeFirstHarvest() (gas: 527334)
StakedEXATest:testDepositClaimsRewardsToReceiver() (gas: 1121108)
StakedEXATest:testDepositEvent(uint256) (runs: 256, μ: 335234, ~: 334978)
StakedEXATest:testDepositShouldClaim(uint256[2],uint32) (runs: 256, μ: 821450, ~: 754892)
StakedEXATest:testDepositEvent(uint256) (runs: 256, μ: 335234, ~: 334990)
StakedEXATest:testDepositShouldClaim(uint256[2],uint32) (runs: 256, μ: 822448, ~: 754904)
StakedEXATest:testDepositToAnotherWithAllowance() (gas: 375284)
StakedEXATest:testDepositToAnotherWithoutAllowanceShouldFail() (gas: 121959)
StakedEXATest:testDepositWithdrawAvgStartTimeAndIndex(uint256[3],uint256,uint256[5]) (runs: 256, μ: 1886121, ~: 1905249)
StakedEXATest:testEarnedWithTime(uint256) (runs: 256, μ: 86132, ~: 86326)
StakedEXATest:testDepositWithdrawAvgStartTimeAndIndex(uint256[3],uint256,uint256[5]) (runs: 256, μ: 1886018, ~: 1905249)
StakedEXATest:testEarnedWithTime(uint256) (runs: 256, μ: 86137, ~: 86326)
StakedEXATest:testEmergencyAdminCanPauseNotUnpause() (gas: 175029)
StakedEXATest:testFinishDistributionEmitEvent() (gas: 240752)
StakedEXATest:testFinishDistributionLetsClaimUnclaimed() (gas: 1784877)
Expand All @@ -566,9 +570,9 @@ StakedEXATest:testGrantRevokeEmergencyAdmin() (gas: 117824)
StakedEXATest:testGrantRevokePauser() (gas: 117836)
StakedEXATest:testHandlerClaim(uint8) (runs: 256, μ: 485340, ~: 485340)
StakedEXATest:testHandlerDeposit(uint80) (runs: 256, μ: 1240331, ~: 1276242)
StakedEXATest:testHandlerHarvest(uint64) (runs: 256, μ: 402354, ~: 411143)
StakedEXATest:testHandlerNotifyRewardAmount(uint64) (runs: 256, μ: 165017, ~: 156797)
StakedEXATest:testHandlerSetDuration(uint32) (runs: 256, μ: 195324, ~: 218711)
StakedEXATest:testHandlerHarvest(uint64) (runs: 256, μ: 402355, ~: 411143)
StakedEXATest:testHandlerNotifyRewardAmount(uint64) (runs: 256, μ: 165160, ~: 156797)
StakedEXATest:testHandlerSetDuration(uint32) (runs: 256, μ: 197124, ~: 218711)
StakedEXATest:testHandlerSetMarket() (gas: 144553)
StakedEXATest:testHandlerWithdraw(uint256) (runs: 256, μ: 91497, ~: 91511)
StakedEXATest:testHarvestAmountWithReducedAllowance() (gas: 184605)
Expand All @@ -579,13 +583,13 @@ StakedEXATest:testHarvestWhenFinished() (gas: 326352)
StakedEXATest:testHarvestX() (gas: 180952)
StakedEXATest:testHarvestZero() (gas: 255436)
StakedEXATest:testInitialValues() (gas: 196484)
StakedEXATest:testInsufficientBalanceError(uint256) (runs: 256, μ: 63922, ~: 64151)
StakedEXATest:testInsufficientBalanceError(uint256) (runs: 256, μ: 63927, ~: 64151)
StakedEXATest:testMaxRewardsGasConsumption() (gas: 144674963)
StakedEXATest:testMultipleClaimsVsOne() (gas: 21936440)
StakedEXATest:testMultipleHarvests() (gas: 284083)
StakedEXATest:testNoRewardsAfterPeriod(uint256) (runs: 256, μ: 1809475, ~: 1804427)
StakedEXATest:testNoRewardsAfterPeriod(uint256) (runs: 256, μ: 1809429, ~: 1804427)
StakedEXATest:testNotPausingRoleError() (gas: 39124)
StakedEXATest:testNotifyRewardAmount(uint256,uint256) (runs: 256, μ: 155635, ~: 155564)
StakedEXATest:testNotifyRewardAmount(uint256,uint256) (runs: 256, μ: 155614, ~: 155564)
StakedEXATest:testNotifyRewardWithUnderlyingAsset() (gas: 460608)
StakedEXATest:testOnlyAdminEnableReward() (gas: 1297302)
StakedEXATest:testOnlyAdminFinishDistribution() (gas: 213640)
Expand All @@ -604,12 +608,12 @@ StakedEXATest:testPermitAndDeposit() (gas: 452146)
StakedEXATest:testPermitFailKeepsFlow() (gas: 484480)
StakedEXATest:testRemoveDepositAllowance() (gas: 466913)
StakedEXATest:testResetDepositAfterRefTime(uint256) (runs: 256, μ: 1033248, ~: 1032994)
StakedEXATest:testRewardAmountNotifiedEvent(uint256) (runs: 256, μ: 105543, ~: 105293)
StakedEXATest:testRewardAmountNotifiedEvent(uint256) (runs: 256, μ: 105551, ~: 105293)
StakedEXATest:testRewardNotListedError() (gas: 1177184)
StakedEXATest:testRewardPaidEvent(uint256,uint256) (runs: 256, μ: 811252, ~: 854321)
StakedEXATest:testRewardsAmounts(uint256) (runs: 256, μ: 1707520, ~: 1707287)
StakedEXATest:testRewardPaidEvent(uint256,uint256) (runs: 256, μ: 810170, ~: 854321)
StakedEXATest:testRewardsAmounts(uint256) (runs: 256, μ: 1707519, ~: 1707287)
StakedEXATest:testRewardsDurationSetEvent(uint40) (runs: 256, μ: 52173, ~: 52149)
StakedEXATest:testSetDuration(uint256,uint40) (runs: 256, μ: 66028, ~: 64453)
StakedEXATest:testSetDuration(uint256,uint40) (runs: 256, μ: 66012, ~: 64453)
StakedEXATest:testSetMarketAddressZero() (gas: 36979)
StakedEXATest:testSetMarketOnlyAdmin() (gas: 1345554)
StakedEXATest:testSetMaxRewardsTokensExceeded() (gas: 111958823)
Expand All @@ -621,12 +625,12 @@ StakedEXATest:testSetSavingsZeroAddressError() (gas: 37006)
StakedEXATest:testTotalSupplyDeposit(uint80) (runs: 256, μ: 330389, ~: 339193)
StakedEXATest:testTotalSupplyWithdraw(uint256) (runs: 256, μ: 81753, ~: 81767)
StakedEXATest:testUntransferable(uint80) (runs: 256, μ: 338580, ~: 348672)
StakedEXATest:testWithdrawEvent(uint256) (runs: 256, μ: 483401, ~: 483158)
StakedEXATest:testWithdrawEvent(uint256) (runs: 256, μ: 483401, ~: 483176)
StakedEXATest:testWithdrawRewardUnderlyingAsset() (gas: 456617)
StakedEXATest:testWithdrawRewardsOnlyAdmin() (gas: 242200)
StakedEXATest:testWithdrawRewardsOnlyReward() (gas: 1177174)
StakedEXATest:testWithdrawSameAmountRewardsShouldEqual(uint256,uint256) (runs: 256, μ: 1065854, ~: 1107874)
StakedEXATest:testWithdrawWithRewards(uint256) (runs: 256, μ: 895625, ~: 895382)
StakedEXATest:testWithdrawSameAmountRewardsShouldEqual(uint256,uint256) (runs: 256, μ: 1065998, ~: 1107874)
StakedEXATest:testWithdrawWithRewards(uint256) (runs: 256, μ: 895625, ~: 895400)
StakedEXATest:testZeroRateError() (gas: 58274)
StakingPreviewerTest:testAllClaimable() (gas: 769205)
StakingPreviewerTest:testAllClaimed() (gas: 818952)
Expand Down
111 changes: 32 additions & 79 deletions contracts/periphery/FlashLoanAdapter.sol
Original file line number Diff line number Diff line change
@@ -1,108 +1,61 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

import { AccessControl } from "@openzeppelin/contracts-v4/access/AccessControl.sol";
import { IERC20 } from "@openzeppelin/contracts-v4/interfaces/IERC20.sol";
import { IERC4626 } from "@openzeppelin/contracts-v4/interfaces/IERC4626.sol";
import { SafeTransferLib } from "solady/src/utils/SafeTransferLib.sol";

import { IFlashLoaner, IFlashLoanRecipient } from "./DebtRoller.sol";

/// @title FlashLoanAdapter
/// @notice Adapter to use Balancer V3 vault with Balancer V2 interface.
/// Uses wrapped tokens when there's not enough liquidity in the vault.
contract FlashLoanAdapter is AccessControl {
IBalancerVaultV3 public immutable vault;
/// @notice Adapter to use Morpho flash loans with the `IFlashLoaner` interface.
/// Morpho flash loans are free, so reported fees are always zero.
contract FlashLoanAdapter is IFlashLoaner {
using SafeTransferLib for address;

/// @notice Mapping to check if a token is a wrapped token.
mapping(IERC20 wToken => bool isWToken) public isWToken;
/// @notice Mapping to get the wrapped token for an asset.
mapping(IERC20 asset => IERC4626 wToken) public wTokens;
/// @notice Morpho contract that provides the flash loans.
IMorpho public immutable morpho;

constructor(IBalancerVaultV3 vault_, address owner) {
_grantRole(DEFAULT_ADMIN_ROLE, owner);
vault = vault_;
constructor(IMorpho morpho_) {
morpho = morpho_;
}

/// @notice Performs a flash loan using the Balancer V3 vault.
/// @notice Performs a flash loan using Morpho.
/// @param recipient The address to receive the flash loan.
/// @param tokens The tokens to borrow.
/// @param amounts The amounts to borrow.
/// @param data Additional data to pass to the recipient.
// solhint-disable-next-line gas-calldata-parameters
function flashLoan(address recipient, IERC20[] memory tokens, uint256[] memory amounts, bytes memory data) external {
if (tokens.length != 1 || amounts.length != 1) revert InvalidLength();
uint256[] memory fees = new uint256[](1);
if (tokens[0].balanceOf(address(vault)) < amounts[0]) {
IERC4626 wToken = wTokens[tokens[0]];
if (wToken == IERC4626(address(0)) || wToken.convertToAssets(wToken.balanceOf(address(vault))) < amounts[0]) {
revert InsufficientLiquidity();
}

tokens[0] = IERC20(address(wToken));
uint256 shares = wToken.previewWithdraw(amounts[0]);
fees[0] = wToken.previewMint(shares) - amounts[0];
amounts[0] = shares;
}
vault.unlock(
abi.encodeWithSelector(this.receiveFlashLoan.selector, abi.encode(recipient, tokens, amounts, fees, data))
);
morpho.flashLoan(address(tokens[0]), amounts[0], abi.encode(recipient, tokens, amounts, data));
}

/// @notice Receives a flash loan from the Balancer V3 vault.
/// @param payload The payload containing the recipient, tokens, amounts, fees, and data.
function receiveFlashLoan(bytes calldata payload) external {
if (msg.sender != address(vault)) revert UnauthorizedVault();
(
address recipient,
IERC20[] memory tokens,
uint256[] memory amounts,
uint256[] memory fees,
bytes memory data
) = abi.decode(payload, (address, IERC20[], uint256[], uint256[], bytes));
/// @notice Receives a flash loan from Morpho, forwards it to the recipient and approves the repayment.
/// @param payload The payload containing the recipient, tokens, amounts, and data.
function onMorphoFlashLoan(uint256, bytes calldata payload) external {
if (msg.sender != address(morpho)) revert UnauthorizedMorpho();
(address recipient, IERC20[] memory tokens, uint256[] memory amounts, bytes memory data) = abi.decode(
payload,
(address, IERC20[], uint256[], bytes)
);
address token = address(tokens[0]);

if (isWToken[tokens[0]]) {
IERC4626 wToken = IERC4626(address(tokens[0]));
vault.sendTo(tokens[0], address(this), amounts[0]);
tokens[0] = IERC20(wToken.asset());
amounts[0] = wToken.redeem(amounts[0], recipient, address(this));
IFlashLoanRecipient(recipient).receiveFlashLoan(tokens, amounts, fees, data);
token.safeTransfer(recipient, amounts[0]);
IFlashLoanRecipient(recipient).receiveFlashLoan(tokens, amounts, new uint256[](1), data);

tokens[0].approve(address(wToken), amounts[0] + fees[0]);
wToken.deposit(amounts[0] + fees[0], address(vault));
vault.settle(wToken, amounts[0]);
} else {
vault.sendTo(tokens[0], recipient, amounts[0]);
IFlashLoanRecipient(recipient).receiveFlashLoan(tokens, amounts, fees, data);
tokens[0].transfer(address(vault), amounts[0]);
vault.settle(tokens[0], amounts[0]);
}
token.safeApprove(address(morpho), amounts[0]);
Comment thread
patitonar marked this conversation as resolved.
}

/// @notice Sets a wrapped token for an asset.
/// @param asset The asset to set the wrapped token for.
/// @param token The wrapped token to set.
function setWToken(IERC20 asset, IERC4626 token) external onlyRole(DEFAULT_ADMIN_ROLE) {
wTokens[asset] = token;
isWToken[token] = true;
emit WTokenSet(asset, token, msg.sender);
/// @notice Returns the amount of `token` available to be flash loaned.
/// @param token The token to check.
function available(IERC20 token) external view returns (uint256) {
return token.balanceOf(address(morpho));
}
}

interface IBalancerVaultV3 {
function sendTo(IERC20 token, address to, uint256 amount) external;
function settle(IERC20 token, uint256 amountHint) external returns (uint256 credit);
function unlock(bytes calldata data) external returns (bytes memory);
interface IMorpho {
function flashLoan(address token, uint256 assets, bytes calldata data) external;
}

interface IFlashLoanRecipient {
function receiveFlashLoan(
IERC20[] memory tokens,
uint256[] memory amounts,
uint256[] memory fees,
bytes calldata data
) external;
}

error InsufficientLiquidity();
error InvalidLength();
error UnauthorizedVault();

event WTokenSet(IERC20 indexed asset, IERC4626 indexed wToken, address indexed account);
error UnauthorizedMorpho();
12 changes: 3 additions & 9 deletions deploy/FlashLoan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@ import type { DeployFunction } from "hardhat-deploy/types";
import tenderlify from "./.utils/tenderlify";

const func: DeployFunction = async ({ deployments: { deploy, get }, getNamedAccounts }) => {
const [{ address: flashLoaner }, { address: timelock }, { deployer }] = await Promise.all([
get("Balancer3Vault"),
get("TimelockController"),
getNamedAccounts(),
]);
const [{ address: morpho }, { deployer }] = await Promise.all([get("Morpho"), getNamedAccounts()]);

await tenderlify(
"FlashLoanAdapter",
await deploy("FlashLoanAdapter", {
args: [flashLoaner, timelock],
args: [morpho],
skipIfAlreadyDeployed: !JSON.parse(env[`DEPLOY_FLASH_LOAN`] ?? "false"),
from: deployer,
log: true,
Expand All @@ -21,8 +17,6 @@ const func: DeployFunction = async ({ deployments: { deploy, get }, getNamedAcco
};

func.tags = ["FlashLoan"];
func.dependencies = ["Governance"];
func.skip = async ({ network, deployments }) =>
!!network.config.sunset || !(await deployments.getOrNull("Balancer3Vault"));
func.skip = async ({ network, deployments }) => !!network.config.sunset || !(await deployments.getOrNull("Morpho"));

export default func;
3 changes: 0 additions & 3 deletions deployments/base/Balancer3Vault.json

This file was deleted.

3 changes: 3 additions & 0 deletions deployments/base/Morpho.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"address": "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"
}
3 changes: 3 additions & 0 deletions deployments/optimism/Morpho.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"address": "0xce95AfbB8EA029495c66020883F87aaE8864AF92"
}
Loading
Loading