@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,240 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity 0.8.9;
3
+
4
+ import "./PendleBaseToken.sol";
5
+ import "../SuperComposableYield/ISuperComposableYield.sol";
6
+ import "../interfaces/IPYieldToken.sol";
7
+ import "../interfaces/IPOwnershipToken.sol";
8
+ import "../libraries/math/FixedPoint.sol";
9
+ import "../interfaces/IPYieldContractFactory.sol";
10
+ import "openzeppelin-solidity/contracts/utils/math/Math.sol";
11
+ import "openzeppelin-solidity/contracts/token/ERC20/utils/SafeERC20.sol";
12
+ import "../SuperComposableYield/SCYUtils.sol";
13
+ import "../SuperComposableYield/implementations/RewardManager.sol";
14
+
15
+ contract PendleYieldToken is PendleBaseToken, IPYieldToken, RewardManager {
16
+ using FixedPoint for uint256;
17
+ using SafeERC20 for IERC20;
18
+
19
+ struct UserData {
20
+ uint256 lastScyIndex;
21
+ uint256 dueInterest;
22
+ }
23
+
24
+ address public immutable SCY;
25
+ address public immutable OT;
26
+
27
+ /// params to do interests & rewards accounting
28
+ uint256 public lastScyBalance;
29
+ uint256 public lastScyIndexBeforeExpiry;
30
+ uint256[] public paramL;
31
+
32
+ /// params to do fee accounting
33
+ mapping(address => uint256) public totalRewardsPostExpiry;
34
+ uint256 public totalProtocolFee;
35
+
36
+ mapping(address => UserData) public data;
37
+
38
+ constructor(
39
+ address _SCY,
40
+ address _OT,
41
+ string memory _name,
42
+ string memory _symbol,
43
+ uint8 __decimals,
44
+ uint256 _expiry
45
+ ) PendleBaseToken(_name, _symbol, __decimals, _expiry) {
46
+ SCY = _SCY;
47
+ OT = _OT;
48
+ }
49
+
50
+ /**
51
+ * @notice this function splits scy into OT + YT of equal qty
52
+ * @dev the scy to tokenize has to be pre-transferred to this contract prior to the function call
53
+ */
54
+ function mintYO(address receiverOT, address receiverYT) public returns (uint256 amountYOOut) {
55
+ uint256 amountToTokenize = _receiveSCY();
56
+
57
+ amountYOOut = _calcAmountToMint(amountToTokenize);
58
+
59
+ _mint(receiverYT, amountYOOut);
60
+
61
+ IPOwnershipToken(OT).mintByYT(receiverOT, amountYOOut);
62
+ }
63
+
64
+ /// this function converts YO tokens into scy, but interests & rewards are not included
65
+ function redeemYO(address receiver) public returns (uint256 amountScyOut) {
66
+ // minimum of OT & YT balance
67
+ uint256 amountYOToRedeem = IERC20(OT).balanceOf(address(this));
68
+ if (!isExpired()) {
69
+ amountYOToRedeem = Math.min(amountYOToRedeem, balanceOf(address(this)));
70
+ _burn(address(this), amountYOToRedeem);
71
+ }
72
+ IPOwnershipToken(OT).burnByYT(address(this), amountYOToRedeem);
73
+
74
+ amountScyOut = _calcAmountRedeemable(amountYOToRedeem);
75
+
76
+ IERC20(SCY).safeTransfer(receiver, amountScyOut);
77
+ _afterTransferOutSCY();
78
+ }
79
+
80
+ function redeemDueInterest(address user) public returns (uint256 interestOut) {
81
+ _updateDueInterest(user);
82
+
83
+ uint256 interestPreFee = data[user].dueInterest;
84
+ data[user].dueInterest = 0;
85
+
86
+ uint256 feeRate = IPYieldContractFactory(factory).interestFeeRate();
87
+ uint256 feeAmount = interestPreFee.mulDown(feeRate);
88
+ totalProtocolFee += feeAmount;
89
+
90
+ interestOut = interestPreFee - feeAmount;
91
+ IERC20(SCY).safeTransfer(user, interestOut);
92
+ _afterTransferOutSCY();
93
+ }
94
+
95
+ function redeemDueRewards(address user, address receiver)
96
+ public
97
+ returns (uint256[] memory rewardsOut)
98
+ {
99
+ if (user != msg.sender) require(receiver == user, "invalid receiver");
100
+ else require(receiver != address(0), "zero address");
101
+
102
+ _updateUserReward(user, balanceOf(user), totalSupply());
103
+ rewardsOut = _doTransferOutRewardsForUser(user, receiver);
104
+ }
105
+
106
+ function updateGlobalReward() public virtual {
107
+ address[] memory rewardTokens = getRewardTokens();
108
+ _updateGlobalReward(rewardTokens, totalSupply());
109
+ }
110
+
111
+ function updateUserReward(address user) public virtual {
112
+ _updateUserReward(user, balanceOf(user), totalSupply());
113
+ }
114
+
115
+ function _updateGlobalReward(address[] memory rewardTokens, uint256 totalSupply)
116
+ internal
117
+ virtual
118
+ override
119
+ {
120
+ _redeemExternalReward();
121
+
122
+ _initGlobalReward(rewardTokens);
123
+
124
+ bool _isExpired = isExpired();
125
+ for (uint256 i = 0; i < rewardTokens.length; ++i) {
126
+ address token = rewardTokens[i];
127
+
128
+ uint256 currentRewardBalance = IERC20(token).balanceOf(address(this));
129
+ uint256 totalIncomeReward = currentRewardBalance - globalReward[token].lastBalance;
130
+
131
+ if (_isExpired) {
132
+ totalRewardsPostExpiry[token] += totalIncomeReward;
133
+ } else if (totalSupply != 0) {
134
+ globalReward[token].index += totalIncomeReward.divDown(totalSupply);
135
+ }
136
+
137
+ globalReward[token].lastBalance = currentRewardBalance;
138
+ }
139
+ }
140
+
141
+ function _redeemExternalReward() internal virtual override {
142
+ ISuperComposableYield(SCY).redeemReward(address(this), address(this));
143
+ }
144
+
145
+ function getRewardTokens()
146
+ public
147
+ view
148
+ virtual
149
+ override(RewardManager)
150
+ returns (address[] memory)
151
+ {
152
+ return ISuperComposableYield(SCY).getRewardTokens();
153
+ }
154
+
155
+ function getScyIndexBeforeExpiry() public returns (uint256 res) {
156
+ if (isExpired()) return res = lastScyIndexBeforeExpiry;
157
+ res = ISuperComposableYield(SCY).scyIndexCurrent();
158
+ lastScyIndexBeforeExpiry = res;
159
+ }
160
+
161
+ function withdrawFeeToTreasury() public {
162
+ address[] memory rewardTokens = ISuperComposableYield(SCY).getRewardTokens();
163
+ uint256 length = rewardTokens.length;
164
+ address treasury = IPYieldContractFactory(factory).treasury();
165
+
166
+ for (uint256 i = 0; i < length; i++) {
167
+ address token = rewardTokens[i];
168
+ uint256 outAmount = totalRewardsPostExpiry[token];
169
+ if (outAmount > 0) IERC20(rewardTokens[i]).safeTransfer(treasury, outAmount);
170
+ totalRewardsPostExpiry[token] = 0;
171
+ }
172
+
173
+ if (totalProtocolFee > 0) {
174
+ IERC20(SCY).safeTransfer(treasury, totalProtocolFee);
175
+ _afterTransferOutSCY();
176
+ totalProtocolFee = 0;
177
+ }
178
+ }
179
+
180
+ function _updateDueInterest(address user) internal {
181
+ uint256 prevIndex = data[user].lastScyIndex;
182
+
183
+ uint256 currentIndex = getScyIndexBeforeExpiry();
184
+
185
+ if (prevIndex == currentIndex) return;
186
+ if (prevIndex == 0) {
187
+ data[user].lastScyIndex = currentIndex;
188
+ return;
189
+ }
190
+
191
+ uint256 principal = balanceOf(user);
192
+
193
+ uint256 interestFromYT = (principal * (currentIndex - prevIndex)).divDown(
194
+ prevIndex * currentIndex
195
+ );
196
+
197
+ data[user].dueInterest += interestFromYT;
198
+ data[user].lastScyIndex = currentIndex;
199
+ }
200
+
201
+ function _calcAmountToMint(uint256 amount) internal returns (uint256) {
202
+ return SCYUtils.scyToAsset(getScyIndexBeforeExpiry(), amount);
203
+ }
204
+
205
+ function _calcAmountRedeemable(uint256 amount) internal returns (uint256) {
206
+ return SCYUtils.assetToScy(getScyIndexBeforeExpiry(), amount);
207
+ }
208
+
209
+ function _receiveSCY() internal returns (uint256 amount) {
210
+ uint256 balanceScy = IERC20(SCY).balanceOf(address(this));
211
+ amount = balanceScy - lastScyBalance;
212
+ require(amount > 0, "RECEIVE_ZERO");
213
+ lastScyBalance = balanceScy;
214
+ }
215
+
216
+ function _afterTransferOutSCY() internal {
217
+ lastScyBalance = IERC20(SCY).balanceOf(address(this));
218
+ }
219
+
220
+ function _beforeTokenTransfer(
221
+ address from,
222
+ address to,
223
+ uint256
224
+ ) internal override {
225
+ address[] memory rewardTokens = getRewardTokens();
226
+ _updateGlobalReward(rewardTokens, totalSupply());
227
+ if (from != address(0) && from != address(this)) {
228
+ _updateDueInterest(from);
229
+ _updateUserRewardSkipGlobal(rewardTokens, from, balanceOf(from));
230
+ }
231
+ if (to != address(0) && to != address(this)) {
232
+ _updateDueInterest(to);
233
+ _updateUserRewardSkipGlobal(rewardTokens, to, balanceOf(to));
234
+ }
235
+ }
236
+ }
237
+ /*INVARIANTS TO CHECK
238
+ - supply OT == supply YT
239
+ - reentrancy check
240
+ */
@@ -0,0 +1,62 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.9;
3
+
4
+ // Audit on 5-Jan-2021 by Keno and BoringCrypto
5
+ // Source: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol + Claimable.sol
6
+ // Edited by BoringCrypto
7
+
8
+ contract BoringOwnableData {
9
+ address public owner;
10
+ address public pendingOwner;
11
+ }
12
+
13
+ contract BoringOwnable is BoringOwnableData {
14
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
15
+
16
+ /// @notice Only allows the `owner` to execute the function.
17
+ modifier onlyOwner() {
18
+ require(msg.sender == owner, "Ownable: caller is not the owner");
19
+ _;
20
+ }
21
+
22
+ constructor(address _owner) {
23
+ owner = _owner;
24
+ }
25
+
26
+ /// @notice Transfers ownership to `newOwner`. Either directly or claimable by the new pending owner.
27
+ /// Can only be invoked by the current `owner`.
28
+ /// @param newOwner Address of the new owner.
29
+ /// @param direct True if `newOwner` should be set immediately. False if `newOwner` needs to use `claimOwnership`.
30
+ /// @param renounce Allows the `newOwner` to be `address(0)` if `direct` and `renounce` is True. Has no effect otherwise.
31
+ function transferOwnership(
32
+ address newOwner,
33
+ bool direct,
34
+ bool renounce
35
+ ) public onlyOwner {
36
+ if (direct) {
37
+ // Checks
38
+ require(newOwner != address(0) || renounce, "Ownable: zero address");
39
+
40
+ // Effects
41
+ emit OwnershipTransferred(owner, newOwner);
42
+ owner = newOwner;
43
+ pendingOwner = address(0);
44
+ } else {
45
+ // Effects
46
+ pendingOwner = newOwner;
47
+ }
48
+ }
49
+
50
+ /// @notice Needs to be called by `pendingOwner` to claim ownership.
51
+ function claimOwnership() public {
52
+ address _pendingOwner = pendingOwner;
53
+
54
+ // Checks
55
+ require(msg.sender == _pendingOwner, "Ownable: caller != pending owner");
56
+
57
+ // Effects
58
+ emit OwnershipTransferred(owner, _pendingOwner);
59
+ owner = _pendingOwner;
60
+ pendingOwner = address(0);
61
+ }
62
+ }
@@ -0,0 +1,64 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity 0.8.9;
3
+
4
+ import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
5
+
6
+ /// Modified by the Pendle team, needs to audit
7
+
8
+ contract BoringOwnableUpgData {
9
+ address public owner;
10
+ address public pendingOwner;
11
+ }
12
+
13
+ contract BoringOwnableUpg is BoringOwnableUpgData, Initializable {
14
+ event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
15
+
16
+ function __BoringOwnable_init() internal onlyInitializing {
17
+ owner = msg.sender;
18
+ }
19
+
20
+ /// @notice Transfers ownership to `newOwner`. Either directly or claimable by the new pending owner.
21
+ /// Can only be invoked by the current `owner`.
22
+ /// @param newOwner Address of the new owner.
23
+ /// @param direct True if `newOwner` should be set immediately. False if `newOwner` needs to use `claimOwnership`.
24
+ /// @param renounce Allows the `newOwner` to be `address(0)` if `direct` and `renounce` is True. Has no effect otherwise.
25
+ function transferOwnership(
26
+ address newOwner,
27
+ bool direct,
28
+ bool renounce
29
+ ) public onlyOwner {
30
+ if (direct) {
31
+ // Checks
32
+ require(newOwner != address(0) || renounce, "Ownable: zero address");
33
+
34
+ // Effects
35
+ emit OwnershipTransferred(owner, newOwner);
36
+ owner = newOwner;
37
+ pendingOwner = address(0);
38
+ } else {
39
+ // Effects
40
+ pendingOwner = newOwner;
41
+ }
42
+ }
43
+
44
+ /// @notice Needs to be called by `pendingOwner` to claim ownership.
45
+ function claimOwnership() public {
46
+ address _pendingOwner = pendingOwner;
47
+
48
+ // Checks
49
+ require(msg.sender == _pendingOwner, "Ownable: caller != pending owner");
50
+
51
+ // Effects
52
+ emit OwnershipTransferred(owner, _pendingOwner);
53
+ owner = _pendingOwner;
54
+ pendingOwner = address(0);
55
+ }
56
+
57
+ /// @notice Only allows the `owner` to execute the function.
58
+ modifier onlyOwner() {
59
+ require(msg.sender == owner, "Ownable: caller is not the owner");
60
+ _;
61
+ }
62
+
63
+ uint256[48] private __gap;
64
+ }
@@ -0,0 +1,82 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ /*
3
+ * MIT License
4
+ * ===========
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ */
23
+
24
+ pragma solidity 0.8.9;
25
+ import "../../interfaces/IJoeRouter01.sol";
26
+ import "../../libraries/JoeLibrary.sol";
27
+ import "openzeppelin-solidity/contracts/token/ERC20/IERC20.sol";
28
+ import "openzeppelin-solidity/contracts/token/ERC20/utils/SafeERC20.sol";
29
+
30
+ abstract contract PendleJoeSwapHelperUpg {
31
+ using SafeERC20 for IERC20;
32
+ address public immutable joeRouter;
33
+ address public immutable joeFactory;
34
+
35
+ /// @dev since this contract will be proxied, it must not contains non-immutable variables
36
+ constructor(address _joeRouter, address _joeFactory) {
37
+ joeRouter = _joeRouter;
38
+ joeFactory = _joeFactory;
39
+ }
40
+
41
+ function _getFirstPair(address[] memory path) internal view returns (address pair) {
42
+ return JoeLibrary.pairFor(joeFactory, path[0], path[1]);
43
+ }
44
+
45
+ /**
46
+ * @notice swap tokens with no limit on amountOut. Tokens must have been transferred to the first pair
47
+ */
48
+ function _swapExactIn(
49
+ address[] memory path,
50
+ uint256 amountIn,
51
+ address receiver
52
+ ) internal virtual returns (uint256 amountOut) {
53
+ uint256[] memory amounts = JoeLibrary.getAmountsOut(joeFactory, amountIn, path);
54
+ _low_level_swap(amounts, path, receiver);
55
+ amountOut = amounts[amounts.length - 1];
56
+ }
57
+
58
+ /// function from TraderJoe
59
+ function _low_level_swap(
60
+ uint256[] memory amounts,
61
+ address[] memory path,
62
+ address _to
63
+ ) internal virtual {
64
+ for (uint256 i; i < path.length - 1; i++) {
65
+ (address input, address output) = (path[i], path[i + 1]);
66
+ (address token0, ) = JoeLibrary.sortTokens(input, output);
67
+ uint256 amountOut = amounts[i + 1];
68
+ (uint256 amount0Out, uint256 amount1Out) = input == token0
69
+ ? (uint256(0), amountOut)
70
+ : (amountOut, uint256(0));
71
+ address to = i < path.length - 2
72
+ ? JoeLibrary.pairFor(joeFactory, output, path[i + 2])
73
+ : _to;
74
+ IJoePair(JoeLibrary.pairFor(joeFactory, input, output)).swap(
75
+ amount0Out,
76
+ amount1Out,
77
+ to,
78
+ new bytes(0)
79
+ );
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,219 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity 0.8.9;
3
+
4
+ import "./base/PendleRouterSCYAndForgeBaseUpg.sol";
5
+ import "./base/PendleRouterOTBaseUpg.sol";
6
+ import "../../interfaces/IPOwnershipToken.sol";
7
+ import "../../interfaces/IPYieldToken.sol";
8
+ import "../../interfaces/IPRouterCore.sol";
9
+
10
+ contract PendleRouterCoreUpg is
11
+ IPRouterCore,
12
+ PendleRouterSCYAndForgeBaseUpg,
13
+ PendleRouterOTBaseUpg
14
+ {
15
+ using MarketMathLib for MarketParameters;
16
+ using FixedPoint for uint256;
17
+ using FixedPoint for int256;
18
+
19
+ /// @dev since this contract will be proxied, it must not contains non-immutable variabless
20
+ constructor(
21
+ address _joeRouter,
22
+ address _joeFactory,
23
+ address _marketFactory
24
+ )
25
+ PendleRouterSCYAndForgeBaseUpg(_joeRouter, _joeFactory)
26
+ PendleRouterOTBaseUpg()
27
+ //solhint-disable-next-line no-empty-blocks
28
+ {
29
+
30
+ }
31
+
32
+ /// @dev docs can be found in the internal function
33
+ function addLiquidity(
34
+ address receiver,
35
+ address market,
36
+ uint256 scyDesired,
37
+ uint256 otDesired,
38
+ uint256 minLpOut
39
+ )
40
+ external
41
+ returns (
42
+ uint256,
43
+ uint256,
44
+ uint256
45
+ )
46
+ {
47
+ return _addLiquidity(receiver, market, scyDesired, otDesired, minLpOut, true);
48
+ }
49
+
50
+ /// @dev docs can be found in the internal function
51
+ function removeLiquidity(
52
+ address receiver,
53
+ address market,
54
+ uint256 lpToRemove,
55
+ uint256 scyOutMin,
56
+ uint256 otOutMin
57
+ ) external returns (uint256, uint256) {
58
+ return _removeLiquidity(receiver, market, lpToRemove, scyOutMin, otOutMin, true);
59
+ }
60
+
61
+ /// @dev docs can be found in the internal function
62
+ function swapExactOtForScy(
63
+ address receiver,
64
+ address market,
65
+ uint256 exactOtIn,
66
+ uint256 minScyOut
67
+ ) external returns (uint256) {
68
+ return _swapExactOtForScy(receiver, market, exactOtIn, minScyOut, true);
69
+ }
70
+
71
+ /// @dev docs can be found in the internal function
72
+ function swapOtForExactScy(
73
+ address receiver,
74
+ address market,
75
+ uint256 maxOtIn,
76
+ uint256 exactScyOut,
77
+ uint256 netOtInGuessMin,
78
+ uint256 netOtInGuessMax
79
+ ) external returns (uint256) {
80
+ return
81
+ _swapOtForExactScy(
82
+ receiver,
83
+ market,
84
+ maxOtIn,
85
+ exactScyOut,
86
+ netOtInGuessMin,
87
+ netOtInGuessMax,
88
+ true
89
+ );
90
+ }
91
+
92
+ /// @dev docs can be found in the internal function
93
+ function swapScyForExactOt(
94
+ address receiver,
95
+ address market,
96
+ uint256 exactOtOut,
97
+ uint256 maxScyIn
98
+ ) external returns (uint256) {
99
+ return _swapScyForExactOt(receiver, market, exactOtOut, maxScyIn, true);
100
+ }
101
+
102
+ /// @dev docs can be found in the internal function
103
+ function swapExactScyForOt(
104
+ address receiver,
105
+ address market,
106
+ uint256 exactScyIn,
107
+ uint256 minOtOut,
108
+ uint256 netOtOutGuessMin,
109
+ uint256 netOtOutGuessMax
110
+ ) external returns (uint256) {
111
+ return
112
+ _swapExactScyForOt(
113
+ receiver,
114
+ market,
115
+ exactScyIn,
116
+ minOtOut,
117
+ netOtOutGuessMin,
118
+ netOtOutGuessMax,
119
+ true
120
+ );
121
+ }
122
+
123
+ /// @dev docs can be found in the internal function
124
+ function mintScyFromRawToken(
125
+ uint256 netRawTokenIn,
126
+ address SCY,
127
+ uint256 minScyOut,
128
+ address receiver,
129
+ address[] calldata path
130
+ ) external returns (uint256) {
131
+ return _mintScyFromRawToken(netRawTokenIn, SCY, minScyOut, receiver, path, true);
132
+ }
133
+
134
+ /// @dev docs can be found in the internal function
135
+ function redeemScyToRawToken(
136
+ address SCY,
137
+ uint256 netScyIn,
138
+ uint256 minRawTokenOut,
139
+ address receiver,
140
+ address[] memory path
141
+ ) external returns (uint256) {
142
+ return _redeemScyToRawToken(SCY, netScyIn, minRawTokenOut, receiver, path, true);
143
+ }
144
+
145
+ /// @dev docs can be found in the internal function
146
+ function mintYoFromRawToken(
147
+ uint256 netRawTokenIn,
148
+ address YT,
149
+ uint256 minYoOut,
150
+ address receiver,
151
+ address[] calldata path
152
+ ) external returns (uint256) {
153
+ return _mintYoFromRawToken(netRawTokenIn, YT, minYoOut, receiver, path, true);
154
+ }
155
+
156
+ /// @dev docs can be found in the internal function
157
+ function redeemYoToRawToken(
158
+ address YT,
159
+ uint256 netYoIn,
160
+ uint256 minRawTokenOut,
161
+ address receiver,
162
+ address[] memory path
163
+ ) external returns (uint256) {
164
+ return _redeemYoToRawToken(YT, netYoIn, minRawTokenOut, receiver, path, true);
165
+ }
166
+
167
+ /**
168
+ * @dev netOtOutGuessMin & netOtOutGuessMax the minimum & maximum possible guess for the netOtOut
169
+ the correct otOut must lie between this range, else the function will revert.
170
+ * @dev the smaller the range, the fewer iterations it will take (hence less gas). The expected way
171
+ to create the guess is to run this function with min = 0, max = type(uint256.max) to trigger the widest
172
+ guess range. After getting the result, min = result * (100-slippage) & max = result * (100+slippage)
173
+ * @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
174
+ */
175
+ function swapExactRawTokenForOt(
176
+ uint256 exactRawTokenIn,
177
+ address receiver,
178
+ address[] calldata path,
179
+ address market,
180
+ uint256 minOtOut,
181
+ uint256 netOtOutGuessMin,
182
+ uint256 netOtOutGuessMax
183
+ ) external returns (uint256 netOtOut) {
184
+ address SCY = IPMarket(market).SCY();
185
+ uint256 netScyUseToBuyOt = _mintScyFromRawToken(
186
+ exactRawTokenIn,
187
+ SCY,
188
+ 1,
189
+ market,
190
+ path,
191
+ true
192
+ );
193
+ netOtOut = _swapExactScyForOt(
194
+ receiver,
195
+ market,
196
+ netScyUseToBuyOt,
197
+ minOtOut,
198
+ netOtOutGuessMin,
199
+ netOtOutGuessMax,
200
+ false
201
+ );
202
+ }
203
+
204
+ /**
205
+ * @notice sell all Ot for RawToken
206
+ * @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
207
+ */
208
+ function swapExactOtForRawToken(
209
+ uint256 exactOtIn,
210
+ address receiver,
211
+ address[] calldata path,
212
+ address market,
213
+ uint256 minRawTokenOut
214
+ ) external returns (uint256 netRawTokenOut) {
215
+ address SCY = IPMarket(market).SCY();
216
+ _swapExactOtForScy(SCY, market, exactOtIn, 1, true);
217
+ netRawTokenOut = _redeemScyToRawToken(SCY, 0, minRawTokenOut, receiver, path, false);
218
+ }
219
+ }