@pendle/core-v2 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/LICENSE +100 -0
  2. package/contracts/SuperComposableYield/ISuperComposableYield.sol +68 -0
  3. package/contracts/SuperComposableYield/SCYUtils.sol +14 -0
  4. package/contracts/SuperComposableYield/implementations/RewardManager.sol +117 -0
  5. package/contracts/SuperComposableYield/implementations/SCYBase.sol +126 -0
  6. package/contracts/SuperComposableYield/implementations/SCYBaseWithRewards.sol +79 -0
  7. package/contracts/core/PendleBaseToken.sol +39 -0
  8. package/contracts/core/PendleMarket.sol +248 -0
  9. package/contracts/core/PendleMarketFactory.sol +60 -0
  10. package/contracts/core/PendleOwnershipToken.sol +44 -0
  11. package/contracts/core/PendleSCYImpl/AaveV3/PendleAaveV3SCY.sol +139 -0
  12. package/contracts/core/PendleSCYImpl/AaveV3/WadRayMath.sol +126 -0
  13. package/contracts/core/PendleSCYImpl/PendleBenQiErc20SCY.sol +127 -0
  14. package/contracts/core/PendleSCYImpl/PendleBtrflySCY.sol +125 -0
  15. package/contracts/core/PendleSCYImpl/PendleYearnVaultSCY.sol +115 -0
  16. package/contracts/core/PendleYieldContractFactory.sol +109 -0
  17. package/contracts/core/PendleYieldToken.sol +240 -0
  18. package/contracts/core/misc/BoringOwnable.sol +62 -0
  19. package/contracts/core/misc/BoringOwnableUpg.sol +64 -0
  20. package/contracts/core/misc/PendleJoeSwapHelperUpg.sol +82 -0
  21. package/contracts/core/router/PendleRouterCoreUpg.sol +219 -0
  22. package/contracts/core/router/PendleRouterProxy.sol +64 -0
  23. package/contracts/core/router/PendleRouterYTUpg.sol +134 -0
  24. package/contracts/core/router/base/PendleRouterOTBaseUpg.sol +218 -0
  25. package/contracts/core/router/base/PendleRouterSCYAndForgeBaseUpg.sol +141 -0
  26. package/contracts/core/router/base/PendleRouterYTBaseUpg.sol +212 -0
  27. package/contracts/interfaces/IAToken.sol +34 -0
  28. package/contracts/interfaces/IAavePool.sol +41 -0
  29. package/contracts/interfaces/IAaveRewardsController.sol +32 -0
  30. package/contracts/interfaces/IBenQiComptroller.sol +33 -0
  31. package/contracts/interfaces/IJoePair.sol +98 -0
  32. package/contracts/interfaces/IJoeRouter01.sol +162 -0
  33. package/contracts/interfaces/IPBaseToken.sol +9 -0
  34. package/contracts/interfaces/IPFlashCallBack.sol +10 -0
  35. package/contracts/interfaces/IPGovernanceManager.sol +28 -0
  36. package/contracts/interfaces/IPMarket.sol +57 -0
  37. package/contracts/interfaces/IPMarketAddRemoveCallback.sol +18 -0
  38. package/contracts/interfaces/IPMarketFactory.sol +8 -0
  39. package/contracts/interfaces/IPMarketSwapCallback.sol +10 -0
  40. package/contracts/interfaces/IPOwnershipToken.sol +15 -0
  41. package/contracts/interfaces/IPPermissionsV2.sol +28 -0
  42. package/contracts/interfaces/IPRouterCore.sol +108 -0
  43. package/contracts/interfaces/IPRouterYT.sol +47 -0
  44. package/contracts/interfaces/IPYieldContractFactory.sol +36 -0
  45. package/contracts/interfaces/IPYieldToken.sol +19 -0
  46. package/contracts/interfaces/IQiErc20.sol +35 -0
  47. package/contracts/interfaces/IQiToken.sol +29 -0
  48. package/contracts/interfaces/IREDACTEDStaking.sol +35 -0
  49. package/contracts/interfaces/IWETH.sol +34 -0
  50. package/contracts/interfaces/IWXBTRFLY.sol +37 -0
  51. package/contracts/interfaces/IYearnVault.sol +32 -0
  52. package/contracts/libraries/JoeLibrary.sol +121 -0
  53. package/contracts/libraries/SCYIndex.sol +55 -0
  54. package/contracts/libraries/helpers/ExpiryUtilsLib.sol +166 -0
  55. package/contracts/libraries/math/FixedPoint.sol +208 -0
  56. package/contracts/libraries/math/LogExpMath.sol +515 -0
  57. package/contracts/libraries/math/MarketApproxLib.sol +140 -0
  58. package/contracts/libraries/math/MarketMathLib.sol +606 -0
  59. package/contracts/periphery/PendleGovernanceManager.sol +36 -0
  60. package/contracts/periphery/PermissionsV2.sol +23 -0
  61. package/package.json +76 -0
  62. package/typechain-types/BoringOwnable.ts +194 -0
  63. package/typechain-types/BoringOwnableData.ts +100 -0
  64. package/typechain-types/BoringOwnableUpg.ts +194 -0
  65. package/typechain-types/BoringOwnableUpgData.ts +100 -0
  66. package/typechain-types/ERC1967UpgradeUpgradeable.ts +97 -0
  67. package/typechain-types/ERC20.ts +417 -0
  68. package/typechain-types/IAToken.ts +331 -0
  69. package/typechain-types/IAavePool.ts +192 -0
  70. package/typechain-types/IAaveRewardsController.ts +148 -0
  71. package/typechain-types/IBeaconUpgradeable.ts +87 -0
  72. package/typechain-types/IBenQiComptroller.ts +125 -0
  73. package/typechain-types/IERC1822ProxiableUpgradeable.ts +87 -0
  74. package/typechain-types/IERC20.ts +300 -0
  75. package/typechain-types/IERC20Metadata.ts +339 -0
  76. package/typechain-types/IJoePair.ts +888 -0
  77. package/typechain-types/IJoeRouter01.ts +1107 -0
  78. package/typechain-types/IPBaseToken.ts +365 -0
  79. package/typechain-types/IPFlashCallback.ts +115 -0
  80. package/typechain-types/IPGovernanceManager.ts +84 -0
  81. package/typechain-types/IPMarket.ts +701 -0
  82. package/typechain-types/IPMarketAddRemoveCallback.ts +169 -0
  83. package/typechain-types/IPMarketFactory.ts +109 -0
  84. package/typechain-types/IPMarketSwapCallback.ts +115 -0
  85. package/typechain-types/IPOwnershipToken.ts +488 -0
  86. package/typechain-types/IPRouterCore.ts +759 -0
  87. package/typechain-types/IPRouterYT.ts +405 -0
  88. package/typechain-types/IPYieldContractFactory.ts +192 -0
  89. package/typechain-types/IPYieldToken.ts +525 -0
  90. package/typechain-types/IPermissionsV2.ts +87 -0
  91. package/typechain-types/IQiErc20.ts +402 -0
  92. package/typechain-types/IQiToken.ts +327 -0
  93. package/typechain-types/IREDACTEDStaking.ts +216 -0
  94. package/typechain-types/ISuperComposableYield.ts +652 -0
  95. package/typechain-types/IWETH.ts +380 -0
  96. package/typechain-types/IWXBTRFLY.ts +254 -0
  97. package/typechain-types/IYearnVault.ts +152 -0
  98. package/typechain-types/PendleAaveV3SCY.ts +901 -0
  99. package/typechain-types/PendleBaseToken.ts +505 -0
  100. package/typechain-types/PendleBenQiErc20SCY.ts +914 -0
  101. package/typechain-types/PendleBtrflyScy.ts +794 -0
  102. package/typechain-types/PendleGovernanceManager.ts +187 -0
  103. package/typechain-types/PendleJoeSwapHelperUpg.ts +97 -0
  104. package/typechain-types/PendleMarket.ts +1008 -0
  105. package/typechain-types/PendleMarketFactory.ts +246 -0
  106. package/typechain-types/PendleOwnershipToken.ts +628 -0
  107. package/typechain-types/PendleRouterCoreUpg.ts +780 -0
  108. package/typechain-types/PendleRouterProxy.ts +417 -0
  109. package/typechain-types/PendleRouterSCYAndForgeBaseUpg.ts +98 -0
  110. package/typechain-types/PendleRouterYTBaseUpg.ts +134 -0
  111. package/typechain-types/PendleRouterYTUpg.ts +453 -0
  112. package/typechain-types/PendleYearnVaultScy.ts +784 -0
  113. package/typechain-types/PendleYieldContractFactory.ts +479 -0
  114. package/typechain-types/PendleYieldToken.ts +1030 -0
  115. package/typechain-types/PermissionsV2.ts +87 -0
  116. package/typechain-types/Proxy.ts +57 -0
  117. package/typechain-types/RewardManager.ts +172 -0
  118. package/typechain-types/SCYBase.ts +734 -0
  119. package/typechain-types/SCYBaseWithRewards.ts +819 -0
  120. package/typechain-types/UUPSUpgradeable.ts +197 -0
  121. package/typechain-types/common.ts +44 -0
  122. package/typechain-types/factories/BoringOwnableData__factory.ts +90 -0
  123. package/typechain-types/factories/BoringOwnableUpgData__factory.ts +94 -0
  124. package/typechain-types/factories/BoringOwnableUpg__factory.ts +139 -0
  125. package/typechain-types/factories/BoringOwnable__factory.ts +149 -0
  126. package/typechain-types/factories/ERC1967UpgradeUpgradeable__factory.ts +75 -0
  127. package/typechain-types/factories/ERC20__factory.ts +348 -0
  128. package/typechain-types/factories/IAToken__factory.ts +225 -0
  129. package/typechain-types/factories/IAavePool__factory.ts +99 -0
  130. package/typechain-types/factories/IAaveRewardsController__factory.ts +78 -0
  131. package/typechain-types/factories/IBeaconUpgradeable__factory.ts +39 -0
  132. package/typechain-types/factories/IBenQiComptroller__factory.ts +59 -0
  133. package/typechain-types/factories/IERC1822ProxiableUpgradeable__factory.ts +43 -0
  134. package/typechain-types/factories/IERC20Metadata__factory.ts +248 -0
  135. package/typechain-types/factories/IERC20__factory.ts +203 -0
  136. package/typechain-types/factories/IJoePair__factory.ts +674 -0
  137. package/typechain-types/factories/IJoeRouter01__factory.ts +772 -0
  138. package/typechain-types/factories/IPBaseToken__factory.ts +271 -0
  139. package/typechain-types/factories/IPFlashCallback__factory.ts +49 -0
  140. package/typechain-types/factories/IPGovernanceManager__factory.ts +39 -0
  141. package/typechain-types/factories/IPMarketAddRemoveCallback__factory.ts +86 -0
  142. package/typechain-types/factories/IPMarketFactory__factory.ts +58 -0
  143. package/typechain-types/factories/IPMarketSwapCallback__factory.ts +53 -0
  144. package/typechain-types/factories/IPMarket__factory.ts +559 -0
  145. package/typechain-types/factories/IPOwnershipToken__factory.ts +349 -0
  146. package/typechain-types/factories/IPRouterCore__factory.ts +516 -0
  147. package/typechain-types/factories/IPRouterYT__factory.ts +246 -0
  148. package/typechain-types/factories/IPYieldContractFactory__factory.ts +117 -0
  149. package/typechain-types/factories/IPYieldToken__factory.ts +383 -0
  150. package/typechain-types/factories/IPermissionsV2__factory.ts +39 -0
  151. package/typechain-types/factories/IQiErc20__factory.ts +270 -0
  152. package/typechain-types/factories/IQiToken__factory.ts +219 -0
  153. package/typechain-types/factories/IREDACTEDStaking__factory.ts +107 -0
  154. package/typechain-types/factories/ISuperComposableYield__factory.ts +438 -0
  155. package/typechain-types/factories/IWETH__factory.ts +261 -0
  156. package/typechain-types/factories/IWXBTRFLY__factory.ts +131 -0
  157. package/typechain-types/factories/IYearnVault__factory.ts +74 -0
  158. package/typechain-types/factories/PendleAaveV3SCY__factory.ts +727 -0
  159. package/typechain-types/factories/PendleBaseToken__factory.ts +386 -0
  160. package/typechain-types/factories/PendleBenQiErc20SCY__factory.ts +753 -0
  161. package/typechain-types/factories/PendleBtrflyScy__factory.ts +652 -0
  162. package/typechain-types/factories/PendleGovernanceManager__factory.ts +149 -0
  163. package/typechain-types/factories/PendleJoeSwapHelperUpg__factory.ts +56 -0
  164. package/typechain-types/factories/PendleMarketFactory__factory.ts +207 -0
  165. package/typechain-types/factories/PendleMarket__factory.ts +891 -0
  166. package/typechain-types/factories/PendleOwnershipToken__factory.ts +565 -0
  167. package/typechain-types/factories/PendleRouterCoreUpg__factory.ts +620 -0
  168. package/typechain-types/factories/PendleRouterProxy__factory.ts +316 -0
  169. package/typechain-types/factories/PendleRouterSCYAndForgeBaseUpg__factory.ts +56 -0
  170. package/typechain-types/factories/PendleRouterYTBaseUpg__factory.ts +66 -0
  171. package/typechain-types/factories/PendleRouterYTUpg__factory.ts +363 -0
  172. package/typechain-types/factories/PendleYearnVaultScy__factory.ts +630 -0
  173. package/typechain-types/factories/PendleYieldContractFactory__factory.ts +368 -0
  174. package/typechain-types/factories/PendleYieldToken__factory.ts +814 -0
  175. package/typechain-types/factories/PermissionsV2__factory.ts +36 -0
  176. package/typechain-types/factories/Proxy__factory.ts +28 -0
  177. package/typechain-types/factories/RewardManager__factory.ts +89 -0
  178. package/typechain-types/factories/SCYBaseWithRewards__factory.ts +535 -0
  179. package/typechain-types/factories/SCYBase__factory.ts +479 -0
  180. package/typechain-types/factories/UUPSUpgradeable__factory.ts +115 -0
  181. package/typechain-types/hardhat.d.ts +564 -0
  182. package/typechain-types/index.ts +122 -0
