diff --git a/.changeset/perfect-ducks-repair.md b/.changeset/perfect-ducks-repair.md new file mode 100644 index 000000000..44046cf65 --- /dev/null +++ b/.changeset/perfect-ducks-repair.md @@ -0,0 +1,6 @@ +--- +"@enzymefinance/abis": minor +"@enzymefinance/sdk": minor +--- + +Add Morpho flash loan asset manager diff --git a/packages/abis/abis/IMorphoBlueFlashLoanAssetManager.abi.json b/packages/abis/abis/IMorphoBlueFlashLoanAssetManager.abi.json new file mode 100644 index 000000000..03c273c1d --- /dev/null +++ b/packages/abis/abis/IMorphoBlueFlashLoanAssetManager.abi.json @@ -0,0 +1,156 @@ +[ + { + "type": "constructor", + "inputs": [ + { + "name": "_morphoBlueAddress", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "flashLoan", + "inputs": [ + { + "name": "_assetAddress", + "type": "address", + "internalType": "address" + }, + { + "name": "_amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_calls", + "type": "tuple[]", + "internalType": "struct IMorphoBlueFlashLoanAssetManager.Call[]", + "components": [ + { + "name": "target", + "type": "address", + "internalType": "address" + }, + { + "name": "data", + "type": "bytes", + "internalType": "bytes" + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "getBorrowedAssetsRecipient", + "inputs": [], + "outputs": [ + { + "name": "borrowedAssetsRecipient_", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getOwner", + "inputs": [], + "outputs": [ + { + "name": "owner_", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "init", + "inputs": [ + { + "name": "_owner", + "type": "address", + "internalType": "address" + }, + { + "name": "_borrowedAssetsRecipient", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onMorphoFlashLoan", + "inputs": [ + { + "name": "_amount", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "_data", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "BorrowedAssetsRecipientSet", + "inputs": [ + { + "name": "borrowedAssetsRecipient", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OwnerSet", + "inputs": [ + { + "name": "owner", + "type": "address", + "indexed": false, + "internalType": "address" + } + ], + "anonymous": false + }, + { + "type": "error", + "name": "MorphoBlueFlashLoanAssetManager__FlashLoan__Unauthorized", + "inputs": [] + }, + { + "type": "error", + "name": "MorphoBlueFlashLoanAssetManager__Init__AlreadyInitialized", + "inputs": [] + }, + { + "type": "error", + "name": "MorphoBlueFlashLoanAssetManager__OnMorphoFlashLoan__UnauthorizedCaller", + "inputs": [] + }, + { + "type": "error", + "name": "MorphoBlueFlashLoanAssetManager__OnMorphoFlashLoan__UnauthorizedInitiator", + "inputs": [] + } +] diff --git a/packages/abis/abis/IMorphoBlueFlashLoanAssetManager.sol b/packages/abis/abis/IMorphoBlueFlashLoanAssetManager.sol new file mode 100644 index 000000000..e39a03457 --- /dev/null +++ b/packages/abis/abis/IMorphoBlueFlashLoanAssetManager.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.6.0 <0.9.0; + +interface IMorphoBlueFlashLoanAssetManager { + struct Call { + address target; + bytes data; + } + + error MorphoBlueFlashLoanAssetManager__FlashLoan__Unauthorized(); + error MorphoBlueFlashLoanAssetManager__Init__AlreadyInitialized(); + error MorphoBlueFlashLoanAssetManager__OnMorphoFlashLoan__UnauthorizedCaller(); + error MorphoBlueFlashLoanAssetManager__OnMorphoFlashLoan__UnauthorizedInitiator(); + + event BorrowedAssetsRecipientSet(address borrowedAssetsRecipient); + event OwnerSet(address owner); + + function flashLoan(address _assetAddress, uint256 _amount, Call[] memory _calls) external; + function getBorrowedAssetsRecipient() external view returns (address borrowedAssetsRecipient_); + function getOwner() external view returns (address owner_); + function init(address _owner, address _borrowedAssetsRecipient) external; + function onMorphoFlashLoan(uint256 _amount, bytes memory _data) external; +} diff --git a/packages/abis/src/IMorphoBlueFlashLoanAssetManager.ts b/packages/abis/src/IMorphoBlueFlashLoanAssetManager.ts new file mode 100644 index 000000000..7257ecce1 --- /dev/null +++ b/packages/abis/src/IMorphoBlueFlashLoanAssetManager.ts @@ -0,0 +1,156 @@ +export const IMorphoBlueFlashLoanAssetManager = [ + { + type: "constructor", + inputs: [ + { + name: "_morphoBlueAddress", + type: "address", + internalType: "address", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "flashLoan", + inputs: [ + { + name: "_assetAddress", + type: "address", + internalType: "address", + }, + { + name: "_amount", + type: "uint256", + internalType: "uint256", + }, + { + name: "_calls", + type: "tuple[]", + internalType: "struct IMorphoBlueFlashLoanAssetManager.Call[]", + components: [ + { + name: "target", + type: "address", + internalType: "address", + }, + { + name: "data", + type: "bytes", + internalType: "bytes", + }, + ], + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "getBorrowedAssetsRecipient", + inputs: [], + outputs: [ + { + name: "borrowedAssetsRecipient_", + type: "address", + internalType: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getOwner", + inputs: [], + outputs: [ + { + name: "owner_", + type: "address", + internalType: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "init", + inputs: [ + { + name: "_owner", + type: "address", + internalType: "address", + }, + { + name: "_borrowedAssetsRecipient", + type: "address", + internalType: "address", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "onMorphoFlashLoan", + inputs: [ + { + name: "_amount", + type: "uint256", + internalType: "uint256", + }, + { + name: "_data", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "event", + name: "BorrowedAssetsRecipientSet", + inputs: [ + { + name: "borrowedAssetsRecipient", + type: "address", + indexed: false, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "OwnerSet", + inputs: [ + { + name: "owner", + type: "address", + indexed: false, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "error", + name: "MorphoBlueFlashLoanAssetManager__FlashLoan__Unauthorized", + inputs: [], + }, + { + type: "error", + name: "MorphoBlueFlashLoanAssetManager__Init__AlreadyInitialized", + inputs: [], + }, + { + type: "error", + name: "MorphoBlueFlashLoanAssetManager__OnMorphoFlashLoan__UnauthorizedCaller", + inputs: [], + }, + { + type: "error", + name: "MorphoBlueFlashLoanAssetManager__OnMorphoFlashLoan__UnauthorizedInitiator", + inputs: [], + }, +] as const; diff --git a/packages/abis/src/index.ts b/packages/abis/src/index.ts index d0196358c..98cff2930 100644 --- a/packages/abis/src/index.ts +++ b/packages/abis/src/index.ts @@ -100,6 +100,7 @@ export { IMigrationHookHandler } from "./IMigrationHookHandler.js"; export { IMinAssetBalancesPostRedemptionPolicy } from "./IMinAssetBalancesPostRedemptionPolicy.js"; export { IMinMaxInvestmentPolicy } from "./IMinMaxInvestmentPolicy.js"; export { IMinSharesSupplyFee } from "./IMinSharesSupplyFee.js"; +export { IMorphoBlueFlashLoanAssetManager } from "./IMorphoBlueFlashLoanAssetManager.js"; export { IMorphoBluePositionLib } from "./IMorphoBluePositionLib.js"; export { IMorphoBluePositionParser } from "./IMorphoBluePositionParser.js"; export { INoDepegOnRedeemSharesForSpecificAssetsPolicy } from "./INoDepegOnRedeemSharesForSpecificAssetsPolicy.js"; diff --git a/packages/sdk/src/Portfolio/AssetManagers.ts b/packages/sdk/src/Portfolio/AssetManagers.ts index fa6d72446..38de53d3e 100644 --- a/packages/sdk/src/Portfolio/AssetManagers.ts +++ b/packages/sdk/src/Portfolio/AssetManagers.ts @@ -1,2 +1,3 @@ export * as AaveV3FlashLoanAssetManager from "./AssetManagers/AaveV3FlashLoanAssetManager.js"; +export * as MorphoBlueFlashLoanAssetManager from "./AssetManagers/MorphoBlueFlashLoanAssetManager.js"; export * as SharePriceThrottledAssetManager from "./AssetManagers/SharePriceThrottledAssetManager.js"; diff --git a/packages/sdk/src/Portfolio/AssetManagers/MorphoBlueFlashLoanAssetManager.ts b/packages/sdk/src/Portfolio/AssetManagers/MorphoBlueFlashLoanAssetManager.ts new file mode 100644 index 000000000..59f9f093a --- /dev/null +++ b/packages/sdk/src/Portfolio/AssetManagers/MorphoBlueFlashLoanAssetManager.ts @@ -0,0 +1,77 @@ +import { IDispatcherOwnedBeaconFactory, IMorphoBlueFlashLoanAssetManager } from "@enzymefinance/abis"; +import { type Address, type Client, type Hex, encodeFunctionData } from "viem"; +import { readContract } from "viem/actions"; +import { Viem } from "../../Utils.js"; + +//-------------------------------------------------------------------------------------------- +// FACTORY +//-------------------------------------------------------------------------------------------- + +export function encodeDeployProxyConstructData(args: { + owner: Address; + borrowedAssetsRecipient: Address; +}) { + return encodeFunctionData({ + abi: IMorphoBlueFlashLoanAssetManager, + functionName: "init", + args: [args.owner, args.borrowedAssetsRecipient], + }); +} + +export function deployProxy(args: { + dispatcherOwnedBeaconFactory: Address; + constructData: Hex; +}) { + return new Viem.PopulatedTransaction({ + abi: IDispatcherOwnedBeaconFactory, + functionName: "deployProxy", + address: args.dispatcherOwnedBeaconFactory, + args: [args.constructData], + }); +} + +//-------------------------------------------------------------------------------------------- +// LIB +//-------------------------------------------------------------------------------------------- + +export function flashLoan(args: { + aaveV3FlashLoanAssetManager: Address; + asset: Address; + amount: bigint; + calls: ReadonlyArray<{ target: Address; data: Hex }>; +}) { + return new Viem.PopulatedTransaction({ + abi: IMorphoBlueFlashLoanAssetManager, + functionName: "flashLoan", + address: args.aaveV3FlashLoanAssetManager, + args: [args.asset, args.amount, args.calls], + }); +} + +export function getBorrowedAssetsRecipient( + client: Client, + args: Viem.ContractCallParameters<{ + aaveV3FlashLoanAssetManager: Address; + }>, +) { + return readContract(client, { + ...Viem.extractBlockParameters(args), + abi: IMorphoBlueFlashLoanAssetManager, + functionName: "getBorrowedAssetsRecipient", + address: args.aaveV3FlashLoanAssetManager, + }); +} + +export function getOwner( + client: Client, + args: Viem.ContractCallParameters<{ + aaveV3FlashLoanAssetManager: Address; + }>, +) { + return readContract(client, { + ...Viem.extractBlockParameters(args), + abi: IMorphoBlueFlashLoanAssetManager, + functionName: "getOwner", + address: args.aaveV3FlashLoanAssetManager, + }); +}