@pendle/core-v2 4.5.0 → 4.5.1-beta-2
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.
- package/build/artifacts/contracts/core/StandardizedYield/implementations/PendleERC20WithSupplyCapSY.sol/PendleERC20WithSupplyCapSY.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPActionMiscV3.sol/IPActionMiscV3.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPActionMiscV3.sol/IPActionMiscV3.json +1156 -34
- package/build/artifacts/contracts/interfaces/IPAllActionV3.sol/IPAllActionV3.dbg.json +1 -1
- package/build/artifacts/contracts/interfaces/IPAllActionV3.sol/IPAllActionV3.json +1183 -61
- package/build/artifacts/contracts/offchain-helpers/PendlePoolDeployHelper.sol/PendlePoolDeployHelper.dbg.json +1 -1
- package/build/artifacts/contracts/offchain-helpers/PendlePoolDeployHelper.sol/PendlePoolDeployHelper.json +2 -2
- package/build/artifacts/contracts/offchain-helpers/router-static/base/ActionMarketAuxStatic.sol/ActionMarketAuxStatic.dbg.json +1 -1
- package/build/artifacts/contracts/router/ActionAddRemoveLiqV3.sol/ActionAddRemoveLiqV3.dbg.json +1 -1
- package/build/artifacts/contracts/router/ActionAddRemoveLiqV3.sol/ActionAddRemoveLiqV3.json +2 -2
- package/build/artifacts/contracts/router/ActionMiscV3.sol/ActionMiscV3.dbg.json +1 -1
- package/build/artifacts/contracts/router/ActionMiscV3.sol/ActionMiscV3.json +1158 -36
- package/build/artifacts/contracts/router/ActionSwapPTV3.sol/ActionSwapPTV3.dbg.json +1 -1
- package/build/artifacts/contracts/router/ActionSwapPTV3.sol/ActionSwapPTV3.json +2 -2
- package/build/artifacts/contracts/router/ActionSwapYTV3.sol/ActionSwapYTV3.dbg.json +1 -1
- package/build/artifacts/contracts/router/ActionSwapYTV3.sol/ActionSwapYTV3.json +2 -2
- package/build/artifacts/contracts/router/base/ActionBase.sol/ActionBase.dbg.json +1 -1
- package/contracts/interfaces/IPActionMiscV3.sol +92 -0
- package/contracts/router/ActionMiscV3.sol +150 -36
- package/contracts/router/ActionSwapYTV3.sol +0 -85
- package/contracts/router/base/ActionBase.sol +106 -1
- package/deployments/merkle-distribution/2024-04-25.json +14930 -0
- package/package.json +1 -1
- package/typechain-types/ActionMiscV3.ts +573 -16
- package/typechain-types/IPActionMiscV3.ts +573 -16
- package/typechain-types/IPAllActionV3.ts +480 -0
- package/typechain-types/ISwellSimpleStakingERC20.ts +289 -0
- package/typechain-types/PendleSwellRswETHStakingSY.ts +1325 -0
- package/typechain-types/PendleSwellStakingERC20SY.ts +1299 -0
- package/typechain-types/factories/ActionAddRemoveLiqV3__factory.ts +1 -1
- package/typechain-types/factories/ActionMiscV3__factory.ts +1157 -35
- package/typechain-types/factories/ActionSwapPTV3__factory.ts +1 -1
- package/typechain-types/factories/ActionSwapYTV3__factory.ts +1 -1
- package/typechain-types/factories/IPActionMiscV3__factory.ts +1156 -34
- package/typechain-types/factories/IPAllActionV3__factory.ts +1183 -61
- package/typechain-types/factories/ISwellSimpleStakingERC20__factory.ts +226 -0
- package/typechain-types/factories/PendlePoolDeployHelper__factory.ts +1 -1
- package/typechain-types/factories/PendleSwellRswETHStakingSY__factory.ts +1106 -0
- package/typechain-types/factories/PendleSwellStakingERC20SY__factory.ts +1112 -0
|
@@ -79,18 +79,16 @@ contract ActionMiscV3 is IPActionMiscV3, ActionBase {
|
|
|
79
79
|
address[] calldata yts,
|
|
80
80
|
address[] calldata markets
|
|
81
81
|
) external {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
IPMarket(markets[i]).redeemRewards(user);
|
|
93
|
-
}
|
|
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);
|
|
94
92
|
}
|
|
95
93
|
}
|
|
96
94
|
|
|
@@ -118,40 +116,156 @@ contract ActionMiscV3 is IPActionMiscV3, ActionBase {
|
|
|
118
116
|
netTokenOut = IStandardizedYield(SY).redeem(receiver, netSyInterm, tokenRedeemSy, minTokenOut, true);
|
|
119
117
|
}
|
|
120
118
|
|
|
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
|
+
|
|
121
255
|
// ----------------- MISC FUNCTIONS -----------------
|
|
122
256
|
|
|
123
257
|
function boostMarkets(address[] memory markets) external {
|
|
124
|
-
for (uint256 i = 0; i < markets.length; ) {
|
|
258
|
+
for (uint256 i = 0; i < markets.length; i++) {
|
|
125
259
|
IPMarket(markets[i]).transferFrom(msg.sender, markets[i], 0);
|
|
126
|
-
unchecked {
|
|
127
|
-
i++;
|
|
128
|
-
}
|
|
129
260
|
}
|
|
130
261
|
}
|
|
131
262
|
|
|
132
263
|
function multicall(Call3[] calldata calls) external payable returns (Result[] memory res) {
|
|
133
264
|
uint256 length = calls.length;
|
|
134
265
|
res = new Result[](length);
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
}
|
|
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);
|
|
155
269
|
}
|
|
156
270
|
}
|
|
157
271
|
|
|
@@ -52,51 +52,6 @@ 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
|
-
|
|
100
55
|
// ------------------ SWAP TOKEN FOR TOKEN ------------------
|
|
101
56
|
|
|
102
57
|
function swapExactYtForToken(
|
|
@@ -138,46 +93,6 @@ contract ActionSwapYTV3 is CallbackHelper, IPActionSwapYTV3, ActionBase {
|
|
|
138
93
|
emit SwapYtAndSy(msg.sender, market, receiver, exactYtIn.neg(), netSyOut.Int());
|
|
139
94
|
}
|
|
140
95
|
|
|
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
|
-
|
|
181
96
|
// ------------------ SWAP PT FOR YT ------------------
|
|
182
97
|
|
|
183
98
|
function swapExactPtForYt(
|
|
@@ -10,8 +10,10 @@ 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";
|
|
13
14
|
|
|
14
|
-
abstract contract ActionBase is TokenHelper, IPLimitOrderType {
|
|
15
|
+
abstract contract ActionBase is TokenHelper, CallbackHelper, IPLimitOrderType {
|
|
16
|
+
using MarketApproxPtInLib for MarketState;
|
|
15
17
|
using MarketApproxPtOutLib for MarketState;
|
|
16
18
|
using PMath for uint256;
|
|
17
19
|
using PYIndexLib for IPYieldToken;
|
|
@@ -236,6 +238,93 @@ abstract contract ActionBase is TokenHelper, IPLimitOrderType {
|
|
|
236
238
|
if (netPtOut < minPtOut) revert("Slippage: INSUFFICIENT_PT_OUT");
|
|
237
239
|
}
|
|
238
240
|
|
|
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
|
+
|
|
239
328
|
// ----------------- LIMIT ORDERS -----------------
|
|
240
329
|
function _fillLimit(
|
|
241
330
|
address receiver,
|
|
@@ -284,4 +373,20 @@ abstract contract ActionBase is TokenHelper, IPLimitOrderType {
|
|
|
284
373
|
function _isEmptyLimit(LimitOrderData calldata a) internal pure returns (bool) {
|
|
285
374
|
return a.normalFills.length == 0 && a.flashFills.length == 0;
|
|
286
375
|
}
|
|
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
|
+
}
|
|
287
392
|
}
|