|
1 | 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | 2 | pragma solidity ^0.8.23; |
3 | 3 |
|
4 | | -import "../../SYBase.sol"; |
5 | | -import "../../../../interfaces/Midas/IDepositVault.sol"; |
6 | | -import "../../../../interfaces/Midas/IRedemptionVault.sol"; |
| 4 | +import "../../SYBaseUpg.sol"; |
| 5 | +import "../../../../interfaces/Midas/IMidasDepositVault.sol"; |
| 6 | +import "../../../../interfaces/Midas/IMidasRedemptionVault.sol"; |
7 | 7 | import "./libraries/DecimalsCorrectionLibrary.sol"; |
8 | 8 | import "./libraries/MidasAdapterLib.sol"; |
9 | 9 |
|
10 | | -contract PendleMidasSY is SYBase { |
| 10 | +contract PendleMidasSY is SYBaseUpg { |
11 | 11 | using DecimalsCorrectionLibrary for uint256; |
12 | 12 | using PMath for uint256; |
13 | 13 |
|
14 | | - bytes32 constant PENDLE_REFERRER_ID = keccak256("midas.referrers.pendle"); |
15 | 14 |
|
| 15 | + bytes32 public constant PENDLE_REFERRER_ID = keccak256("midas.referrers.pendle"); |
| 16 | + |
| 17 | + // solhint-disable immutable-vars-naming |
16 | 18 | address public immutable depositVault; |
17 | 19 | address public immutable redemptionVault; |
18 | 20 | address public immutable mTokenDataFeed; |
| 21 | + address public immutable underlying; |
| 22 | + |
| 23 | + uint256 public immutable yieldTokenUnit; |
| 24 | + uint256 public immutable underlyingUnit; |
19 | 25 |
|
20 | 26 | constructor( |
21 | | - string memory _name, |
22 | | - string memory _symbol, |
23 | 27 | address _mToken, |
24 | 28 | address _depositVault, |
25 | 29 | address _redemptionVault, |
26 | | - address _mTokenDataFeed |
27 | | - ) SYBase(_name, _symbol, _mToken) { |
| 30 | + address _mTokenDataFeed, |
| 31 | + address _underlying |
| 32 | + ) SYBaseUpg(_mToken) { |
28 | 33 | depositVault = _depositVault; |
29 | 34 | redemptionVault = _redemptionVault; |
30 | 35 | mTokenDataFeed = _mTokenDataFeed; |
| 36 | + underlying = _underlying; |
31 | 37 |
|
32 | | - _safeApproveInf(_mToken, redemptionVault); |
| 38 | + yieldTokenUnit = 10 ** MidasAdapterLib.getTokenDecimals(_mToken); |
| 39 | + underlyingUnit = 10 ** MidasAdapterLib.getTokenDecimals(_underlying); |
| 40 | + } |
| 41 | + |
| 42 | + function initialize(string memory _name, string memory _symbol) external initializer { |
| 43 | + __SYBaseUpg_init(_name, _symbol); |
| 44 | + _safeApproveInf(yieldToken, redemptionVault); |
33 | 45 | } |
34 | 46 |
|
35 | 47 | function _deposit( |
36 | 48 | address tokenIn, |
37 | 49 | uint256 amountDeposited |
38 | 50 | ) internal virtual override returns (uint256 /*amountSharesOut*/) { |
39 | | - uint256 balanceBefore = _selfBalance(IERC20(yieldToken)); |
| 51 | + if (tokenIn == yieldToken) { |
| 52 | + return amountDeposited; |
| 53 | + } |
| 54 | + |
| 55 | + uint256 balanceBefore = _selfBalance(yieldToken); |
40 | 56 | _safeApproveInf(tokenIn, depositVault); |
41 | | - IDepositVault(depositVault).depositInstant( |
| 57 | + IMidasDepositVault(depositVault).depositInstant( |
42 | 58 | tokenIn, |
43 | 59 | MidasAdapterLib.tokenAmountToBase18(tokenIn, amountDeposited), |
44 | 60 | 0, |
45 | 61 | PENDLE_REFERRER_ID |
46 | 62 | ); |
47 | | - return _selfBalance(IERC20(yieldToken)) - balanceBefore; |
| 63 | + return _selfBalance(yieldToken) - balanceBefore; |
48 | 64 | } |
49 | 65 |
|
50 | 66 | function _redeem( |
51 | 67 | address receiver, |
52 | 68 | address tokenOut, |
53 | 69 | uint256 amountSharesToRedeem |
54 | 70 | ) internal override returns (uint256 amountTokenOut) { |
55 | | - uint256 balanceBefore = _selfBalance(IERC20(tokenOut)); |
56 | | - // no need to approve as it was already done in the constructor |
57 | | - IRedemptionVault(redemptionVault).redeemInstant(tokenOut, amountSharesToRedeem, 0); |
58 | | - amountTokenOut = balanceBefore - _selfBalance(IERC20(tokenOut)); |
| 71 | + |
| 72 | + if (tokenOut == yieldToken) { |
| 73 | + _transferOut(tokenOut, receiver, amountSharesToRedeem); |
| 74 | + return amountSharesToRedeem; |
| 75 | + } |
| 76 | + |
| 77 | + uint256 balanceBefore = _selfBalance(tokenOut); |
| 78 | + IMidasRedemptionVault(redemptionVault).redeemInstant(tokenOut, amountSharesToRedeem, 0); |
| 79 | + amountTokenOut = balanceBefore - _selfBalance(tokenOut); |
59 | 80 | _transferOut(tokenOut, receiver, amountTokenOut); |
60 | 81 | } |
61 | 82 |
|
62 | 83 | function exchangeRate() public view virtual override returns (uint256) { |
63 | | - return PMath.ONE; |
| 84 | + return IMidasDataFeed(mTokenDataFeed).getDataInBase18() * underlyingUnit / yieldTokenUnit; |
64 | 85 | } |
65 | 86 |
|
66 | 87 | function _previewDeposit( |
67 | 88 | address tokenIn, |
68 | 89 | uint256 amountTokenToDeposit |
69 | 90 | ) internal view override returns (uint256 /*amountSharesOut*/) { |
| 91 | + if (tokenIn == yieldToken) { |
| 92 | + return amountTokenToDeposit; |
| 93 | + } |
| 94 | + |
| 95 | + // amountTokenToDeposit is converted to base 18 inside lib |
70 | 96 | return MidasAdapterLib.estimateAmountOutDeposit(depositVault, mTokenDataFeed, tokenIn, amountTokenToDeposit); |
71 | 97 | } |
72 | 98 |
|
73 | 99 | function _previewRedeem( |
74 | 100 | address tokenOut, |
75 | 101 | uint256 amountSharesToRedeem |
76 | 102 | ) internal view override returns (uint256 /*amountTokenOut*/) { |
| 103 | + if (tokenOut == yieldToken) { |
| 104 | + return amountSharesToRedeem; |
| 105 | + } |
| 106 | + |
| 107 | + // amountTokenOut is converted back to original decimals inside lib |
77 | 108 | return MidasAdapterLib.estimateAmountOutRedeem(redemptionVault, mTokenDataFeed, tokenOut, amountSharesToRedeem); |
78 | 109 | } |
79 | 110 |
|
80 | 111 | function getTokensIn() public view override returns (address[] memory res) { |
81 | | - return IManageableVault(depositVault).getPaymentTokens(); |
| 112 | + return ArrayLib.append(IMidasManageableVault(depositVault).getPaymentTokens(), yieldToken); |
82 | 113 | } |
83 | 114 |
|
84 | 115 | function getTokensOut() public view override returns (address[] memory res) { |
85 | | - return IManageableVault(redemptionVault).getPaymentTokens(); |
| 116 | + return ArrayLib.append(IMidasManageableVault(redemptionVault).getPaymentTokens(), yieldToken); |
86 | 117 | } |
87 | 118 |
|
88 | 119 | function isValidTokenIn(address token) public view override returns (bool) { |
89 | | - return IManageableVault(depositVault).tokensConfig(token).dataFeed != address(0); |
| 120 | + return token == yieldToken || IMidasManageableVault(depositVault).tokensConfig(token).dataFeed != address(0); |
90 | 121 | } |
91 | 122 |
|
92 | 123 | function isValidTokenOut(address token) public view override returns (bool) { |
93 | | - return IManageableVault(redemptionVault).tokensConfig(token).dataFeed != address(0); |
| 124 | + return token == yieldToken || IMidasManageableVault(redemptionVault).tokensConfig(token).dataFeed != address(0); |
94 | 125 | } |
95 | 126 |
|
96 | 127 | function assetInfo() external view returns (AssetType assetType, address assetAddress, uint8 assetDecimals) { |
97 | | - return (AssetType.TOKEN, yieldToken, MidasAdapterLib.getTokenDecimals(yieldToken)); |
| 128 | + return (AssetType.TOKEN, underlying, MidasAdapterLib.getTokenDecimals(underlying)); |
98 | 129 | } |
99 | 130 | } |
0 commit comments