generated from PaulRBerg/foundry-template
-
Notifications
You must be signed in to change notification settings - Fork 3
/
MorphoPendleWrapper.sol
58 lines (42 loc) · 2.19 KB
/
MorphoPendleWrapper.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// SPDX-License-Identifier: MIT
// Thanks to ultrasecr.eth
pragma solidity ^0.8.19;
import { IMorphoFlashLoanCallback } from "../morpho/interfaces/IMorphoFlashLoanCallback.sol";
import { IMorpho } from "../morpho/interfaces/IMorpho.sol";
import { IPendleRouterV3 } from "./interfaces/IPendleRouterV3.sol";
import { IPPrincipalToken } from "./interfaces/IPPrincipalToken.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC7399, IERC20 } from "../BaseWrapper.sol";
import { BasePendleWrapper } from "./BasePendleWrapper.sol";
/// @dev Pendle Flash Lender that uses Morpho Pools as source of X liquidity,
/// then deposits X on Pendle to borrow whatever's necessary.
contract MorphoPendleWrapper is BasePendleWrapper, IMorphoFlashLoanCallback {
using SafeERC20 for IERC20;
error NotMorpho();
uint256 private constant FEE = 0;
IMorpho public immutable morpho;
constructor(IMorpho _morpho, IPendleRouterV3 _pendleRouter) BasePendleWrapper(_pendleRouter) {
morpho = _morpho;
}
/// @inheritdoc IERC7399
function maxFlashLoan(address asset) public view returns (uint256) {
if (IPPrincipalToken(asset).isExpired()) return 0;
return IPPrincipalToken(asset).SY().yieldToken().balanceOf(address(morpho));
}
/// @inheritdoc IERC7399
function flashFee(address asset, uint256 amount) external view returns (uint256) {
uint256 max = maxFlashLoan(asset);
return amount >= max ? type(uint256).max : FEE;
}
function _flashLoan(address asset, uint256 amount, bytes memory data) internal override {
address underlying = address(IPPrincipalToken(asset).SY().yieldToken());
bytes memory metadata = abi.encode(underlying, asset, data);
morpho.flashLoan(underlying, amount, metadata);
}
function onMorphoFlashLoan(uint256 amount, bytes calldata params) external override {
if (msg.sender != address(morpho)) revert NotMorpho();
(IERC20 underlying, IERC20 asset, bytes memory data) = abi.decode(params, (IERC20, IERC20, bytes));
_handleFlashLoan(underlying, asset, amount, FEE, data);
_approveRepayment(address(underlying), amount, FEE);
}
}