@pendle/core-v2 4.5.1-beta-2 → 4.5.1-oracle-beta

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 (116) hide show
  1. package/build/artifacts/contracts/core/StandardizedYield/implementations/PendleERC20WithSupplyCapSY.sol/PendleERC20WithSupplyCapSY.dbg.json +1 -1
  2. package/build/artifacts/contracts/core/StandardizedYield/implementations/PendleERC20WithSupplyCapSY.sol/PendleERC20WithSupplyCapSY.json +2 -2
  3. package/build/artifacts/contracts/core/StandardizedYield/implementations/Swell/PendleSwellRswETHStakingSY.sol/PendleSwellRswETHStakingSY.dbg.json +4 -0
  4. package/build/artifacts/contracts/core/StandardizedYield/implementations/Swell/PendleSwellRswETHStakingSY.sol/PendleSwellRswETHStakingSY.json +1049 -0
  5. package/build/artifacts/contracts/core/StandardizedYield/implementations/Swell/PendleSwellStakingERC20SY.sol/PendleSwellStakingERC20SY.dbg.json +4 -0
  6. package/build/artifacts/contracts/core/StandardizedYield/implementations/Swell/PendleSwellStakingERC20SY.sol/PendleSwellStakingERC20SY.json +1039 -0
  7. package/build/artifacts/contracts/interfaces/IPActionMiscV3.sol/IPActionMiscV3.dbg.json +1 -1
  8. package/build/artifacts/contracts/interfaces/IPActionMiscV3.sol/IPActionMiscV3.json +32 -1154
  9. package/build/artifacts/contracts/interfaces/IPAllActionV3.sol/IPAllActionV3.dbg.json +1 -1
  10. package/build/artifacts/contracts/interfaces/IPAllActionV3.sol/IPAllActionV3.json +60 -1182
  11. package/build/artifacts/contracts/interfaces/IPGovernanceProxy.sol/IPGovernanceProxy.dbg.json +4 -0
  12. package/build/artifacts/contracts/interfaces/IPGovernanceProxy.sol/IPGovernanceProxy.json +60 -0
  13. package/build/artifacts/contracts/interfaces/IPPYLpOracle.sol/IPPYLpOracle.dbg.json +4 -0
  14. package/build/artifacts/contracts/interfaces/{IPPtLpOracle.sol/IPPtLpOracle.json → IPPYLpOracle.sol/IPPYLpOracle.json} +50 -2
  15. package/build/artifacts/contracts/interfaces/IPPausingInterface.sol/IPPausingInterface.dbg.json +4 -0
  16. package/build/artifacts/contracts/interfaces/IPPausingInterface.sol/IPPausingInterface.json +25 -0
  17. package/build/artifacts/contracts/interfaces/Swell/ISwellSimpleStakingERC20.sol/ISwellSimpleStakingERC20.dbg.json +4 -0
  18. package/build/artifacts/contracts/interfaces/Swell/ISwellSimpleStakingERC20.sol/ISwellSimpleStakingERC20.json +207 -0
  19. package/build/artifacts/contracts/offchain-helpers/PendleGovernanceProxy.sol/PendleGovernanceProxy.dbg.json +4 -0
  20. package/build/artifacts/contracts/offchain-helpers/PendleGovernanceProxy.sol/PendleGovernanceProxy.json +401 -0
  21. package/build/artifacts/contracts/offchain-helpers/PendlePoolDeployHelper.sol/PendlePoolDeployHelper.dbg.json +1 -1
  22. package/build/artifacts/contracts/offchain-helpers/PendlePoolDeployHelper.sol/PendlePoolDeployHelper.json +2 -2
  23. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionMarketAuxStatic.sol/ActionMarketAuxStatic.dbg.json +1 -1
  24. package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionMarketAuxStatic.sol/ActionMarketAuxStatic.json +2 -2
  25. package/build/artifacts/contracts/oracles/PendleLpOracleLib.sol/PendleLpOracleLib.dbg.json +1 -1
  26. package/build/artifacts/contracts/oracles/PendleLpOracleLib.sol/PendleLpOracleLib.json +2 -2
  27. package/build/artifacts/contracts/oracles/PendlePYLpOracle.sol/PendlePYLpOracle.dbg.json +4 -0
  28. package/build/artifacts/contracts/oracles/PendlePYLpOracle.sol/PendlePYLpOracle.json +422 -0
  29. package/build/artifacts/contracts/oracles/PendlePYOracleLib.sol/PendlePYOracleLib.dbg.json +4 -0
  30. package/build/artifacts/contracts/oracles/{PendlePtOracleLib.sol/PendlePtOracleLib.json → PendlePYOracleLib.sol/PendlePYOracleLib.json} +4 -4
  31. package/build/artifacts/contracts/oracles/samples/BoringLpGlpOracle.sol/BoringLpGlpOracle.dbg.json +1 -1
  32. package/build/artifacts/contracts/oracles/samples/BoringLpGlpOracle.sol/BoringLpGlpOracle.json +2 -2
  33. package/build/artifacts/contracts/oracles/samples/BoringPYUsdChainlinkAssetOracle.sol/BoringPYUsdChainlinkAssetOracle.dbg.json +4 -0
  34. package/build/artifacts/contracts/oracles/samples/BoringPYUsdChainlinkAssetOracle.sol/BoringPYUsdChainlinkAssetOracle.json +183 -0
  35. package/build/artifacts/contracts/oracles/samples/BoringPYUsdChainlinkSYOracle.sol/BoringPYUsdChainlinkSYOracle.dbg.json +4 -0
  36. package/build/artifacts/contracts/oracles/samples/BoringPYUsdChainlinkSYOracle.sol/BoringPYUsdChainlinkSYOracle.json +183 -0
  37. package/build/artifacts/contracts/router/ActionAddRemoveLiqV3.sol/ActionAddRemoveLiqV3.dbg.json +1 -1
  38. package/build/artifacts/contracts/router/ActionAddRemoveLiqV3.sol/ActionAddRemoveLiqV3.json +2 -2
  39. package/build/artifacts/contracts/router/ActionMiscV3.sol/ActionMiscV3.dbg.json +1 -1
  40. package/build/artifacts/contracts/router/ActionMiscV3.sol/ActionMiscV3.json +34 -1156
  41. package/build/artifacts/contracts/router/ActionSwapPTV3.sol/ActionSwapPTV3.dbg.json +1 -1
  42. package/build/artifacts/contracts/router/ActionSwapPTV3.sol/ActionSwapPTV3.json +2 -2
  43. package/build/artifacts/contracts/router/ActionSwapYTV3.sol/ActionSwapYTV3.dbg.json +1 -1
  44. package/build/artifacts/contracts/router/ActionSwapYTV3.sol/ActionSwapYTV3.json +2 -2
  45. package/build/artifacts/contracts/router/base/ActionBase.sol/ActionBase.dbg.json +1 -1
  46. package/contracts/core/StandardizedYield/implementations/PendleERC20WithSupplyCapSY.sol +6 -1
  47. package/contracts/core/StandardizedYield/implementations/Swell/PendleSwellRswETHStakingSY.sol +56 -0
  48. package/contracts/core/StandardizedYield/implementations/Swell/PendleSwellStakingERC20SY.sol +111 -0
  49. package/contracts/interfaces/IPActionMiscV3.sol +0 -92
  50. package/contracts/interfaces/IPGovernanceProxy.sol +14 -0
  51. package/contracts/interfaces/{IPPtLpOracle.sol → IPPYLpOracle.sol} +5 -1
  52. package/contracts/interfaces/IPPausingInterface.sol +8 -0
  53. package/contracts/interfaces/Swell/ISwellSimpleStakingERC20.sol +66 -0
  54. package/contracts/offchain-helpers/PendleGovernanceProxy.sol +84 -0
  55. package/contracts/offchain-helpers/router-static/base/ActionMarketAuxStatic.sol +12 -4
  56. package/contracts/oracles/PendleLpOracleLib.sol +4 -4
  57. package/contracts/oracles/{PendlePtLpOracle.sol → PendlePYLpOracle.sol} +44 -16
  58. package/contracts/oracles/{PendlePtOracleLib.sol → PendlePYOracleLib.sol} +31 -1
  59. package/contracts/oracles/samples/BoringLpGlpOracle.sol +2 -2
  60. package/contracts/oracles/samples/{BoringPtUsdChainlinkOracle.sol → BoringPYUsdChainlinkAssetOracle.sol} +36 -12
  61. package/contracts/oracles/samples/BoringPYUsdChainlinkSYOracle.sol +102 -0
  62. package/contracts/router/ActionMiscV3.sol +36 -150
  63. package/contracts/router/ActionSwapYTV3.sol +85 -0
  64. package/contracts/router/base/ActionBase.sol +1 -106
  65. package/deployments/1-markets/EZETH-MAINNET-SEP2024.json +11 -0
  66. package/deployments/1-markets/PUFETH-MAINNET-SEP2024.json +11 -0
  67. package/deployments/1-markets/RSETH-MAINNET-SEP2024.json +11 -0
  68. package/deployments/1-markets/RSWETH-SWELL-STAKING-MAINNET-JUL2024.json +11 -0
  69. package/deployments/1-markets/SUSDE-MAINNET-SEP2024.json +13 -0
  70. package/deployments/1-markets/WEETH-MAINNET-SEP2024.json +11 -0
  71. package/deployments/42161-markets/EZETH-ARB-SEP2024.json +11 -0
  72. package/deployments/42161-markets/RSETH-ARBITRUM-SEP2024.json +11 -0
  73. package/deployments/42161-markets/SILO-PTEETH-ARBITRUM-JUNE2024.json +11 -0
  74. package/deployments/42161-markets/SILO-PTEZETH-ARBITRUM-JUNE2024.json +11 -0
  75. package/deployments/42161-markets/WEETH-ARB-SEP2024.json +11 -0
  76. package/deployments/56-markets/WEETH-BSC-SEP2024.json +11 -0
  77. package/package.json +1 -1
  78. package/typechain-types/ActionMiscV3.ts +16 -573
  79. package/typechain-types/BoringPYUsdChainlinkAssetOracle.ts +244 -0
  80. package/typechain-types/BoringPYUsdChainlinkSYOracle.ts +243 -0
  81. package/typechain-types/IPActionMiscV3.ts +16 -573
  82. package/typechain-types/IPAllActionV3.ts +0 -480
  83. package/typechain-types/IPGovernanceProxy.ts +142 -0
  84. package/typechain-types/IPPYLpOracle.ts +379 -0
  85. package/typechain-types/IPPausingInterface.ts +112 -0
  86. package/typechain-types/PendleGovernanceProxy.ts +603 -0
  87. package/typechain-types/PendlePYLpOracle.ts +612 -0
  88. package/typechain-types/factories/ActionAddRemoveLiqV3__factory.ts +1 -1
  89. package/typechain-types/factories/ActionMarketAuxStatic__factory.ts +1 -1
  90. package/typechain-types/factories/ActionMiscV3__factory.ts +33 -1155
  91. package/typechain-types/factories/ActionSwapPTV3__factory.ts +1 -1
  92. package/typechain-types/factories/ActionSwapYTV3__factory.ts +1 -1
  93. package/typechain-types/factories/BoringLpGlpOracle__factory.ts +1 -1
  94. package/typechain-types/factories/BoringPYUsdChainlinkAssetOracle__factory.ts +269 -0
  95. package/typechain-types/factories/BoringPYUsdChainlinkSYOracle__factory.ts +267 -0
  96. package/typechain-types/factories/IPActionMiscV3__factory.ts +32 -1154
  97. package/typechain-types/factories/IPAllActionV3__factory.ts +60 -1182
  98. package/typechain-types/factories/IPGovernanceProxy__factory.ts +75 -0
  99. package/typechain-types/factories/IPPYLpOracle__factory.ts +214 -0
  100. package/typechain-types/factories/IPPausingInterface__factory.ts +40 -0
  101. package/typechain-types/factories/PendleERC20WithSupplyCapSY__factory.ts +1 -1
  102. package/typechain-types/factories/PendleGovernanceProxy__factory.ts +458 -0
  103. package/typechain-types/factories/PendlePYLpOracle__factory.ts +487 -0
  104. package/typechain-types/factories/PendlePoolDeployHelper__factory.ts +1 -1
  105. package/typechain-types/factories/PendleSwellRswETHStakingSY__factory.ts +1 -1
  106. package/typechain-types/hardhat.d.ts +90 -0
  107. package/typechain-types/index.ts +20 -0
  108. package/build/artifacts/contracts/interfaces/IPPtLpOracle.sol/IPPtLpOracle.dbg.json +0 -4
  109. package/build/artifacts/contracts/oracles/PendlePtLpOracle.sol/PendlePtLpOracle.dbg.json +0 -4
  110. package/build/artifacts/contracts/oracles/PendlePtLpOracle.sol/PendlePtLpOracle.json +0 -367
  111. package/build/artifacts/contracts/oracles/PendlePtOracleLib.sol/PendlePtOracleLib.dbg.json +0 -4
  112. package/build/artifacts/contracts/oracles/samples/BoringPtUsdChainlinkOracle.sol/BoringPtUsdChainlinkOracle.dbg.json +0 -4
  113. package/build/artifacts/contracts/oracles/samples/BoringPtUsdChainlinkOracle.sol/BoringPtUsdChainlinkOracle.json +0 -157
  114. /package/deployments/1-markets/{EZETH-JUNE2024.json → EZETH-APR2024.json} +0 -0
  115. /package/deployments/42161-markets/{RSETH-MAY2024.json → RSETH-JUNE2024.json} +0 -0
  116. /package/deployments/42161-markets/{WEETH-MAY2024.json → WEETH-JUNE2024.json} +0 -0
