@pendle/core-v2 0.5.1-beta-5 → 0.6.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.
- package/contracts/SuperComposableYield/ISuperComposableYield.sol +2 -0
- package/contracts/SuperComposableYield/implementations/RewardManager.sol +35 -20
- package/contracts/SuperComposableYield/implementations/SCYBase.sol +39 -19
- package/contracts/SuperComposableYield/implementations/SCYBaseWithRewards.sol +26 -14
- package/contracts/core/PendleBaseToken.sol +2 -2
- package/contracts/core/PendleMarket.sol +145 -61
- package/contracts/core/PendleMarketFactory.sol +30 -19
- package/contracts/core/{PendleOwnershipToken.sol → PendlePrincipalToken.sol} +14 -2
- package/contracts/core/PendleRouter.sol +23 -9
- package/contracts/core/PendleSCYImpl/AaveV3/PendleAaveV3SCY.sol +21 -20
- package/contracts/core/PendleSCYImpl/PendleBenQiErc20SCY.sol +22 -16
- package/contracts/core/PendleSCYImpl/PendleBtrflySCY.sol +13 -13
- package/contracts/core/PendleSCYImpl/PendleStETHSCY.sol +107 -0
- package/contracts/core/PendleSCYImpl/PendleYearnVaultSCY.sol +14 -15
- package/contracts/core/PendleYieldContractFactory.sol +29 -14
- package/contracts/core/PendleYieldToken.sol +130 -76
- package/contracts/core/RouterStatic.sol +16 -157
- package/contracts/core/actions/ActionCallback.sol +36 -18
- package/contracts/core/actions/ActionCore.sol +41 -88
- package/contracts/core/actions/ActionRedeem.sol +36 -0
- package/contracts/core/actions/ActionYT.sol +41 -59
- package/contracts/core/actions/base/{ActionSCYAndOTBase.sol → ActionSCYAndPTBase.sol} +59 -45
- package/contracts/core/actions/base/{ActionSCYAndYOBase.sol → ActionSCYAndPYBase.sol} +57 -19
- package/contracts/core/actions/base/ActionSCYAndYTBase.sol +31 -21
- package/contracts/interfaces/IPActionCore.sol +21 -28
- package/contracts/interfaces/IPActionRedeem.sol +17 -0
- package/contracts/interfaces/IPActionYT.sol +5 -12
- package/contracts/interfaces/IPAllAction.sol +2 -2
- package/contracts/interfaces/IPMarket.sol +33 -10
- package/contracts/interfaces/IPMarketAddRemoveCallback.sol +2 -2
- package/contracts/interfaces/IPMarketFactory.sol +3 -1
- package/contracts/interfaces/IPMarketSwapCallback.sol +1 -1
- package/contracts/interfaces/{IPOwnershipToken.sol → IPPrincipalToken.sol} +1 -1
- package/contracts/interfaces/IPRouterStatic.sol +7 -82
- package/contracts/interfaces/IPYieldContractFactory.sol +10 -2
- package/contracts/interfaces/IPYieldToken.sol +14 -5
- package/contracts/interfaces/IWstETH.sol +10 -0
- package/contracts/libraries/JoeLibrary.sol +1 -1
- package/contracts/libraries/math/LogExpMath.sol +1 -1
- package/contracts/libraries/math/MarketApproxLib.sol +128 -88
- package/contracts/libraries/math/MarketMathAux.sol +13 -13
- package/contracts/libraries/math/MarketMathCore.sol +62 -93
- package/contracts/libraries/math/Math.sol +14 -2
- package/contracts/periphery/PendleGovernanceManager.sol +5 -3
- package/package.json +3 -2
|
@@ -8,7 +8,7 @@ import "../../interfaces/IPMarketSwapCallback.sol";
|
|
|
8
8
|
import "../../SuperComposableYield/SCYUtils.sol";
|
|
9
9
|
import "../../libraries/math/MarketApproxLib.sol";
|
|
10
10
|
import "../../libraries/math/MarketMathAux.sol";
|
|
11
|
-
import "./base/
|
|
11
|
+
import "./base/ActionSCYAndPYBase.sol";
|
|
12
12
|
import "./base/ActionType.sol";
|
|
13
13
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
14
14
|
|
|
@@ -26,62 +26,80 @@ contract ActionCallback is IPMarketSwapCallback, ActionType {
|
|
|
26
26
|
|
|
27
27
|
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
28
28
|
constructor(address _marketFactory) {
|
|
29
|
+
require(_marketFactory != address(0), "zero address");
|
|
29
30
|
marketFactory = _marketFactory;
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
/**
|
|
34
|
+
* @dev The callback is only callable by a Pendle Market created by the factory
|
|
35
|
+
*/
|
|
32
36
|
function swapCallback(
|
|
33
|
-
int256
|
|
37
|
+
int256 ptToAccount,
|
|
34
38
|
int256 scyToAccount,
|
|
35
39
|
bytes calldata data
|
|
36
40
|
) external override onlyPendleMarket(msg.sender) {
|
|
37
|
-
(ACTION_TYPE swapType, ) = abi.decode(data, (ACTION_TYPE,
|
|
38
|
-
|
|
41
|
+
(ACTION_TYPE swapType, ) = abi.decode(data, (ACTION_TYPE, address));
|
|
39
42
|
if (swapType == ACTION_TYPE.SwapExactScyForYt) {
|
|
40
|
-
_swapExactScyForYt_callback(msg.sender, data);
|
|
43
|
+
_swapExactScyForYt_callback(msg.sender, ptToAccount, scyToAccount, data);
|
|
41
44
|
} else if (swapType == ACTION_TYPE.SwapSCYForExactYt) {
|
|
42
|
-
_swapScyForExactYt_callback(msg.sender,
|
|
45
|
+
_swapScyForExactYt_callback(msg.sender, ptToAccount, scyToAccount, data);
|
|
43
46
|
} else if (
|
|
44
47
|
swapType == ACTION_TYPE.SwapYtForExactScy || swapType == ACTION_TYPE.SwapExactYtForScy
|
|
45
48
|
) {
|
|
46
|
-
_swapYtForScy_callback(msg.sender, scyToAccount, data);
|
|
49
|
+
_swapYtForScy_callback(msg.sender, ptToAccount, scyToAccount, data);
|
|
47
50
|
} else {
|
|
48
51
|
require(false, "unknown swapType");
|
|
49
52
|
}
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
function _swapExactScyForYt_callback(
|
|
55
|
+
function _swapExactScyForYt_callback(
|
|
56
|
+
address market,
|
|
57
|
+
int256 ptToAccount,
|
|
58
|
+
int256, /*scyToAccount*/
|
|
59
|
+
bytes calldata data
|
|
60
|
+
) internal {
|
|
53
61
|
(, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
54
62
|
(, address receiver) = abi.decode(data, (ACTION_TYPE, address));
|
|
55
63
|
|
|
56
|
-
|
|
64
|
+
uint256 ptOwed = ptToAccount.abs();
|
|
65
|
+
uint256 amountPYout = YT.mintPY(market, receiver);
|
|
66
|
+
|
|
67
|
+
require(amountPYout >= ptOwed, "insufficient pt to pay");
|
|
57
68
|
}
|
|
58
69
|
|
|
59
70
|
function _swapScyForExactYt_callback(
|
|
60
71
|
address market,
|
|
61
|
-
int256
|
|
72
|
+
int256 ptToAccount,
|
|
62
73
|
int256 scyToAccount,
|
|
63
74
|
bytes calldata data
|
|
64
75
|
) internal {
|
|
65
76
|
(, address payer, address receiver) = abi.decode(data, (ACTION_TYPE, address, address));
|
|
66
77
|
(ISuperComposableYield SCY, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
67
78
|
|
|
68
|
-
uint256
|
|
79
|
+
uint256 ptOwed = ptToAccount.neg().Uint();
|
|
69
80
|
uint256 scyReceived = scyToAccount.Uint();
|
|
70
81
|
|
|
71
|
-
//
|
|
72
|
-
uint256
|
|
82
|
+
// ptOwed = totalAsset
|
|
83
|
+
uint256 scyIndex = SCY.scyIndexCurrent();
|
|
84
|
+
uint256 scyNeedTotal = SCYUtils.assetToScy(scyIndex, ptOwed);
|
|
85
|
+
scyNeedTotal += scyIndex.rawDivUp(SCYUtils.ONE);
|
|
86
|
+
|
|
87
|
+
{
|
|
88
|
+
uint256 netScyToPull = scyNeedTotal.subMax0(scyReceived);
|
|
89
|
+
SCY.safeTransferFrom(payer, address(YT), netScyToPull);
|
|
90
|
+
}
|
|
73
91
|
|
|
74
|
-
uint256
|
|
75
|
-
SCY.safeTransferFrom(payer, address(YT), netScyToPull);
|
|
92
|
+
uint256 amountPYout = YT.mintPY(market, receiver);
|
|
76
93
|
|
|
77
|
-
|
|
94
|
+
require(amountPYout >= ptOwed, "insufficient pt to pay");
|
|
78
95
|
}
|
|
79
96
|
|
|
80
97
|
/**
|
|
81
|
-
@dev receive
|
|
98
|
+
@dev receive PT -> pair with YT to redeem SCY -> payback SCY
|
|
82
99
|
*/
|
|
83
100
|
function _swapYtForScy_callback(
|
|
84
101
|
address market,
|
|
102
|
+
int256, /*ptToAccount*/
|
|
85
103
|
int256 scyToAccount,
|
|
86
104
|
bytes calldata data
|
|
87
105
|
) internal {
|
|
@@ -90,7 +108,7 @@ contract ActionCallback is IPMarketSwapCallback, ActionType {
|
|
|
90
108
|
|
|
91
109
|
uint256 scyOwed = scyToAccount.neg().Uint();
|
|
92
110
|
|
|
93
|
-
uint256 netScyReceived = YT.
|
|
111
|
+
uint256 netScyReceived = YT.redeemPY(address(this));
|
|
94
112
|
|
|
95
113
|
SCY.safeTransfer(market, scyOwed);
|
|
96
114
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
3
|
|
|
4
|
-
import "./base/
|
|
5
|
-
import "./base/
|
|
6
|
-
import "../../interfaces/
|
|
4
|
+
import "./base/ActionSCYAndPTBase.sol";
|
|
5
|
+
import "./base/ActionSCYAndPYBase.sol";
|
|
6
|
+
import "../../interfaces/IPPrincipalToken.sol";
|
|
7
7
|
import "../../interfaces/IPYieldToken.sol";
|
|
8
8
|
import "../../interfaces/IPActionCore.sol";
|
|
9
9
|
import "../../libraries/math/MarketMathAux.sol";
|
|
10
10
|
|
|
11
|
-
contract ActionCore is IPActionCore,
|
|
11
|
+
contract ActionCore is IPActionCore, ActionSCYAndPTBase, ActionSCYAndPYBase {
|
|
12
12
|
using MarketMathCore for MarketState;
|
|
13
13
|
using MarketMathAux for MarketState;
|
|
14
14
|
using Math for uint256;
|
|
@@ -20,19 +20,15 @@ contract ActionCore is IPActionCore, ActionSCYAndOTBase, ActionSCYAndYOBase {
|
|
|
20
20
|
address _joeFactory,
|
|
21
21
|
address _marketFactory
|
|
22
22
|
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//solhint-disable-next-line no-empty-blocks
|
|
26
|
-
{
|
|
27
|
-
|
|
28
|
-
}
|
|
23
|
+
ActionSCYAndPYBase(_joeRouter, _joeFactory) //solhint-disable-next-line no-empty-blocks
|
|
24
|
+
{}
|
|
29
25
|
|
|
30
26
|
/// @dev docs can be found in the internal function
|
|
31
27
|
function addLiquidity(
|
|
32
28
|
address receiver,
|
|
33
29
|
address market,
|
|
34
30
|
uint256 scyDesired,
|
|
35
|
-
uint256
|
|
31
|
+
uint256 ptDesired,
|
|
36
32
|
uint256 minLpOut
|
|
37
33
|
)
|
|
38
34
|
external
|
|
@@ -42,7 +38,7 @@ contract ActionCore is IPActionCore, ActionSCYAndOTBase, ActionSCYAndYOBase {
|
|
|
42
38
|
uint256
|
|
43
39
|
)
|
|
44
40
|
{
|
|
45
|
-
return _addLiquidity(receiver, market, scyDesired,
|
|
41
|
+
return _addLiquidity(receiver, market, scyDesired, ptDesired, minLpOut, true);
|
|
46
42
|
}
|
|
47
43
|
|
|
48
44
|
/// @dev docs can be found in the internal function
|
|
@@ -51,79 +47,49 @@ contract ActionCore is IPActionCore, ActionSCYAndOTBase, ActionSCYAndYOBase {
|
|
|
51
47
|
address market,
|
|
52
48
|
uint256 lpToRemove,
|
|
53
49
|
uint256 scyOutMin,
|
|
54
|
-
uint256
|
|
50
|
+
uint256 ptOutMin
|
|
55
51
|
) external returns (uint256, uint256) {
|
|
56
|
-
return _removeLiquidity(receiver, market, lpToRemove, scyOutMin,
|
|
52
|
+
return _removeLiquidity(receiver, market, lpToRemove, scyOutMin, ptOutMin, true);
|
|
57
53
|
}
|
|
58
54
|
|
|
59
55
|
/// @dev docs can be found in the internal function
|
|
60
|
-
function
|
|
56
|
+
function swapExactPtForScy(
|
|
61
57
|
address receiver,
|
|
62
58
|
address market,
|
|
63
|
-
uint256
|
|
59
|
+
uint256 exactPtIn,
|
|
64
60
|
uint256 minScyOut
|
|
65
61
|
) external returns (uint256) {
|
|
66
|
-
return
|
|
62
|
+
return _swapExactPtForScy(receiver, market, exactPtIn, minScyOut, true);
|
|
67
63
|
}
|
|
68
64
|
|
|
69
65
|
/// @dev docs can be found in the internal function
|
|
70
|
-
function
|
|
66
|
+
function swapPtForExactScy(
|
|
71
67
|
address receiver,
|
|
72
68
|
address market,
|
|
73
69
|
uint256 exactScyOut,
|
|
74
|
-
|
|
75
|
-
uint256 otInGuessMax,
|
|
76
|
-
uint256 maxIteration,
|
|
77
|
-
uint256 eps
|
|
70
|
+
ApproxParams memory approx
|
|
78
71
|
) external returns (uint256) {
|
|
79
|
-
return
|
|
80
|
-
_swapOtForExactScy(
|
|
81
|
-
receiver,
|
|
82
|
-
market,
|
|
83
|
-
exactScyOut,
|
|
84
|
-
ApproxParams({
|
|
85
|
-
guessMin: otInGuessMin,
|
|
86
|
-
guessMax: otInGuessMax,
|
|
87
|
-
eps: eps,
|
|
88
|
-
maxIteration: maxIteration
|
|
89
|
-
}),
|
|
90
|
-
true
|
|
91
|
-
);
|
|
72
|
+
return _swapPtForExactScy(receiver, market, exactScyOut, approx, true);
|
|
92
73
|
}
|
|
93
74
|
|
|
94
75
|
/// @dev docs can be found in the internal function
|
|
95
|
-
function
|
|
76
|
+
function swapScyForExactPt(
|
|
96
77
|
address receiver,
|
|
97
78
|
address market,
|
|
98
|
-
uint256
|
|
79
|
+
uint256 exactPtOut,
|
|
99
80
|
uint256 maxScyIn
|
|
100
81
|
) external returns (uint256) {
|
|
101
|
-
return
|
|
82
|
+
return _swapScyForExactPt(receiver, market, exactPtOut, maxScyIn, true);
|
|
102
83
|
}
|
|
103
84
|
|
|
104
85
|
/// @dev docs can be found in the internal function
|
|
105
|
-
function
|
|
86
|
+
function swapExactScyForPt(
|
|
106
87
|
address receiver,
|
|
107
88
|
address market,
|
|
108
89
|
uint256 exactScyIn,
|
|
109
|
-
|
|
110
|
-
uint256 otOutguessMax,
|
|
111
|
-
uint256 maxIteration,
|
|
112
|
-
uint256 eps
|
|
90
|
+
ApproxParams memory approx
|
|
113
91
|
) external returns (uint256) {
|
|
114
|
-
return
|
|
115
|
-
_swapExactScyForOt(
|
|
116
|
-
receiver,
|
|
117
|
-
market,
|
|
118
|
-
exactScyIn,
|
|
119
|
-
ApproxParams({
|
|
120
|
-
guessMin: otOutguessMin,
|
|
121
|
-
guessMax: otOutguessMax,
|
|
122
|
-
eps: eps,
|
|
123
|
-
maxIteration: maxIteration
|
|
124
|
-
}),
|
|
125
|
-
true
|
|
126
|
-
);
|
|
92
|
+
return _swapExactScyForPt(receiver, market, exactScyIn, approx, true);
|
|
127
93
|
}
|
|
128
94
|
|
|
129
95
|
/// @dev docs can be found in the internal function
|
|
@@ -149,47 +115,45 @@ contract ActionCore is IPActionCore, ActionSCYAndOTBase, ActionSCYAndYOBase {
|
|
|
149
115
|
}
|
|
150
116
|
|
|
151
117
|
/// @dev docs can be found in the internal function
|
|
152
|
-
function
|
|
118
|
+
function mintPyFromRawToken(
|
|
153
119
|
uint256 netRawTokenIn,
|
|
154
120
|
address YT,
|
|
155
|
-
uint256
|
|
121
|
+
uint256 minPyOut,
|
|
156
122
|
address receiver,
|
|
157
123
|
address[] calldata path
|
|
158
124
|
) external returns (uint256) {
|
|
159
|
-
return
|
|
125
|
+
return _mintPyFromRawToken(netRawTokenIn, YT, minPyOut, receiver, path, true);
|
|
160
126
|
}
|
|
161
127
|
|
|
162
128
|
/// @dev docs can be found in the internal function
|
|
163
|
-
function
|
|
129
|
+
function redeemPyToRawToken(
|
|
164
130
|
address YT,
|
|
165
|
-
uint256
|
|
131
|
+
uint256 netPyIn,
|
|
166
132
|
uint256 minRawTokenOut,
|
|
167
133
|
address receiver,
|
|
168
134
|
address[] memory path
|
|
169
135
|
) external returns (uint256) {
|
|
170
|
-
return
|
|
136
|
+
return _redeemPyToRawToken(YT, netPyIn, minRawTokenOut, receiver, path, true);
|
|
171
137
|
}
|
|
172
138
|
|
|
173
139
|
/**
|
|
174
|
-
* @dev
|
|
175
|
-
the correct
|
|
140
|
+
* @dev netPtOutGuessMin & netPtOutGuessMax the minimum & maximum possible guess for the netPtOut
|
|
141
|
+
the correct ptOut must lie between this range, else the function will revert.
|
|
176
142
|
* @dev the smaller the range, the fewer iterations it will take (hence less gas). The expected way
|
|
177
143
|
to create the guess is to run this function with min = 0, max = type(uint256.max) to trigger the widest
|
|
178
|
-
guess range. After getting the result, min = result * (
|
|
144
|
+
guess range. After getting the result, min = result * (1-eps) & max = result * (1+eps)
|
|
179
145
|
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
146
|
+
* @param approx params to approx. Guess params will be the min, max & offchain guess for netPtOut
|
|
180
147
|
*/
|
|
181
|
-
function
|
|
148
|
+
function swapExactRawTokenForPt(
|
|
182
149
|
uint256 exactRawTokenIn,
|
|
183
150
|
address receiver,
|
|
184
151
|
address[] calldata path,
|
|
185
152
|
address market,
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
uint256 maxIteration,
|
|
189
|
-
uint256 eps
|
|
190
|
-
) external returns (uint256 netOtOut) {
|
|
153
|
+
ApproxParams memory approx
|
|
154
|
+
) external returns (uint256 netPtOut) {
|
|
191
155
|
address SCY = IPMarket(market).SCY();
|
|
192
|
-
uint256
|
|
156
|
+
uint256 netScyUseToBuyPt = _mintScyFromRawToken(
|
|
193
157
|
exactRawTokenIn,
|
|
194
158
|
SCY,
|
|
195
159
|
1,
|
|
@@ -197,33 +161,22 @@ contract ActionCore is IPActionCore, ActionSCYAndOTBase, ActionSCYAndYOBase {
|
|
|
197
161
|
path,
|
|
198
162
|
true
|
|
199
163
|
);
|
|
200
|
-
|
|
201
|
-
receiver,
|
|
202
|
-
market,
|
|
203
|
-
netScyUseToBuyOt,
|
|
204
|
-
ApproxParams({
|
|
205
|
-
guessMin: otOutguessMin,
|
|
206
|
-
guessMax: otOutguessMax,
|
|
207
|
-
eps: eps,
|
|
208
|
-
maxIteration: maxIteration
|
|
209
|
-
}),
|
|
210
|
-
false
|
|
211
|
-
);
|
|
164
|
+
netPtOut = _swapExactScyForPt(receiver, market, netScyUseToBuyPt, approx, false);
|
|
212
165
|
}
|
|
213
166
|
|
|
214
167
|
/**
|
|
215
|
-
* @notice sell all
|
|
168
|
+
* @notice sell all Pt for RawToken
|
|
216
169
|
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
217
170
|
*/
|
|
218
|
-
function
|
|
219
|
-
uint256
|
|
171
|
+
function swapExactPtForRawToken(
|
|
172
|
+
uint256 exactPtIn,
|
|
220
173
|
address receiver,
|
|
221
174
|
address[] calldata path,
|
|
222
175
|
address market,
|
|
223
176
|
uint256 minRawTokenOut
|
|
224
177
|
) external returns (uint256 netRawTokenOut) {
|
|
225
178
|
address SCY = IPMarket(market).SCY();
|
|
226
|
-
|
|
179
|
+
_swapExactPtForScy(SCY, market, exactPtIn, 1, true);
|
|
227
180
|
netRawTokenOut = _redeemScyToRawToken(SCY, 0, minRawTokenOut, receiver, path, false);
|
|
228
181
|
}
|
|
229
182
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
import "../../interfaces/IPActionRedeem.sol";
|
|
5
|
+
import "../../SuperComposableYield/ISuperComposableYield.sol";
|
|
6
|
+
import "../../interfaces/IPYieldToken.sol";
|
|
7
|
+
import "../../core/PendleMarket.sol";
|
|
8
|
+
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
9
|
+
|
|
10
|
+
contract ActionRedeem is IPActionRedeem {
|
|
11
|
+
function redeemDueIncome(
|
|
12
|
+
address user,
|
|
13
|
+
address[] calldata scys,
|
|
14
|
+
address[] calldata yieldTokens,
|
|
15
|
+
address[] calldata /*gauges*/
|
|
16
|
+
)
|
|
17
|
+
external
|
|
18
|
+
returns (
|
|
19
|
+
uint256[][] memory scyRewards,
|
|
20
|
+
uint256[] memory ytInterests,
|
|
21
|
+
uint256[][] memory ytRewards
|
|
22
|
+
)
|
|
23
|
+
{
|
|
24
|
+
scyRewards = new uint256[][](scys.length);
|
|
25
|
+
for (uint256 i = 0; i < scys.length; ++i) {
|
|
26
|
+
scyRewards[i] = ISuperComposableYield(scys[i]).redeemReward(user);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
ytInterests = new uint256[](yieldTokens.length);
|
|
30
|
+
ytRewards = new uint256[][](yieldTokens.length);
|
|
31
|
+
for (uint256 i = 0; i < yieldTokens.length; ++i) {
|
|
32
|
+
(ytInterests[i], ytRewards[i]) = IPYieldToken(yieldTokens[i])
|
|
33
|
+
.redeemDueInterestAndRewards(user);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
3
|
|
|
4
4
|
import "./base/ActionSCYAndYTBase.sol";
|
|
5
|
-
import "../../interfaces/
|
|
5
|
+
import "../../interfaces/IPPrincipalToken.sol";
|
|
6
6
|
import "../../interfaces/IPYieldToken.sol";
|
|
7
7
|
import "../../interfaces/IPActionYT.sol";
|
|
8
8
|
import "../../libraries/math/MarketMathAux.sol";
|
|
@@ -15,13 +15,20 @@ contract ActionYT is IPActionYT, ActionSCYAndYTBase {
|
|
|
15
15
|
|
|
16
16
|
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
17
17
|
constructor(address _joeRouter, address _joeFactory)
|
|
18
|
-
|
|
19
|
-
ActionSCYAndYTBase()
|
|
18
|
+
ActionSCYAndPYBase(_joeRouter, _joeFactory)
|
|
20
19
|
//solhint-disable-next-line no-empty-blocks
|
|
21
20
|
{
|
|
22
21
|
|
|
23
22
|
}
|
|
24
23
|
|
|
24
|
+
/**
|
|
25
|
+
* @dev Take in a fixed amount of YT and returns receiver a corresponding amount of SCY
|
|
26
|
+
* @dev inner working step
|
|
27
|
+
- Transfer exactYtIn amount of YT to YT
|
|
28
|
+
- market.swapScyToExactPt is called, the receiver of PT is YT
|
|
29
|
+
- YT.redeemPY is called, burning exactYtIn YT & PT to SCY
|
|
30
|
+
- Return the owed Scy for contract, the rest is transferred to user
|
|
31
|
+
*/
|
|
25
32
|
function swapExactYtForScy(
|
|
26
33
|
address receiver,
|
|
27
34
|
address market,
|
|
@@ -31,6 +38,14 @@ contract ActionYT is IPActionYT, ActionSCYAndYTBase {
|
|
|
31
38
|
return _swapExactYtForScy(receiver, market, exactYtIn, minScyOut, true);
|
|
32
39
|
}
|
|
33
40
|
|
|
41
|
+
/**
|
|
42
|
+
* @dev Take in a corresponding amount of SCY & return receiver a fixed amount of YT
|
|
43
|
+
* @dev inner working step
|
|
44
|
+
- Input SCY is transferred to YT address
|
|
45
|
+
- swap.swapExactPtForScy is called the receiver is YT
|
|
46
|
+
- YT.mintPY is called, granting router exactYtOut YT & PT
|
|
47
|
+
- The owed PT is paid by setting the PT receiver is market, YT receiver is $receiver
|
|
48
|
+
*/
|
|
34
49
|
function swapScyForExactYt(
|
|
35
50
|
address receiver,
|
|
36
51
|
address market,
|
|
@@ -40,71 +55,49 @@ contract ActionYT is IPActionYT, ActionSCYAndYTBase {
|
|
|
40
55
|
return _swapScyForExactYt(receiver, market, exactYtOut, maxScyIn);
|
|
41
56
|
}
|
|
42
57
|
|
|
58
|
+
/**
|
|
59
|
+
* @dev Take in a fixed a mount of SCY and return receiver the corresponding amount of YT
|
|
60
|
+
* @dev can refer to the doc of swapExactRawTokenForYt
|
|
61
|
+
* @param approx params to approx. Guess params will be the min, max & offchain guess for netYtOut
|
|
62
|
+
*/
|
|
43
63
|
function swapExactScyForYt(
|
|
44
64
|
address receiver,
|
|
45
65
|
address market,
|
|
46
66
|
uint256 exactScyIn,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
uint256 eps
|
|
51
|
-
) external returns (uint256) {
|
|
52
|
-
return
|
|
53
|
-
_swapExactScyForYt(
|
|
54
|
-
receiver,
|
|
55
|
-
market,
|
|
56
|
-
exactScyIn,
|
|
57
|
-
ApproxParams({
|
|
58
|
-
guessMin: netYtOutGuessMin,
|
|
59
|
-
guessMax: netYtOutGuessMax,
|
|
60
|
-
eps: eps,
|
|
61
|
-
maxIteration: maxIteration
|
|
62
|
-
}),
|
|
63
|
-
true
|
|
64
|
-
);
|
|
67
|
+
ApproxParams memory approx
|
|
68
|
+
) external returns (uint256 netYtOut) {
|
|
69
|
+
return _swapExactScyForYt(receiver, market, exactScyIn, approx, true);
|
|
65
70
|
}
|
|
66
71
|
|
|
72
|
+
/**
|
|
73
|
+
* @dev take in a correesponding amount of YT & return an exactScyOut amount of SCY
|
|
74
|
+
* @dev can refer to the doc of swapExactYtForRawToken
|
|
75
|
+
* @param approx params to approx. Guess params will be the min, max & offchain guess for netYtIn
|
|
76
|
+
*/
|
|
67
77
|
function swapYtForExactScy(
|
|
68
78
|
address receiver,
|
|
69
79
|
address market,
|
|
70
80
|
uint256 exactScyOut,
|
|
71
|
-
|
|
72
|
-
uint256 netYtInGuessMax,
|
|
73
|
-
uint256 maxIteration,
|
|
74
|
-
uint256 eps
|
|
81
|
+
ApproxParams memory approx
|
|
75
82
|
) external returns (uint256 netYtIn) {
|
|
76
|
-
return
|
|
77
|
-
_swapYtForExactScy(
|
|
78
|
-
receiver,
|
|
79
|
-
market,
|
|
80
|
-
exactScyOut,
|
|
81
|
-
ApproxParams({
|
|
82
|
-
guessMin: netYtInGuessMin,
|
|
83
|
-
guessMax: netYtInGuessMax,
|
|
84
|
-
eps: eps,
|
|
85
|
-
maxIteration: maxIteration
|
|
86
|
-
}),
|
|
87
|
-
true
|
|
88
|
-
);
|
|
83
|
+
return _swapYtForExactScy(receiver, market, exactScyOut, approx, true);
|
|
89
84
|
}
|
|
90
85
|
|
|
91
86
|
/**
|
|
92
|
-
* @dev netYtOutGuessMin & Max can be used in the same way as
|
|
87
|
+
* @dev netYtOutGuessMin & Max can be used in the same way as RawTokenPT
|
|
93
88
|
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
94
89
|
* @dev inner working of this function:
|
|
95
90
|
- mintScyFromRawToken is invoked, except the YT contract will receive all the outcome SCY
|
|
96
|
-
- market.
|
|
97
|
-
- callback will do call YT
|
|
91
|
+
- market.swapExactPtToScy is called, which will transfer SCY to the YT contract, and callback is invoked
|
|
92
|
+
- callback will do call YT.mintPT, which will mint PT to the market & YT to the receiver
|
|
93
|
+
* @param approx params to approx. Guess params will be the min, max & offchain guess for netYtOut
|
|
98
94
|
*/
|
|
99
95
|
function swapExactRawTokenForYt(
|
|
100
96
|
uint256 exactRawTokenIn,
|
|
101
97
|
address receiver,
|
|
102
98
|
address[] calldata path,
|
|
103
99
|
address market,
|
|
104
|
-
|
|
105
|
-
uint256 netYtOutGuessMax,
|
|
106
|
-
uint256 maxIteration,
|
|
107
|
-
uint256 eps
|
|
100
|
+
ApproxParams memory approx
|
|
108
101
|
) external returns (uint256 netYtOut) {
|
|
109
102
|
(ISuperComposableYield SCY, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
110
103
|
|
|
@@ -117,18 +110,7 @@ contract ActionYT is IPActionYT, ActionSCYAndYTBase {
|
|
|
117
110
|
true
|
|
118
111
|
);
|
|
119
112
|
|
|
120
|
-
netYtOut = _swapExactScyForYt(
|
|
121
|
-
receiver,
|
|
122
|
-
market,
|
|
123
|
-
netScyUsedToBuyYT,
|
|
124
|
-
ApproxParams({
|
|
125
|
-
guessMin: netYtOutGuessMin,
|
|
126
|
-
guessMax: netYtOutGuessMax,
|
|
127
|
-
eps: eps,
|
|
128
|
-
maxIteration: maxIteration
|
|
129
|
-
}),
|
|
130
|
-
false
|
|
131
|
-
);
|
|
113
|
+
netYtOut = _swapExactScyForYt(receiver, market, netScyUsedToBuyYT, approx, false);
|
|
132
114
|
}
|
|
133
115
|
|
|
134
116
|
/**
|
|
@@ -137,8 +119,8 @@ contract ActionYT is IPActionYT, ActionSCYAndYTBase {
|
|
|
137
119
|
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
138
120
|
* @dev inner working of this function:
|
|
139
121
|
- YT is transferred to the YT contract
|
|
140
|
-
- market.
|
|
141
|
-
- callback will do call YT
|
|
122
|
+
- market.swapScyForExactPt is called, which will transfer PT directly to the YT contract, and callback is invoked
|
|
123
|
+
- callback will do call YT.redeemPY, which will redeem the outcome SCY to this router, then
|
|
142
124
|
all SCY owed to the market will be paid, the rest is used to feed redeemScyToRawToken
|
|
143
125
|
*/
|
|
144
126
|
function swapExactYtForRawToken(
|