@@ -0,0 +1,248 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity 0.8.9;
3
+
4
+ import "./PendleBaseToken.sol";
5
+ import "../interfaces/IPOwnershipToken.sol";
6
+ import "../SuperComposableYield/ISuperComposableYield.sol";
7
+ import "../interfaces/IPMarket.sol";
8
+ import "../interfaces/IPMarketFactory.sol";
9
+ import "../interfaces/IPMarketSwapCallback.sol";
10
+ import "../interfaces/IPMarketAddRemoveCallback.sol";
11
+
12
+ import "../libraries/math/LogExpMath.sol";
13
+ import "../libraries/math/FixedPoint.sol";
14
+ import "../libraries/math/MarketMathLib.sol";
15
+
16
+ import "openzeppelin-solidity/contracts/token/ERC20/utils/SafeERC20.sol";
17
+ import "openzeppelin-solidity/contracts/security/ReentrancyGuard.sol";
18
+
19
+ // solhint-disable reason-string
20
+ contract PendleMarket is PendleBaseToken, IPMarket, ReentrancyGuard {
21
+ using FixedPoint for uint256;
22
+ using FixedPoint for int256;
23
+ using FixedPoint for uint128;
24
+ using LogExpMath for uint256;
25
+ using MarketMathLib for MarketParameters;
26
+ using SafeERC20 for IERC20;
27
+
28
+ string private constant NAME = "Pendle Market";
29
+ string private constant SYMBOL = "PENDLE-LPT";
30
+ uint256 private constant MINIMUM_LIQUIDITY = 10**3;
31
+ uint8 private constant DECIMALS = 18;
32
+ int256 internal constant RATE_PRECISION = 1e9;
33
+
34
+ address public immutable OT;
35
+ address public immutable SCY;
36
+ address public immutable YT;
37
+
38
+ int256 public immutable scalarRoot;
39
+ uint256 public immutable feeRateRoot; // allow fee to be changable?
40
+ int256 public immutable anchorRoot;
41
+
42
+ uint256 public immutable rateOracleTimeWindow;
43
+ int8 public immutable reserveFeePercent;
44
+
45
+ MarketStorage public marketStorage;
46
+
47
+ constructor(
48
+ address _OT,
49
+ uint256 _rateOracleTimeWindow,
50
+ uint256 _feeRateRoot,
51
+ int256 _scalarRoot,
52
+ int256 _anchorRoot,
53
+ uint8 _reserveFeePercent
54
+ ) PendleBaseToken(NAME, SYMBOL, 18, IPOwnershipToken(_OT).expiry()) {
55
+ OT = _OT;
56
+ SCY = IPOwnershipToken(_OT).SCY();
57
+ YT = IPOwnershipToken(_OT).YT();
58
+ feeRateRoot = _feeRateRoot;
59
+ scalarRoot = _scalarRoot;
60
+ rateOracleTimeWindow = _rateOracleTimeWindow;
61
+
62
+ require(_reserveFeePercent <= 100, "invalid fee rate");
63
+ reserveFeePercent = int8(_reserveFeePercent);
64
+ anchorRoot = _anchorRoot;
65
+ }
66
+
67
+ function addLiquidity(
68
+ address receiver,
69
+ uint256 scyDesired,
70
+ uint256 otDesired,
71
+ bytes calldata data
72
+ )
73
+ external
74
+ nonReentrant
75
+ returns (
76
+ uint256 lpToAccount,
77
+ uint256 scyUsed,
78
+ uint256 otUsed
79
+ )
80
+ {
81
+ MarketParameters memory market = readState();
82
+ SCYIndex index = SCYIndexLib.newIndex(SCY);
83
+
84
+ uint256 lpToReserve;
85
+ (lpToReserve, lpToAccount, scyUsed, otUsed) = market.addLiquidity(
86
+ index,
87
+ scyDesired,
88
+ otDesired
89
+ );
90
+
91
+ // initializing the market
92
+ if (lpToReserve != 0) {
93
+ market.setInitialImpliedRate(index, anchorRoot, block.timestamp);
94
+ _mint(address(1), lpToReserve);
95
+ }
96
+
97
+ _mint(receiver, lpToAccount);
98
+
99
+ if (data.length > 0) {
100
+ IPMarketAddRemoveCallback(msg.sender).addLiquidityCallback(
101
+ lpToAccount,
102
+ scyUsed,
103
+ otUsed,
104
+ data
105
+ );
106
+ }
107
+
108
+ require(market.totalOt.Uint() <= IERC20(OT).balanceOf(address(this)));
109
+ require(market.totalScy.Uint() <= IERC20(SCY).balanceOf(address(this)));
110
+
111
+ _writeState(market);
112
+ }
113
+
114
+ function removeLiquidity(
115
+ address receiver,
116
+ uint256 lpToRemove,
117
+ bytes calldata data
118
+ ) external nonReentrant returns (uint256 scyToAccount, uint256 otToAccount) {
119
+ MarketParameters memory market = readState();
120
+
121
+ (scyToAccount, otToAccount) = market.removeLiquidity(lpToRemove);
122
+
123
+ IERC20(SCY).safeTransfer(receiver, scyToAccount);
124
+ IERC20(OT).safeTransfer(receiver, otToAccount);
125
+
126
+ if (data.length > 0) {
127
+ IPMarketAddRemoveCallback(msg.sender).removeLiquidityCallback(
128
+ lpToRemove,
129
+ scyToAccount,
130
+ otToAccount,
131
+ data
132
+ );
133
+ }
134
+
135
+ _burn(address(this), lpToRemove);
136
+
137
+ _writeState(market);
138
+ }
139
+
140
+ function swapExactOtForScy(
141
+ address receiver,
142
+ uint256 exactOtIn,
143
+ uint256 minScyOut,
144
+ bytes calldata data
145
+ ) external nonReentrant returns (uint256 netScyOut, uint256 netScyToReserve) {
146
+ require(block.timestamp < expiry, "MARKET_EXPIRED");
147
+
148
+ MarketParameters memory market = readState();
149
+
150
+ (netScyOut, netScyToReserve) = market.swapExactOtForScy(
151
+ SCYIndexLib.newIndex(SCY),
152
+ exactOtIn,
153
+ block.timestamp
154
+ );
155
+ require(netScyOut >= minScyOut, "insufficient scy out");
156
+ IERC20(SCY).safeTransfer(receiver, netScyOut);
157
+ IERC20(SCY).safeTransfer(IPMarketFactory(factory).treasury(), netScyToReserve);
158
+
159
+ if (data.length > 0) {
160
+ IPMarketSwapCallback(msg.sender).swapCallback(exactOtIn.neg(), netScyOut.Int(), data);
161
+ }
162
+
163
+ // have received enough OT
164
+ require(market.totalOt.Uint() <= IERC20(OT).balanceOf(address(this)));
165
+ _writeState(market);
166
+ }
167
+
168
+ function swapScyForExactOt(
169
+ address receiver,
170
+ uint256 exactOtOut,
171
+ uint256 maxScyIn,
172
+ bytes calldata data
173
+ ) external nonReentrant returns (uint256 netScyIn, uint256 netScyToReserve) {
174
+ require(block.timestamp < expiry, "MARKET_EXPIRED");
175
+
176
+ MarketParameters memory market = readState();
177
+
178
+ (netScyIn, netScyToReserve) = market.swapScyForExactOt(
179
+ SCYIndexLib.newIndex(SCY),
180
+ exactOtOut,
181
+ block.timestamp
182
+ );
183
+ require(netScyIn <= maxScyIn, "scy in exceed limit");
184
+ IERC20(OT).safeTransfer(receiver, exactOtOut);
185
+ IERC20(SCY).safeTransfer(IPMarketFactory(factory).treasury(), netScyToReserve);
186
+
187
+ if (data.length > 0) {
188
+ IPMarketSwapCallback(msg.sender).swapCallback(exactOtOut.Int(), netScyIn.neg(), data);
189
+ }
190
+
191
+ // have received enough SCY
192
+ require(market.totalScy.Uint() <= IERC20(SCY).balanceOf(address(this)));
193
+ _writeState(market);
194
+ }
195
+
196
+ /// @dev this function is just a place holder. Later on the rewards will be transferred to the liquidity minining
197
+ /// instead
198
+ function redeemScyReward() external returns (uint256[] memory outAmounts) {
199
+ outAmounts = ISuperComposableYield(SCY).redeemReward(
200
+ address(this),
201
+ IPMarketFactory(factory).treasury()
202
+ );
203
+ }
204
+
205
+ /// the only non-view part in this function is the ISuperComposableYield(SCY).scyIndexCurrent()
206
+ function readState() public view returns (MarketParameters memory market) {
207
+ MarketStorage storage store = marketStorage;
208
+ market.totalOt = store.totalOt;
209
+ market.totalScy = store.totalScy;
210
+ market.totalLp = totalSupply().Int();
211
+ market.oracleRate = store.oracleRate;
212
+ market.reserveFeePercent = reserveFeePercent;
213
+
214
+ market.scalarRoot = scalarRoot;
215
+ market.feeRateRoot = feeRateRoot;
216
+ market.rateOracleTimeWindow = rateOracleTimeWindow;
217
+ market.expiry = expiry;
218
+
219
+ market.lastImpliedRate = store.lastImpliedRate;
220
+ market.lastTradeTime = store.lastTradeTime;
221
+
222
+ market.updateNewRateOracle(block.timestamp);
223
+ }
224
+
225
+ function _writeState(MarketParameters memory market) internal {
226
+ MarketStorage storage store = marketStorage;
227
+
228
+ store.totalOt = market.totalOt.Int128();
229
+ store.totalScy = market.totalScy.Int128();
230
+ store.lastImpliedRate = market.lastImpliedRate.Uint112();
231
+ store.oracleRate = market.oracleRate.Uint112();
232
+ store.lastTradeTime = market.lastTradeTime.Uint32();
233
+ }
234
+
235
+ function readTokens()
236
+ external
237
+ view
238
+ returns (
239
+ ISuperComposableYield _SCY,
240
+ IPOwnershipToken _OT,
241
+ IPYieldToken _YT
242
+ )
243
+ {
244
+ _SCY = ISuperComposableYield(SCY);
245
+ _OT = IPOwnershipToken(OT);
246
+ _YT = IPYieldToken(YT);
247
+ }
248
+ }
@@ -0,0 +1,60 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity 0.8.9;
3
+ import "openzeppelin-solidity/contracts/utils/structs/EnumerableSet.sol";
4
+ import "../interfaces/IPMarket.sol";
5
+ import "../interfaces/IPYieldContractFactory.sol";
6
+ import "../interfaces/IPMarketFactory.sol";
7
+ import "../periphery/PermissionsV2.sol";
8
+ import "./PendleMarket.sol";
9
+
10
+ contract PendleMarketFactory is PermissionsV2, IPMarketFactory {
11
+ using EnumerableSet for EnumerableSet.AddressSet;
12
+
13
+ mapping(address => EnumerableSet.AddressSet) internal otMarkets;
14
+ address public immutable yieldContractFactory;
15
+ address public treasury;
16
+
17
+ constructor(address _governanceManager, address _yieldContractFactory)
18
+ PermissionsV2(_governanceManager)
19
+ {
20
+ yieldContractFactory = _yieldContractFactory;
21
+ }
22
+
23
+ function createNewMarket(
24
+ address OT,
25
+ uint256 feeRateRoot,
26
+ int256 scalarRoot,
27
+ int256 anchorRoot,
28
+ uint8 reserveFeePercent,
29
+ uint256 rateOracleTimeWindow
30
+ ) external returns (address market) {
31
+ address SCY = IPOwnershipToken(OT).SCY();
32
+ uint256 expiry = IPOwnershipToken(OT).expiry();
33
+
34
+ require(
35
+ IPYieldContractFactory(yieldContractFactory).getOT(SCY, expiry) == OT,
36
+ "INVALID_OT"
37
+ );
38
+
39
+ market = address(
40
+ new PendleMarket(
41
+ OT,
42
+ rateOracleTimeWindow,
43
+ feeRateRoot,
44
+ scalarRoot,
45
+ anchorRoot,
46
+ reserveFeePercent
47
+ )
48
+ );
49
+ otMarkets[address(OT)].add(market);
50
+ }
51
+
52
+ function setTreasury(address newTreasury) external onlyGovernance {
53
+ treasury = newTreasury;
54
+ }
55
+
56
+ function isValidMarket(address market) external view returns (bool) {
57
+ address OT = IPMarket(market).OT();
58
+ return otMarkets[OT].contains(market);
59
+ }
60
+ }
@@ -0,0 +1,44 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity 0.8.9;
3
+
4
+ import "./PendleBaseToken.sol";
5
+ import "../interfaces/IPOwnershipToken.sol";
6
+
7
+ contract PendleOwnershipToken is PendleBaseToken, IPOwnershipToken {
8
+ address public immutable SCY;
9
+ address public YT;
10
+
11
+ modifier onlyYT() {
12
+ require(msg.sender == address(YT), "ONLY_YT");
13
+ _;
14
+ }
15
+
16
+ modifier onlyFactory() {
17
+ require(msg.sender == factory, "ONLY_FACTORY");
18
+ _;
19
+ }
20
+
21
+ constructor(
22
+ address _SCY,
23
+ string memory _name,
24
+ string memory _symbol,
25
+ uint8 __decimals,
26
+ uint256 _expiry
27
+ ) PendleBaseToken(_name, _symbol, __decimals, _expiry) {
28
+ SCY = _SCY;
29
+ }
30
+
31
+ function initialize(address _YT) external onlyFactory {
32
+ YT = _YT;
33
+ }
34
+
35
+ function burnByYT(address user, uint256 amount) external onlyYT {
36
+ _burn(user, amount);
37
+ emit Burn(user, amount);
38
+ }
39
+
40
+ function mintByYT(address user, uint256 amount) external onlyYT {
41
+ _mint(user, amount);
42
+ emit Mint(user, amount);
43
+ }
44
+ }
@@ -0,0 +1,139 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity 0.8.9;
3
+ pragma abicoder v2;
4
+ import "../../../SuperComposableYield/implementations/SCYBaseWithRewards.sol";
5
+ import "../../../interfaces/IAToken.sol";
6
+ import "../../../interfaces/IAavePool.sol";
7
+ import "../../../interfaces/IAaveRewardsController.sol";
8
+ import "./WadRayMath.sol";
9
+
10
+ contract PendleAaveV3SCY is SCYBaseWithRewards {
11
+ using WadRayMath for uint256;
12
+ using SafeERC20 for IERC20;
13
+
14
+ address public immutable underlying;
15
+ address public immutable pool;
16
+ address public immutable rewardsController;
17
+ address public immutable aToken;
18
+
19
+ uint256 public lastScyIndex;
20
+
21
+ // WIP: Aave reward controller can config to have more rewardsToken,
22
+ // hence rewardsLength should not be immutable
23
+ constructor(
24
+ string memory _name,
25
+ string memory _symbol,
26
+ uint8 __scydecimals,
27
+ uint8 __assetDecimals,
28
+ address _aavePool,
29
+ address _underlying,
30
+ address _aToken,
31
+ address _rewardsController
32
+ ) SCYBaseWithRewards(_name, _symbol, __scydecimals, __assetDecimals) {
33
+ aToken = _aToken;
34
+ pool = _aavePool;
35
+ underlying = _underlying;
36
+ rewardsController = _rewardsController;
37
+ IERC20(underlying).safeIncreaseAllowance(aToken, type(uint256).max);
38
+ }
39
+
40
+ /*///////////////////////////////////////////////////////////////
41
+ DEPOSIT/REDEEM USING BASE TOKENS
42
+ //////////////////////////////////////////////////////////////*/
43
+
44
+ function _deposit(address token, uint256 amountBase)
45
+ internal
46
+ virtual
47
+ override
48
+ returns (uint256 amountScyOut)
49
+ {
50
+ // aTokenScaled -> scy is 1:1
51
+ if (token == aToken) {
52
+ amountScyOut = amountBase.rayDiv(scyIndexCurrent());
53
+ } else {
54
+ IAavePool(pool).supply(underlying, amountBase, address(this), 0);
55
+ _afterSendToken(underlying);
56
+ amountScyOut = _afterReceiveToken(aToken);
57
+ }
58
+ }
59
+
60
+ function _redeem(address token, uint256 amountScy)
61
+ internal
62
+ virtual
63
+ override
64
+ returns (uint256 amountBaseOut)
65
+ {
66
+ if (token == aToken) {
67
+ amountBaseOut = amountScy.rayMul(scyIndexCurrent());
68
+ } else {
69
+ uint256 amountBaseExpected = amountScy.rayMul(scyIndexCurrent());
70
+ IAavePool(pool).withdraw(underlying, amountBaseExpected, address(this));
71
+ _afterSendToken(aToken);
72
+ amountBaseOut = _afterReceiveToken(token);
73
+ }
74
+ }
75
+
76
+ /*///////////////////////////////////////////////////////////////
77
+ SCY-INDEX
78
+ //////////////////////////////////////////////////////////////*/
79
+
80
+ function scyIndexCurrent() public virtual override returns (uint256 res) {
81
+ res = IAavePool(pool).getReserveNormalizedIncome(underlying);
82
+ lastScyIndex = res;
83
+ return res;
84
+ }
85
+
86
+ function scyIndexStored() public view override returns (uint256 res) {
87
+ res = lastScyIndex;
88
+ }
89
+
90
+ function getRewardTokens() public view override returns (address[] memory res) {
91
+ return IAaveRewardsController(rewardsController).getRewardsByAsset(aToken);
92
+ }
93
+
94
+ /*///////////////////////////////////////////////////////////////
95
+ MISC FUNCTIONS FOR METADATA
96
+ //////////////////////////////////////////////////////////////*/
97
+
98
+ function getBaseTokens() public view virtual override returns (address[] memory res) {
99
+ res = new address[](2);
100
+ res[0] = underlying;
101
+ res[1] = aToken;
102
+ }
103
+
104
+ function isValidBaseToken(address token) public view virtual override returns (bool res) {
105
+ res = (token == underlying || token == aToken);
106
+ }
107
+
108
+ /*///////////////////////////////////////////////////////////////
109
+ REWARDS-RELATED
110
+ //////////////////////////////////////////////////////////////*/
111
+
112
+ function _redeemExternalReward() internal override {
113
+ address[] memory assets = new address[](1);
114
+ assets[0] = aToken;
115
+
116
+ IAaveRewardsController(rewardsController).claimAllRewards(assets, address(this));
117
+ }
118
+
119
+ /// @dev balance of aToken is saved by scaledBalanceOf instead
120
+ function _afterReceiveToken(address token) internal virtual override returns (uint256 res) {
121
+ if (token == aToken) {
122
+ uint256 curBalance = IAToken(aToken).scaledBalanceOf(address(this));
123
+ res = (curBalance - lastBalanceOf[token]).rayMul(scyIndexCurrent());
124
+ lastBalanceOf[token] = curBalance;
125
+ } else {
126
+ uint256 curBalance = IERC20(token).balanceOf(address(this));
127
+ res = curBalance - lastBalanceOf[token];
128
+ lastBalanceOf[token] = curBalance;
129
+ }
130
+ }
131
+
132
+ function _afterSendToken(address token) internal virtual override {
133
+ if (token == aToken) {
134
+ lastBalanceOf[token] = IAToken(aToken).scaledBalanceOf(address(this));
135
+ } else {
136
+ lastBalanceOf[token] = IERC20(token).balanceOf(address(this));
137
+ }
138
+ }
139
+ }
@@ -0,0 +1,126 @@
1
+ // SPDX-License-Identifier: BUSL-1.1
2
+ pragma solidity 0.8.9;
3
+
4
+ /**
5
+ * @title WadRayMath library
6
+ * @author Aave
7
+ * @notice Provides functions to perform calculations with Wad and Ray units
8
+ * @dev Provides mul and div function for wads (decimal numbers with 18 digits of precision) and rays (decimal numbers
9
+ * with 27 digits of precision)
10
+ * @dev Operations are rounded. If a value is >=.5, will be rounded up, otherwise rounded down.
11
+ **/
12
+ library WadRayMath {
13
+ // HALF_WAD and HALF_RAY expressed with extended notation as constant with operations are not supported in Yul assembly
14
+ uint256 internal constant WAD = 1e18;
15
+ uint256 internal constant HALF_WAD = 0.5e18;
16
+
17
+ uint256 internal constant RAY = 1e27;
18
+ uint256 internal constant HALF_RAY = 0.5e27;
19
+
20
+ uint256 internal constant WAD_RAY_RATIO = 1e9;
21
+
22
+ /**
23
+ * @dev Multiplies two wad, rounding half up to the nearest wad
24
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
25
+ * @param a Wad
26
+ * @param b Wad
27
+ * @return c = a*b, in wad
28
+ **/
29
+ function wadMul(uint256 a, uint256 b) internal pure returns (uint256 c) {
30
+ // to avoid overflow, a <= (type(uint256).max - HALF_WAD) / b
31
+ assembly {
32
+ if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_WAD), b))))) {
33
+ revert(0, 0)
34
+ }
35
+
36
+ c := div(add(mul(a, b), HALF_WAD), WAD)
37
+ }
38
+ }
39
+
40
+ /**
41
+ * @dev Divides two wad, rounding half up to the nearest wad
42
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
43
+ * @param a Wad
44
+ * @param b Wad
45
+ * @return c = a/b, in wad
46
+ **/
47
+ function wadDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {
48
+ // to avoid overflow, a <= (type(uint256).max - halfB) / WAD
49
+ assembly {
50
+ if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), WAD))))) {
51
+ revert(0, 0)
52
+ }
53
+
54
+ c := div(add(mul(a, WAD), div(b, 2)), b)
55
+ }
56
+ }
57
+
58
+ /**
59
+ * @notice Multiplies two ray, rounding half up to the nearest ray
60
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
61
+ * @param a Ray
62
+ * @param b Ray
63
+ * @return c = a raymul b
64
+ **/
65
+ function rayMul(uint256 a, uint256 b) internal pure returns (uint256 c) {
66
+ // to avoid overflow, a <= (type(uint256).max - HALF_RAY) / b
67
+ assembly {
68
+ if iszero(or(iszero(b), iszero(gt(a, div(sub(not(0), HALF_RAY), b))))) {
69
+ revert(0, 0)
70
+ }
71
+
72
+ c := div(add(mul(a, b), HALF_RAY), RAY)
73
+ }
74
+ }
75
+
76
+ /**
77
+ * @notice Divides two ray, rounding half up to the nearest ray
78
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
79
+ * @param a Ray
80
+ * @param b Ray
81
+ * @return c = a raydiv b
82
+ **/
83
+ function rayDiv(uint256 a, uint256 b) internal pure returns (uint256 c) {
84
+ // to avoid overflow, a <= (type(uint256).max - halfB) / RAY
85
+ assembly {
86
+ if or(iszero(b), iszero(iszero(gt(a, div(sub(not(0), div(b, 2)), RAY))))) {
87
+ revert(0, 0)
88
+ }
89
+
90
+ c := div(add(mul(a, RAY), div(b, 2)), b)
91
+ }
92
+ }
93
+
94
+ /**
95
+ * @dev Casts ray down to wad
96
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
97
+ * @param a Ray
98
+ * @return b = a converted to wad, rounded half up to the nearest wad
99
+ **/
100
+ function rayToWad(uint256 a) internal pure returns (uint256 b) {
101
+ assembly {
102
+ b := div(a, WAD_RAY_RATIO)
103
+ let remainder := mod(a, WAD_RAY_RATIO)
104
+ if iszero(lt(remainder, div(WAD_RAY_RATIO, 2))) {
105
+ b := add(b, 1)
106
+ }
107
+ }
108
+ }
109
+
110
+ /**
111
+ * @dev Converts wad up to ray
112
+ * @dev assembly optimized for improved gas savings, see https://twitter.com/transmissions11/status/1451131036377571328
113
+ * @param a Wad
114
+ * @return b = a converted in ray
115
+ **/
116
+ function wadToRay(uint256 a) internal pure returns (uint256 b) {
117
+ // to avoid overflow, b/WAD_RAY_RATIO == a
118
+ assembly {
119
+ b := mul(a, WAD_RAY_RATIO)
120
+
121
+ if iszero(eq(div(b, WAD_RAY_RATIO), a)) {
122
+ revert(0, 0)
123
+ }
124
+ }
125
+ }
126
+ }