@@ -0,0 +1,102 @@
1
+ // SPDX-License-Identifier: GPL-3.0-or-later
2
+ pragma solidity ^0.8.17;
3
+
4
+ import "../../interfaces/IPPYLpOracle.sol";
5
+ import "../../interfaces/IPMarket.sol";
6
+ import "../../core/libraries/math/PMath.sol";
7
+ import "../PendleLpOracleLib.sol";
8
+
9
+ import {AggregatorV2V3Interface as IChainlinkAggregator} from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV2V3Interface.sol";
10
+
11
+ /**
12
+ * @notice The returned price from this contract is multiplied by the default USD price of the
13
+ * SY-equivalent token, as read from a Chainlink-interface oracle.
14
+ *
15
+ * Example of this usage:
16
+ * - PT-weETH = ptToSyRate * weETH price
17
+ * - PT-ezETH = ptToSyRate * ezETH price
18
+ *
19
+ * For more details into how the oracle is implemented, refer to PendlePYLpOracle & PendlePYOracleLib.
20
+ */
21
+ contract BoringPYUsdChainlinkSYOracle {
22
+ using PendlePYOracleLib for IPMarket;
23
+
24
+ uint32 public immutable twapDuration;
25
+ address public immutable market;
26
+ address public immutable feed;
27
+ uint8 public immutable feedDecimals;
28
+ address public immutable pyLpOracle;
29
+
30
+ constructor(uint32 _twapDuration, address _market, address _feed, address _pyLpOracle) {
31
+ twapDuration = _twapDuration;
32
+ market = _market;
33
+ feed = _feed;
34
+ feedDecimals = IChainlinkAggregator(feed).decimals();
35
+
36
+ // required only for sample2
37
+ pyLpOracle = _pyLpOracle;
38
+
39
+ /**
40
+ * @notice All pricing functions in this contract should only be used after checkOracleState() is ran successfully without reverting.
41
+ * This equals to calling checkOracleState() in your oracle constructor.
42
+ */
43
+ // checkOracleState();
44
+ }
45
+
46
+ /// @notice direct integration with PendlePYOracleLib, which optimizes gas efficiency.
47
+ /// @notice please checkOracleState() before use
48
+ function getPtPriceSample1() external view virtual returns (uint256) {
49
+ uint256 ptRate = IPMarket(market).getPtToSyRate(twapDuration);
50
+ uint256 syEquivalentTokenPrice = _getSYEquivalentTokenPrice();
51
+ return (syEquivalentTokenPrice * ptRate) / PMath.ONE;
52
+ }
53
+
54
+ /// @notice integration with the PendlePtOracle contract, resulting in a smaller bytecode size and simpler structure
55
+ /// but slightly higher gas usage (~ 4000 gas, 2 external calls & 1 cold code load)
56
+ /// @notice please checkOracleState() before use
57
+ function getPtPriceSample2() external view virtual returns (uint256) {
58
+ uint256 ptRate = IPPYLpOracle(pyLpOracle).getPtToSyRate(market, twapDuration);
59
+ uint256 syEquivalentTokenPrice = _getSYEquivalentTokenPrice();
60
+ return (syEquivalentTokenPrice * ptRate) / PMath.ONE;
61
+ }
62
+
63
+ function getYtPriceSample1() external view virtual returns (uint256) {
64
+ uint256 ytRate = IPMarket(market).getYtToSyRate(twapDuration);
65
+ uint256 syEquivalentTokenPrice = _getSYEquivalentTokenPrice();
66
+ return (syEquivalentTokenPrice * ytRate) / PMath.ONE;
67
+ }
68
+
69
+ function getYtPriceSample2() external view virtual returns (uint256) {
70
+ uint256 ytRate = IPPYLpOracle(pyLpOracle).getYtToSyRate(market, twapDuration);
71
+ uint256 syEquivalentTokenPrice = _getSYEquivalentTokenPrice();
72
+ return (syEquivalentTokenPrice * ytRate) / PMath.ONE;
73
+ }
74
+
75
+ function _getSYEquivalentTokenPrice() internal view virtual returns (uint256) {
76
+ uint256 rawPrice = uint256(IChainlinkAggregator(feed).latestAnswer());
77
+ return feedDecimals < 18 ? rawPrice * 10 ** (18 - feedDecimals) : rawPrice / 10 ** (feedDecimals - 18);
78
+ }
79
+
80
+ // ------------------ NOT TO INCLUDE IN PRODUCTION CODE ------------------
81
+
82
+ error IncreaseCardinalityRequired(uint16 cardinalityRequired);
83
+ error AdditionalWaitRequired(uint32 duration);
84
+
85
+ /// @notice Call only once for each (market, duration). Once successful, it's permanently valid (also for any shorter duration).
86
+ function checkOracleState() external view {
87
+ (bool increaseCardinalityRequired, uint16 cardinalityRequired, bool oldestObservationSatisfied) = IPPYLpOracle(
88
+ pyLpOracle
89
+ ).getOracleState(market, twapDuration);
90
+
91
+ if (increaseCardinalityRequired) {
92
+ // It's required to call IPMarket(market).increaseObservationsCardinalityNext(cardinalityRequired) and wait for
93
+ // at least the twapDuration, to allow data population.
94
+ revert IncreaseCardinalityRequired(cardinalityRequired);
95
+ }
96
+
97
+ if (!oldestObservationSatisfied) {
98
+ // It's necessary to wait for at least the twapDuration, to allow data population.
99
+ revert AdditionalWaitRequired(twapDuration);
100
+ }
101
+ }
102
+ }
@@ -79,16 +79,18 @@ contract ActionMiscV3 is IPActionMiscV3, ActionBase {
79
79
  address[] calldata yts,
80
80
  address[] calldata markets
81
81
  ) external {
82
- for (uint256 i = 0; i < sys.length; ++i) {
83
- IStandardizedYield(sys[i]).claimRewards(user);
84
- }
85
-
86
- for (uint256 i = 0; i < yts.length; ++i) {
87
- IPYieldToken(yts[i]).redeemDueInterestAndRewards(user, true, true);
88
- }
89
-
90
- for (uint256 i = 0; i < markets.length; ++i) {
91
- IPMarket(markets[i]).redeemRewards(user);
82
+ unchecked {
83
+ for (uint256 i = 0; i < sys.length; ++i) {
84
+ IStandardizedYield(sys[i]).claimRewards(user);
85
+ }
86
+
87
+ for (uint256 i = 0; i < yts.length; ++i) {
88
+ IPYieldToken(yts[i]).redeemDueInterestAndRewards(user, true, true);
89
+ }
90
+
91
+ for (uint256 i = 0; i < markets.length; ++i) {
92
+ IPMarket(markets[i]).redeemRewards(user);
93
+ }
92
94
  }
93
95
  }
94
96
 
@@ -116,156 +118,40 @@ contract ActionMiscV3 is IPActionMiscV3, ActionBase {
116
118
  netTokenOut = IStandardizedYield(SY).redeem(receiver, netSyInterm, tokenRedeemSy, minTokenOut, true);
117
119
  }
118
120
 
119
- // TODO: need to allow exit to SY as well
120
- // TODO: check against minOut
121
- // double check event orders
122
-
123
- function exitPreExpToToken(
124
- address receiver,
125
- address market,
126
- uint256 netPtIn,
127
- uint256 netYtIn,
128
- uint256 netLpIn,
129
- TokenOutput calldata output,
130
- LimitOrderData calldata limit
131
- ) external returns (uint256 totalTokenOut, ExitPreExpReturnParams memory params) {
132
- IStandardizedYield SY;
133
-
134
- (SY, params) = _exitPreExpToSy(true, address(0), market, netPtIn, netYtIn, netLpIn, limit);
135
- totalTokenOut = _redeemSyToToken(receiver, address(SY), params.totalSyOut, output, false);
136
-
137
- emit ExitPreExpToToken(msg.sender, market, output.tokenOut, receiver, netLpIn, totalTokenOut, params);
138
- }
139
-
140
- function exitPreExpToSy(
141
- address receiver,
142
- address market,
143
- uint256 netPtIn,
144
- uint256 netYtIn,
145
- uint256 netLpIn,
146
- uint256 minSyOut,
147
- LimitOrderData calldata limit
148
- ) external returns (ExitPreExpReturnParams memory params) {
149
- (, params) = _exitPreExpToSy(false, receiver, market, netPtIn, netYtIn, netLpIn, limit);
150
- require(params.totalSyOut >= minSyOut, "Slippage: INSUFFICIENT_SY_OUT");
151
-
152
- emit ExitPreExpToSy(msg.sender, market, receiver, netLpIn, params);
153
- }
154
-
155
- function _exitPreExpToSy(
156
- bool setReceiverToSy,
157
- address receiver,
158
- address market,
159
- uint256 netPtIn,
160
- uint256 netYtIn,
161
- uint256 netLpIn,
162
- LimitOrderData calldata limit
163
- ) internal returns (IStandardizedYield SY, ExitPreExpReturnParams memory p) {
164
- IPPrincipalToken PT;
165
- IPYieldToken YT;
166
- (SY, PT, YT) = IPMarket(market).readTokens();
167
-
168
- if (setReceiverToSy) receiver = address(SY);
169
-
170
- if (netLpIn > 0) {
171
- _transferFrom(IERC20(market), msg.sender, market, netLpIn);
172
- (p.netSyFromRemove, p.netPtFromRemove) = IPMarket(market).burn(receiver, address(this), netLpIn);
173
- }
174
-
175
- if (netPtIn > 0) {
176
- _transferIn(address(PT), address(this), netPtIn);
177
- }
178
-
179
- p.netPyRedeem = PMath.min(p.netPtFromRemove + netPtIn, netYtIn);
180
-
181
- if (p.netPyRedeem > 0) {
182
- _transferOut(address(PT), address(YT), p.netPyRedeem);
183
- _transferFrom(YT, msg.sender, address(YT), p.netPyRedeem);
184
- p.netSyFromRedeem = IPYieldToken(YT).redeemPY(receiver);
185
- }
186
-
187
- p.netPtSwap = p.netPtFromRemove + netPtIn - p.netPyRedeem;
188
- p.netYtSwap = netYtIn - p.netPyRedeem;
189
-
190
- if (p.netPtSwap > 0) {
191
- address ptEntry = _entry_swapExactPtForSy(market, limit);
192
- if (ptEntry != address(this)) _transferOut(address(PT), ptEntry, p.netPtSwap);
193
- (p.netSyFromSwap, p.netSyFee) = _swapExactPtForSy(receiver, market, p.netPtSwap, 0, limit);
194
- } else if (p.netYtSwap > 0) {
195
- _transferFrom(YT, msg.sender, _entry_swapExactYtForSy(YT, limit), p.netYtSwap);
196
- (p.netSyFromSwap, p.netSyFee) = _swapExactYtForSy(receiver, market, SY, YT, p.netYtSwap, 0, limit);
197
- }
198
-
199
- p.totalSyOut = p.netSyFromRemove + p.netSyFromRedeem + p.netSyFromSwap;
200
- }
201
-
202
- function exitPostExpToToken(
203
- address receiver,
204
- address market,
205
- uint256 netPtIn,
206
- uint256 netLpIn,
207
- TokenOutput calldata output
208
- ) external returns (uint256 totalTokenOut, ExitPostExpReturnParams memory params) {
209
- IStandardizedYield SY;
210
-
211
- (SY, params) = _exitPostExpToSy(receiver, market, netPtIn, netLpIn);
212
- totalTokenOut = _redeemSyToToken(receiver, address(SY), params.totalSyOut, output, false);
213
-
214
- emit ExitPostExpToToken(msg.sender, market, output.tokenOut, receiver, netLpIn, totalTokenOut, params);
215
- }
216
-
217
- function exitPostExpToSy(
218
- address receiver,
219
- address market,
220
- uint256 netPtIn,
221
- uint256 netLpIn,
222
- uint256 minSyOut
223
- ) external returns (ExitPostExpReturnParams memory params) {
224
- (, params) = _exitPostExpToSy(receiver, market, netPtIn, netLpIn);
225
- require(params.totalSyOut >= minSyOut, "Slippage: INSUFFICIENT_SY_OUT");
226
-
227
- emit ExitPostExpToSy(msg.sender, market, receiver, netLpIn, params);
228
- }
229
-
230
- function _exitPostExpToSy(
231
- address receiver,
232
- address market,
233
- uint256 netPtIn,
234
- uint256 netLpIn
235
- ) internal returns (IStandardizedYield SY, ExitPostExpReturnParams memory p) {
236
- IPPrincipalToken PT;
237
- IPYieldToken YT;
238
- (SY, PT, YT) = IPMarket(market).readTokens();
239
-
240
- if (netLpIn > 0) {
241
- _transferFrom(IERC20(market), msg.sender, market, netLpIn);
242
- (p.netSyFromRemove, p.netPtFromRemove) = IPMarket(market).burn(receiver, address(YT), netLpIn);
243
- }
244
-
245
- if (netPtIn > 0) {
246
- _transferFrom(PT, msg.sender, address(YT), netPtIn);
247
- }
248
-
249
- p.netPtRedeem = p.netPtFromRemove + netPtIn;
250
- p.netSyFromRedeem = IPYieldToken(YT).redeemPY(receiver);
251
-
252
- p.totalSyOut = p.netSyFromRemove + p.netSyFromRedeem;
253
- }
254
-
255
121
  // ----------------- MISC FUNCTIONS -----------------
256
122
 
257
123
  function boostMarkets(address[] memory markets) external {
258
- for (uint256 i = 0; i < markets.length; i++) {
124
+ for (uint256 i = 0; i < markets.length; ) {
259
125
  IPMarket(markets[i]).transferFrom(msg.sender, markets[i], 0);
126
+ unchecked {
127
+ i++;
128
+ }
260
129
  }
261
130
  }
262
131
 
263
132
  function multicall(Call3[] calldata calls) external payable returns (Result[] memory res) {
264
133
  uint256 length = calls.length;
265
134
  res = new Result[](length);
266
- for (uint256 i = 0; i < length; i++) {
267
- (bool success, bytes memory result) = _delegateToSelf(calls[i].callData, calls[i].allowFailure);
268
- res[i] = Result(success, result);
135
+ Call3 calldata call;
136
+ for (uint256 i = 0; i < length; ) {
137
+ call = calls[i];
138
+
139
+ // delegatecall to itself, it turns allowing invoking functions from other actions
140
+ (bool success, bytes memory result) = address(this).delegatecall(call.callData);
141
+
142
+ if (!success && !call.allowFailure) {
143
+ assembly {
144
+ // We use Yul's revert() to bubble up errors from the target contract.
145
+ revert(add(32, result), mload(result))
146
+ }
147
+ }
148
+
149
+ res[i].success = success;
150
+ res[i].returnData = result;
151
+
152
+ unchecked {
153
+ ++i;
154
+ }
269
155
  }
270
156
  }
271
157
 
@@ -52,6 +52,51 @@ contract ActionSwapYTV3 is CallbackHelper, IPActionSwapYTV3, ActionBase {
52
52
  emit SwapYtAndSy(msg.sender, market, receiver, netYtOut.Int(), exactSyIn.neg());
53
53
  }
54
54
 
55
+ function _entry_swapExactSyForYt(IPYieldToken YT, LimitOrderData calldata limit) internal view returns (address) {
56
+ return !_isEmptyLimit(limit) ? address(this) : address(YT);
57
+ }
58
+
59
+ function _swapExactSyForYt(
60
+ address receiver,
61
+ address market,
62
+ IStandardizedYield SY,
63
+ IPYieldToken YT,
64
+ uint256 exactSyIn,
65
+ uint256 minYtOut,
66
+ ApproxParams calldata guessYtOut,
67
+ LimitOrderData calldata limit
68
+ ) internal returns (uint256 netYtOut, uint256 netSyFee) {
69
+ uint256 netSyLeft = exactSyIn;
70
+ bool doMarketOrder = true;
71
+
72
+ if (!_isEmptyLimit(limit)) {
73
+ (netSyLeft, netYtOut, netSyFee, doMarketOrder) = _fillLimit(receiver, SY, netSyLeft, limit);
74
+ if (doMarketOrder) {
75
+ _transferOut(address(SY), address(YT), netSyLeft);
76
+ }
77
+ }
78
+
79
+ if (doMarketOrder) {
80
+ (uint256 netYtOutMarket, ) = _readMarket(market).approxSwapExactSyForYt(
81
+ YT.newIndex(),
82
+ netSyLeft,
83
+ block.timestamp,
84
+ guessYtOut
85
+ );
86
+
87
+ (, uint256 netSyFeeMarket) = IPMarket(market).swapExactPtForSy(
88
+ address(YT),
89
+ netYtOutMarket, // exactPtIn = netYtOut
90
+ _encodeSwapExactSyForYt(receiver, YT)
91
+ );
92
+
93
+ netYtOut += netYtOutMarket;
94
+ netSyFee += netSyFeeMarket;
95
+ }
96
+
97
+ if (netYtOut < minYtOut) revert("Slippage: INSUFFICIENT_YT_OUT");
98
+ }
99
+
55
100
  // ------------------ SWAP TOKEN FOR TOKEN ------------------
56
101
 
57
102
  function swapExactYtForToken(
@@ -93,6 +138,46 @@ contract ActionSwapYTV3 is CallbackHelper, IPActionSwapYTV3, ActionBase {
93
138
  emit SwapYtAndSy(msg.sender, market, receiver, exactYtIn.neg(), netSyOut.Int());
94
139
  }
95
140
 
141
+ function _entry_swapExactYtForSy(IPYieldToken YT, LimitOrderData calldata limit) internal view returns (address) {
142
+ return !_isEmptyLimit(limit) ? address(this) : address(YT);
143
+ }
144
+
145
+ function _swapExactYtForSy(
146
+ address receiver,
147
+ address market,
148
+ IStandardizedYield SY,
149
+ IPYieldToken YT,
150
+ uint256 exactYtIn,
151
+ uint256 minSyOut,
152
+ LimitOrderData calldata limit
153
+ ) internal returns (uint256 netSyOut, uint256 netSyFee) {
154
+ uint256 netYtLeft = exactYtIn;
155
+ bool doMarketOrder = true;
156
+
157
+ if (!_isEmptyLimit(limit)) {
158
+ (netYtLeft, netSyOut, netSyFee, doMarketOrder) = _fillLimit(receiver, YT, netYtLeft, limit);
159
+ if (doMarketOrder) {
160
+ _transferOut(address(YT), address(YT), netYtLeft);
161
+ }
162
+ }
163
+
164
+ if (doMarketOrder) {
165
+ uint256 preSyBalance = SY.balanceOf(receiver);
166
+
167
+ (, uint256 netSyFeeMarket) = IPMarket(market).swapSyForExactPt(
168
+ address(YT),
169
+ netYtLeft, // exactPtOut = netYtLeft
170
+ _encodeSwapYtForSy(receiver, YT)
171
+ );
172
+
173
+ // avoid stack issue
174
+ netSyFee += netSyFeeMarket;
175
+ netSyOut += SY.balanceOf(receiver) - preSyBalance;
176
+ }
177
+
178
+ if (netSyOut < minSyOut) revert("Slippage: INSUFFICIENT_SY_OUT");
179
+ }
180
+
96
181
  // ------------------ SWAP PT FOR YT ------------------
97
182
 
98
183
  function swapExactPtForYt(
@@ -10,10 +10,8 @@ import "../../router/base/MarketApproxLib.sol";
10
10
 
11
11
  import "../../core/libraries/Errors.sol";
12
12
  import "../swap-aggregator/IPSwapAggregator.sol";
13
- import "./CallbackHelper.sol";
14
13
 
15
- abstract contract ActionBase is TokenHelper, CallbackHelper, IPLimitOrderType {
16
- using MarketApproxPtInLib for MarketState;
14
+ abstract contract ActionBase is TokenHelper, IPLimitOrderType {
17
15
  using MarketApproxPtOutLib for MarketState;
18
16
  using PMath for uint256;
19
17
  using PYIndexLib for IPYieldToken;
@@ -238,93 +236,6 @@ abstract contract ActionBase is TokenHelper, CallbackHelper, IPLimitOrderType {
238
236
  if (netPtOut < minPtOut) revert("Slippage: INSUFFICIENT_PT_OUT");
239
237
  }
240
238
 
241
- // ----------------- YT SWAP -----------------
242
-
243
- function _entry_swapExactYtForSy(IPYieldToken YT, LimitOrderData calldata limit) internal view returns (address) {
244
- return !_isEmptyLimit(limit) ? address(this) : address(YT);
245
- }
246
-
247
- function _swapExactYtForSy(
248
- address receiver,
249
- address market,
250
- IStandardizedYield SY,
251
- IPYieldToken YT,
252
- uint256 exactYtIn,
253
- uint256 minSyOut,
254
- LimitOrderData calldata limit
255
- ) internal returns (uint256 netSyOut, uint256 netSyFee) {
256
- uint256 netYtLeft = exactYtIn;
257
- bool doMarketOrder = true;
258
-
259
- if (!_isEmptyLimit(limit)) {
260
- (netYtLeft, netSyOut, netSyFee, doMarketOrder) = _fillLimit(receiver, YT, netYtLeft, limit);
261
- if (doMarketOrder) {
262
- _transferOut(address(YT), address(YT), netYtLeft);
263
- }
264
- }
265
-
266
- if (doMarketOrder) {
267
- uint256 preSyBalance = SY.balanceOf(receiver);
268
-
269
- (, uint256 netSyFeeMarket) = IPMarket(market).swapSyForExactPt(
270
- address(YT),
271
- netYtLeft, // exactPtOut = netYtLeft
272
- _encodeSwapYtForSy(receiver, YT)
273
- );
274
-
275
- // avoid stack issue
276
- netSyFee += netSyFeeMarket;
277
- netSyOut += SY.balanceOf(receiver) - preSyBalance;
278
- }
279
-
280
- if (netSyOut < minSyOut) revert("Slippage: INSUFFICIENT_SY_OUT");
281
- }
282
-
283
- function _entry_swapExactSyForYt(IPYieldToken YT, LimitOrderData calldata limit) internal view returns (address) {
284
- return !_isEmptyLimit(limit) ? address(this) : address(YT);
285
- }
286
-
287
- function _swapExactSyForYt(
288
- address receiver,
289
- address market,
290
- IStandardizedYield SY,
291
- IPYieldToken YT,
292
- uint256 exactSyIn,
293
- uint256 minYtOut,
294
- ApproxParams calldata guessYtOut,
295
- LimitOrderData calldata limit
296
- ) internal returns (uint256 netYtOut, uint256 netSyFee) {
297
- uint256 netSyLeft = exactSyIn;
298
- bool doMarketOrder = true;
299
-
300
- if (!_isEmptyLimit(limit)) {
301
- (netSyLeft, netYtOut, netSyFee, doMarketOrder) = _fillLimit(receiver, SY, netSyLeft, limit);
302
- if (doMarketOrder) {
303
- _transferOut(address(SY), address(YT), netSyLeft);
304
- }
305
- }
306
-
307
- if (doMarketOrder) {
308
- (uint256 netYtOutMarket, ) = _readMarket(market).approxSwapExactSyForYt(
309
- YT.newIndex(),
310
- netSyLeft,
311
- block.timestamp,
312
- guessYtOut
313
- );
314
-
315
- (, uint256 netSyFeeMarket) = IPMarket(market).swapExactPtForSy(
316
- address(YT),
317
- netYtOutMarket, // exactPtIn = netYtOut
318
- _encodeSwapExactSyForYt(receiver, YT)
319
- );
320
-
321
- netYtOut += netYtOutMarket;
322
- netSyFee += netSyFeeMarket;
323
- }
324
-
325
- if (netYtOut < minYtOut) revert("Slippage: INSUFFICIENT_YT_OUT");
326
- }
327
-
328
239
  // ----------------- LIMIT ORDERS -----------------
329
240
  function _fillLimit(
330
241
  address receiver,
@@ -373,20 +284,4 @@ abstract contract ActionBase is TokenHelper, CallbackHelper, IPLimitOrderType {
373
284
  function _isEmptyLimit(LimitOrderData calldata a) internal pure returns (bool) {
374
285
  return a.normalFills.length == 0 && a.flashFills.length == 0;
375
286
  }
376
-
377
- // ----------------- DELEGATE CALL -----------------
378
-
379
- function _delegateToSelf(
380
- bytes memory data,
381
- bool allowFailure
382
- ) internal returns (bool success, bytes memory result) {
383
- (success, result) = address(this).delegatecall(data);
384
-
385
- if (!success && !allowFailure) {
386
- assembly {
387
- // We use Yul's revert() to bubble up errors from the target contract.
388
- revert(add(32, result), mload(result))
389
- }
390
- }
391
- }
392
287
  }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "SY ezETH",
3
+ "SY": "0x22E12A50e3ca49FB183074235cB1db84Fe4C716D",
4
+ "YT": "0x1623F1A991584A6b69baBbdbffD26E2B46485465",
5
+ "PT": "0x248241244356D18f63d0c16082996839ecB0C7bF",
6
+ "market": "0xcDBD5ff3E03b6828Db9C32e2131A60ABA5137901",
7
+ "expiry": 1727308800,
8
+ "scalarRoot": "7728447732000000000",
9
+ "initAnchor": "1116672357000000000",
10
+ "lnFeeRateRoot": "2995508979000000"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "SY pufETH",
3
+ "SY": "0x253008ba4aE2f3E6488DC998a5321D4EB1a0c905",
4
+ "YT": "0x1a65eB80a2ac3ea6E41D456DdD6E9cC5728BEf7C",
5
+ "PT": "0xd4e75971eAF78a8d93D96df530f1FFf5f9F53288",
6
+ "market": "0xA54FC268101c8b97DE19eF3141d34751a11996B2",
7
+ "expiry": 1727308800,
8
+ "scalarRoot": "7770558179000000000",
9
+ "initAnchor": "1110275954000000000",
10
+ "lnFeeRateRoot": "2995508979000000"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "SY rsETH",
3
+ "SY": "0x730A5E2AcEbccAA5e9095723B3CB862739DA793c",
4
+ "YT": "0xE653E4048620E546AFff02D3689678896d22e236",
5
+ "PT": "0x7bAf258049cc8B9A78097723dc19a8b103D4098F",
6
+ "market": "0x6b4740722e46048874d84306B2877600ABCea3Ae",
7
+ "expiry": 1727308800,
8
+ "scalarRoot": "7770558179000000000",
9
+ "initAnchor": "1110275954000000000",
10
+ "lnFeeRateRoot": "2995508979000000"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "SY rswETH",
3
+ "SY": "0x4f3A7a07A968B67F1f9692b70242f10E665d38Ad",
4
+ "YT": "0xf0E4244Ca93Ac36752DA5939Afd9CB73B0637b06",
5
+ "PT": "0x0a0E172511114456EC63A85FF32E45C5e0E27D63",
6
+ "market": "0x1e0c2e41f3165ff6B8a660092f63E10BC0EebE26",
7
+ "expiry": 1721865600,
8
+ "scalarRoot": "8113474588000000000",
9
+ "initAnchor": "1061316437000000000",
10
+ "lnFeeRateRoot": "2995508979000000"
11
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "SUSDE-MAINNET-SEP2024",
3
+ "SY": "0x4139cDC6345aFFbaC0692b43bed4D059Df3e6d65",
4
+ "YT": "0xdc02b77a3986da62C7A78FED73949C9767850809",
5
+ "PT": "0x6c9f097e044506712B58EAC670c9a5fd4BCceF13",
6
+ "market": "0xd1D7D99764f8a52Aff007b7831cc02748b2013b5",
7
+ "expiry": 1727308800,
8
+ "lnFeeRateRoot": "2995508979000000",
9
+ "scalarRoot": "8580934398000000000",
10
+ "initAnchor": "1120006408000000000",
11
+ "doCacheIndexSameBlock": true,
12
+ "deployTxHash": "0x467c0c15148778d0b99a1d9f3bd7406fd0c58d8a6e3284a57a50e55ae0160165"
13
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "SY weETH",
3
+ "SY": "0xAC0047886a985071476a1186bE89222659970d65",
4
+ "YT": "0xA54Df645A042D24121a737dAA89a57EbF8E0b71c",
5
+ "PT": "0x1c085195437738d73d75DC64bC5A3E098b7f93b1",
6
+ "market": "0xC8eDd52D0502Aa8b4D5C77361D4B3D300e8fC81c",
7
+ "expiry": 1727308800,
8
+ "scalarRoot": "7728447732000000000",
9
+ "initAnchor": "1116672357000000000",
10
+ "lnFeeRateRoot": "2995508979000000"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "SY ezETH",
3
+ "SY": "0x0dE802e3D6Cc9145A150bBDc8da9F988a98c5202",
4
+ "YT": "0xE58AfaA6E2abF9A9F243D5A55Bd5447628c4D811",
5
+ "PT": "0x2CCFce9bE49465CC6f947b5F6aC9383673733Da9",
6
+ "market": "0x35f3dB08a6e9cB4391348b0B404F493E7ae264c0",
7
+ "expiry": 1727308800,
8
+ "scalarRoot": "7728447732000000000",
9
+ "initAnchor": "1116672357000000000",
10
+ "lnFeeRateRoot": "2995508979000000"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "SY rsETH",
3
+ "SY": "0xf176fB51F4eB826136a54FDc71C50fCd2202E272",
4
+ "YT": "0x2FDc424946AA72D42E2F897447d7c335E64845F0",
5
+ "PT": "0x30c98c0139B62290E26aC2a2158AC341Dcaf1333",
6
+ "market": "0x1d38d4204159aA5e767aFbA8f76BE22117De61E5",
7
+ "expiry": 1727308800,
8
+ "scalarRoot": "7770558179000000000",
9
+ "initAnchor": "1110275954000000000",
10
+ "lnFeeRateRoot": "29999550000000"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "SY sETH-pteETHSilo",
3
+ "SY": "0xd0c4351a18F40b96b6446Da3A191496DF36d60F9",
4
+ "YT": "0x7Cfb81E9c9402D48c6F3161204a21800b210BAeA",
5
+ "PT": "0x2D5405688f253D741a9F1090DD90D8A285CF5C79",
6
+ "market": "0x6aBE9Ac2df48490693BdB9d66Fa898fc9cD7cc36",
7
+ "expiry": 1719446400,
8
+ "scalarRoot": "10324763686000000000",
9
+ "initAnchor": "1041846750000000000",
10
+ "lnFeeRateRoot": "499875041000000"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "SY sETH-ptezETHSilo",
3
+ "SY": "0x8242F81F7B06C1e67bC80DFD2B2716f58bD46651",
4
+ "YT": "0x8138E8cAC470Dc963437b055834B54D56d6d6a29",
5
+ "PT": "0xd7e810aEd2988B8A7eA0187d55C939110b178521",
6
+ "market": "0xCf602767e9c82194DaF58EB67a3169d60DbAaC62",
7
+ "expiry": 1719446400,
8
+ "scalarRoot": "10324763686000000000",
9
+ "initAnchor": "1041846750000000000",
10
+ "lnFeeRateRoot": "499875041000000"
11
+ }
@@ -0,0 +1,11 @@
1
+ {
2
+ "name": "SY weETH",
3
+ "SY": "0xa6C895EB332E91c5b3D00B7baeEAae478cc502DA",
4
+ "YT": "0xfB2A7AC0372C2425c273932f8d438518402A873E",
5
+ "PT": "0xb8b0a120F6A68Dd06209619F62429fB1a8e92feC",
6
+ "market": "0xf9F9779d8fF604732EBA9AD345E6A27EF5c2a9d6",
7
+ "expiry": 1727308800,
8
+ "scalarRoot": "7728447732000000000",
9
+ "initAnchor": "1116672357000000000",
10
+ "lnFeeRateRoot": "2995508979000000"
11
+ }