@pendle/core-v2 0.5.1-beta-4 → 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
- package/typechain-types/ActionCallback.ts +5 -5
- package/typechain-types/ActionCore.ts +312 -234
- package/typechain-types/ActionRedeem.ts +125 -0
- package/typechain-types/ActionSCYAndPYBase.ts +223 -0
- package/typechain-types/ActionSCYAndYOBase.ts +129 -3
- package/typechain-types/ActionSCYAndYTBase.ts +149 -3
- package/typechain-types/ActionYT.ts +192 -94
- package/typechain-types/IPActionCore.ts +183 -231
- package/typechain-types/IPActionRedeem.ts +125 -0
- package/typechain-types/IPActionYT.ts +43 -91
- package/typechain-types/IPAllAction.ts +258 -321
- package/typechain-types/IPMarket.ts +150 -50
- package/typechain-types/IPMarketAddRemoveCallback.ts +10 -10
- package/typechain-types/IPMarketFactory.ts +28 -6
- package/typechain-types/IPMarketSwapCallback.ts +5 -5
- package/typechain-types/{IPOwnershipToken.ts → IPPrincipalToken.ts} +5 -5
- package/typechain-types/IPRouterStatic.ts +50 -530
- package/typechain-types/IPYieldContractFactory.ts +85 -19
- package/typechain-types/IPYieldToken.ts +138 -37
- package/typechain-types/ISuperComposableYield.ts +13 -0
- package/typechain-types/IWstETH.ts +149 -0
- package/typechain-types/PendleAaveV3SCY.ts +110 -0
- package/typechain-types/PendleBaseToken.ts +1 -1
- package/typechain-types/PendleBenQiErc20SCY.ts +55 -12
- package/typechain-types/PendleBtrflyScy.ts +27 -23
- package/typechain-types/PendleGovernanceManager.ts +5 -5
- package/typechain-types/PendleMarket.ts +197 -100
- package/typechain-types/PendleMarketFactory.ts +96 -34
- package/typechain-types/{PendleOwnershipToken.ts → PendlePrincipalToken.ts} +15 -6
- package/typechain-types/PendleRouter.ts +19 -0
- package/typechain-types/PendleRouterRedeemUpg.ts +125 -0
- package/typechain-types/PendleStEthSCY.ts +872 -0
- package/typechain-types/PendleYearnVaultScy.ts +27 -23
- package/typechain-types/PendleYieldContractFactory.ts +94 -28
- package/typechain-types/PendleYieldToken.ts +142 -57
- package/typechain-types/RewardManager.ts +21 -0
- package/typechain-types/RouterStatic.ts +50 -530
- package/typechain-types/SCYBase.ts +25 -0
- package/typechain-types/SCYBaseWithRewards.ts +64 -0
- package/typechain-types/factories/ActionCallback__factory.ts +2 -2
- package/typechain-types/factories/ActionCore__factory.ts +263 -79
- package/typechain-types/factories/ActionRedeem__factory.ts +105 -0
- package/typechain-types/factories/ActionSCYAndPYBase__factory.ts +200 -0
- package/typechain-types/factories/ActionSCYAndYOBase__factory.ts +148 -0
- package/typechain-types/factories/ActionSCYAndYTBase__factory.ts +173 -0
- package/typechain-types/factories/ActionYT__factory.ts +265 -56
- package/typechain-types/factories/IPActionCore__factory.ts +114 -78
- package/typechain-types/factories/IPActionRedeem__factory.ts +70 -0
- package/typechain-types/factories/IPActionYT__factory.ts +90 -54
- package/typechain-types/factories/IPAllAction__factory.ts +254 -138
- package/typechain-types/factories/IPMarketAddRemoveCallback__factory.ts +2 -2
- package/typechain-types/factories/IPMarketFactory__factory.ts +26 -1
- package/typechain-types/factories/IPMarketSwapCallback__factory.ts +1 -1
- package/typechain-types/factories/IPMarket__factory.ts +125 -13
- package/typechain-types/factories/{IPOwnershipToken__factory.ts → IPPrincipalToken__factory.ts} +8 -8
- package/typechain-types/factories/IPRouterStatic__factory.ts +12 -628
- package/typechain-types/factories/IPYieldContractFactory__factory.ts +72 -2
- package/typechain-types/factories/IPYieldToken__factory.ts +93 -7
- package/typechain-types/factories/ISuperComposableYield__factory.ts +13 -0
- package/typechain-types/factories/IWstETH__factory.ts +74 -0
- package/typechain-types/factories/PendleAaveV3SCY__factory.ts +97 -3
- package/typechain-types/factories/PendleBaseToken__factory.ts +1 -1
- package/typechain-types/factories/PendleBenQiErc20SCY__factory.ts +62 -7
- package/typechain-types/factories/PendleBtrflyScy__factory.ts +42 -19
- package/typechain-types/factories/PendleGovernanceManager__factory.ts +2 -2
- package/typechain-types/factories/PendleMarketFactory__factory.ts +66 -15
- package/typechain-types/factories/PendleMarket__factory.ts +170 -53
- package/typechain-types/factories/PendlePrincipalToken__factory.ts +540 -0
- package/typechain-types/factories/PendleRouterRedeemUpg__factory.ts +112 -0
- package/typechain-types/factories/PendleRouter__factory.ts +23 -1
- package/typechain-types/factories/PendleStEthSCY__factory.ts +716 -0
- package/typechain-types/factories/PendleYearnVaultScy__factory.ts +41 -18
- package/typechain-types/factories/PendleYieldContractFactory__factory.ts +75 -5
- package/typechain-types/factories/PendleYieldToken__factory.ts +102 -33
- package/typechain-types/factories/RewardManager__factory.ts +13 -0
- package/typechain-types/factories/RouterStatic__factory.ts +13 -629
- package/typechain-types/factories/SCYBaseWithRewards__factory.ts +60 -2
- package/typechain-types/factories/SCYBase__factory.ts +28 -2
- package/typechain-types/hardhat.d.ts +52 -16
- package/typechain-types/index.ts +14 -6
- package/typechain-types/factories/PendleOwnershipToken__factory.ts +0 -527
|
@@ -9,7 +9,7 @@ import "../../../libraries/math/MarketApproxLib.sol";
|
|
|
9
9
|
import "../../../libraries/math/MarketMathAux.sol";
|
|
10
10
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
11
11
|
|
|
12
|
-
abstract contract
|
|
12
|
+
abstract contract ActionSCYAndPTBase {
|
|
13
13
|
using Math for uint256;
|
|
14
14
|
using Math for int256;
|
|
15
15
|
using MarketMathCore for MarketState;
|
|
@@ -20,18 +20,18 @@ abstract contract ActionSCYAndOTBase {
|
|
|
20
20
|
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* @notice addLiquidity to the market, using both SCY &
|
|
24
|
-
msg.sender is required to pay SCY &
|
|
23
|
+
* @notice addLiquidity to the market, using both SCY & PT, the receiver will receive LP before
|
|
24
|
+
msg.sender is required to pay SCY & PT
|
|
25
25
|
* @dev inner working of this function:
|
|
26
26
|
- market.addLiquidity is called
|
|
27
27
|
- LP is minted to the receiver, and this router's addLiquidityCallback is invoked
|
|
28
|
-
- the router will transfer the necessary scy &
|
|
28
|
+
- the router will transfer the necessary scy & pt from msg.sender to the market, and finish the callback
|
|
29
29
|
*/
|
|
30
30
|
function _addLiquidity(
|
|
31
31
|
address receiver,
|
|
32
32
|
address market,
|
|
33
33
|
uint256 scyDesired,
|
|
34
|
-
uint256
|
|
34
|
+
uint256 ptDesired,
|
|
35
35
|
uint256 minLpOut,
|
|
36
36
|
bool doPull
|
|
37
37
|
)
|
|
@@ -39,16 +39,16 @@ abstract contract ActionSCYAndOTBase {
|
|
|
39
39
|
returns (
|
|
40
40
|
uint256 netLpOut,
|
|
41
41
|
uint256 scyUsed,
|
|
42
|
-
uint256
|
|
42
|
+
uint256 ptUsed
|
|
43
43
|
)
|
|
44
44
|
{
|
|
45
|
-
(ISuperComposableYield SCY,
|
|
45
|
+
(ISuperComposableYield SCY, IPPrincipalToken PT, ) = IPMarket(market).readTokens();
|
|
46
46
|
|
|
47
47
|
MarketState memory state = IPMarket(market).readState(false);
|
|
48
|
-
(, netLpOut, scyUsed,
|
|
48
|
+
(, netLpOut, scyUsed, ptUsed) = state.addLiquidity(
|
|
49
49
|
SCYIndexLib.newIndex(SCY),
|
|
50
50
|
scyDesired,
|
|
51
|
-
|
|
51
|
+
ptDesired,
|
|
52
52
|
false
|
|
53
53
|
);
|
|
54
54
|
|
|
@@ -56,18 +56,18 @@ abstract contract ActionSCYAndOTBase {
|
|
|
56
56
|
|
|
57
57
|
if (doPull) {
|
|
58
58
|
IERC20(SCY).safeTransferFrom(msg.sender, market, scyUsed);
|
|
59
|
-
IERC20(
|
|
59
|
+
IERC20(PT).safeTransferFrom(msg.sender, market, ptUsed);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
IPMarket(market).addLiquidity(receiver,
|
|
62
|
+
IPMarket(market).addLiquidity(receiver, ptDesired, scyDesired, abi.encode()); // ignore return
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
|
-
* @notice removeLiquidity from the market to receive both SCY &
|
|
67
|
-
SCY &
|
|
66
|
+
* @notice removeLiquidity from the market to receive both SCY & PT. The receiver will receive
|
|
67
|
+
SCY & PT before msg.sender is required to transfer in the necessary LP
|
|
68
68
|
* @dev inner working of this function:
|
|
69
69
|
- market.removeLiquidity is called
|
|
70
|
-
- SCY &
|
|
70
|
+
- SCY & PT is transferred to the receiver, and the router's callback is invoked
|
|
71
71
|
- the router will transfer the necessary LP from msg.sender to the market, and finish the callback
|
|
72
72
|
*/
|
|
73
73
|
function _removeLiquidity(
|
|
@@ -75,45 +75,45 @@ abstract contract ActionSCYAndOTBase {
|
|
|
75
75
|
address market,
|
|
76
76
|
uint256 lpToRemove,
|
|
77
77
|
uint256 scyOutMin,
|
|
78
|
-
uint256
|
|
78
|
+
uint256 ptOutMin,
|
|
79
79
|
bool doPull
|
|
80
|
-
) internal returns (uint256 netScyOut, uint256
|
|
80
|
+
) internal returns (uint256 netScyOut, uint256 netPtOut) {
|
|
81
81
|
MarketState memory state = IPMarket(market).readState(false);
|
|
82
82
|
|
|
83
|
-
(netScyOut,
|
|
83
|
+
(netScyOut, netPtOut) = state.removeLiquidity(lpToRemove, false);
|
|
84
84
|
require(netScyOut >= scyOutMin, "insufficient scy out");
|
|
85
|
-
require(
|
|
85
|
+
require(netPtOut >= ptOutMin, "insufficient pt out");
|
|
86
86
|
|
|
87
87
|
if (doPull) {
|
|
88
88
|
IERC20(market).safeTransferFrom(msg.sender, market, lpToRemove);
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
IPMarket(market).removeLiquidity(receiver, lpToRemove, abi.encode());
|
|
91
|
+
IPMarket(market).removeLiquidity(receiver, lpToRemove, abi.encode()); // ignore return
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
|
-
* @notice swap exact
|
|
96
|
-
transfer the owed
|
|
95
|
+
* @notice swap exact PT for SCY, with receiver receiving SCY before msg.sender is required to
|
|
96
|
+
transfer the owed PT
|
|
97
97
|
* @dev inner working of this function:
|
|
98
98
|
- market.swap is called
|
|
99
99
|
- SCY is transferred to the receiver, and the router's callback is invoked
|
|
100
|
-
- the router will transfer the necessary
|
|
100
|
+
- the router will transfer the necessary PT from msg.sender to the market, and finish the callback
|
|
101
101
|
*/
|
|
102
|
-
function
|
|
102
|
+
function _swapExactPtForScy(
|
|
103
103
|
address receiver,
|
|
104
104
|
address market,
|
|
105
|
-
uint256
|
|
105
|
+
uint256 exactPtIn,
|
|
106
106
|
uint256 minScyOut,
|
|
107
107
|
bool doPull
|
|
108
108
|
) internal returns (uint256 netScyOut) {
|
|
109
109
|
if (doPull) {
|
|
110
|
-
address
|
|
111
|
-
IERC20(
|
|
110
|
+
address PT = IPMarket(market).PT();
|
|
111
|
+
IERC20(PT).safeTransferFrom(msg.sender, market, exactPtIn);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
(netScyOut, ) = IPMarket(market).
|
|
114
|
+
(netScyOut, ) = IPMarket(market).swapExactPtForScy(
|
|
115
115
|
receiver,
|
|
116
|
-
|
|
116
|
+
exactPtIn,
|
|
117
117
|
minScyOut,
|
|
118
118
|
abi.encode()
|
|
119
119
|
);
|
|
@@ -121,17 +121,23 @@ abstract contract ActionSCYAndOTBase {
|
|
|
121
121
|
require(netScyOut >= minScyOut, "insufficient scy out");
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
-
|
|
124
|
+
/**
|
|
125
|
+
* @notice swap PT for exact SCY, with receiver receiving SCY before msg.sender is required to
|
|
126
|
+
transfer the owed PT
|
|
127
|
+
* @dev inner working of this function is similar to swapExactPtForScy
|
|
128
|
+
* @param approx params to approx. Guess params will be the min, max & offchain guess for netPtIn
|
|
129
|
+
*/
|
|
130
|
+
function _swapPtForExactScy(
|
|
125
131
|
address receiver,
|
|
126
132
|
address market,
|
|
127
133
|
uint256 exactScyOut,
|
|
128
134
|
ApproxParams memory approx,
|
|
129
135
|
bool doPull
|
|
130
|
-
) internal returns (uint256
|
|
136
|
+
) internal returns (uint256 netPtIn) {
|
|
131
137
|
MarketState memory state = IPMarket(market).readState(false);
|
|
132
|
-
(ISuperComposableYield SCY,
|
|
138
|
+
(ISuperComposableYield SCY, IPPrincipalToken PT, ) = IPMarket(market).readTokens();
|
|
133
139
|
|
|
134
|
-
(
|
|
140
|
+
(netPtIn, ) = state.approxSwapPtForExactScy(
|
|
135
141
|
SCYIndexLib.newIndex(SCY),
|
|
136
142
|
exactScyOut,
|
|
137
143
|
block.timestamp,
|
|
@@ -139,33 +145,33 @@ abstract contract ActionSCYAndOTBase {
|
|
|
139
145
|
);
|
|
140
146
|
|
|
141
147
|
if (doPull) {
|
|
142
|
-
IERC20(
|
|
148
|
+
IERC20(PT).safeTransferFrom(msg.sender, market, netPtIn);
|
|
143
149
|
}
|
|
144
150
|
|
|
145
|
-
IPMarket(market).
|
|
151
|
+
IPMarket(market).swapExactPtForScy(receiver, netPtIn, exactScyOut, abi.encode()); // ignore return
|
|
146
152
|
}
|
|
147
153
|
|
|
148
154
|
/**
|
|
149
|
-
* @notice swap SCY for exact
|
|
155
|
+
* @notice swap SCY for exact PT, with receiver receiving PT before msg.sender is required to
|
|
150
156
|
transfer the owed SCY
|
|
151
157
|
* @dev inner working of this function:
|
|
152
158
|
- market.swap is called
|
|
153
|
-
-
|
|
159
|
+
- PT is transferred to the receiver, and the router's callback is invoked
|
|
154
160
|
- the router will transfer the necessary SCY from msg.sender to the market, and finish the callback
|
|
155
161
|
*/
|
|
156
|
-
function
|
|
162
|
+
function _swapScyForExactPt(
|
|
157
163
|
address receiver,
|
|
158
164
|
address market,
|
|
159
|
-
uint256
|
|
165
|
+
uint256 exactPtOut,
|
|
160
166
|
uint256 maxScyIn,
|
|
161
167
|
bool doPull
|
|
162
168
|
) internal returns (uint256 netScyIn) {
|
|
163
169
|
MarketState memory state = IPMarket(market).readState(false);
|
|
164
170
|
address SCY = IPMarket(market).SCY();
|
|
165
171
|
|
|
166
|
-
(netScyIn, ) = state.
|
|
172
|
+
(netScyIn, ) = state.swapScyForExactPt(
|
|
167
173
|
SCYIndexLib.newIndex(SCY),
|
|
168
|
-
|
|
174
|
+
exactPtOut,
|
|
169
175
|
block.timestamp,
|
|
170
176
|
false
|
|
171
177
|
);
|
|
@@ -175,20 +181,28 @@ abstract contract ActionSCYAndOTBase {
|
|
|
175
181
|
IERC20(SCY).safeTransferFrom(msg.sender, market, netScyIn);
|
|
176
182
|
}
|
|
177
183
|
|
|
178
|
-
IPMarket(market).
|
|
184
|
+
IPMarket(market).swapScyForExactPt(receiver, exactPtOut, maxScyIn, abi.encode()); // ignore return
|
|
179
185
|
}
|
|
180
186
|
|
|
181
|
-
|
|
187
|
+
/**
|
|
188
|
+
* @dev swap exact amount of Scy to PT
|
|
189
|
+
* @dev inner working steps:
|
|
190
|
+
- The outcome amount of PT in is approximated
|
|
191
|
+
- market.swapExactPtToScy() is called, user will receive their PT
|
|
192
|
+
- The approximated amount of PT is transferred from msg.sender to market via router
|
|
193
|
+
* @param approx params to approx. Guess params will be the min, max & offchain guess for netPtOut
|
|
194
|
+
*/
|
|
195
|
+
function _swapExactScyForPt(
|
|
182
196
|
address receiver,
|
|
183
197
|
address market,
|
|
184
198
|
uint256 exactScyIn,
|
|
185
199
|
ApproxParams memory approx,
|
|
186
200
|
bool doPull
|
|
187
|
-
) internal returns (uint256
|
|
201
|
+
) internal returns (uint256 netPtOut) {
|
|
188
202
|
MarketState memory state = IPMarket(market).readState(false);
|
|
189
203
|
address SCY = IPMarket(market).SCY();
|
|
190
204
|
|
|
191
|
-
(
|
|
205
|
+
(netPtOut, ) = state.approxSwapExactScyForPt(
|
|
192
206
|
SCYIndexLib.newIndex(SCY),
|
|
193
207
|
exactScyIn,
|
|
194
208
|
block.timestamp,
|
|
@@ -199,6 +213,6 @@ abstract contract ActionSCYAndOTBase {
|
|
|
199
213
|
IERC20(SCY).safeTransferFrom(msg.sender, market, exactScyIn);
|
|
200
214
|
}
|
|
201
215
|
|
|
202
|
-
IPMarket(market).
|
|
216
|
+
IPMarket(market).swapScyForExactPt(receiver, netPtOut, exactScyIn, abi.encode()); // ignore return
|
|
203
217
|
}
|
|
204
218
|
}
|
|
@@ -7,9 +7,41 @@ import "../../../SuperComposableYield/ISuperComposableYield.sol";
|
|
|
7
7
|
import "../../../interfaces/IPYieldToken.sol";
|
|
8
8
|
|
|
9
9
|
// solhint-disable no-empty-blocks
|
|
10
|
-
abstract contract
|
|
10
|
+
abstract contract ActionSCYAndPYBase is PendleJoeSwapHelperUpg {
|
|
11
11
|
using SafeERC20 for IERC20;
|
|
12
12
|
|
|
13
|
+
event MintScyFromRawToken(
|
|
14
|
+
address indexed user,
|
|
15
|
+
address indexed rawTokenIn,
|
|
16
|
+
uint256 netRawTokenIn,
|
|
17
|
+
address indexed SCY,
|
|
18
|
+
uint256 netScyOut
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
event RedeemScyToRawToken(
|
|
22
|
+
address indexed user,
|
|
23
|
+
address indexed SCY,
|
|
24
|
+
uint256 netScyIn,
|
|
25
|
+
address indexed rawTokenOut,
|
|
26
|
+
uint256 netRawTokenOut
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
event MintPyFromRawToken(
|
|
30
|
+
address indexed user,
|
|
31
|
+
address indexed rawTokenIn,
|
|
32
|
+
uint256 netRawTokenIn,
|
|
33
|
+
address indexed YT,
|
|
34
|
+
uint256 netPyOut
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
event RedeemPyToRawToken(
|
|
38
|
+
address indexed user,
|
|
39
|
+
address indexed YT,
|
|
40
|
+
uint256 netPyIn,
|
|
41
|
+
address indexed rawTokenOut,
|
|
42
|
+
uint256 netRawTokenOut
|
|
43
|
+
);
|
|
44
|
+
|
|
13
45
|
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
14
46
|
constructor(address _joeRouter, address _joeFactory)
|
|
15
47
|
PendleJoeSwapHelperUpg(_joeRouter, _joeFactory)
|
|
@@ -43,6 +75,7 @@ abstract contract ActionSCYAndYOBase is PendleJoeSwapHelperUpg {
|
|
|
43
75
|
|
|
44
76
|
address baseToken = path[path.length - 1];
|
|
45
77
|
netScyOut = ISuperComposableYield(SCY).mintNoPull(receiver, baseToken, minScyOut);
|
|
78
|
+
emit MintScyFromRawToken(msg.sender, path[0], netRawTokenIn, SCY, netScyOut);
|
|
46
79
|
}
|
|
47
80
|
|
|
48
81
|
/**
|
|
@@ -84,56 +117,61 @@ abstract contract ActionSCYAndYOBase is PendleJoeSwapHelperUpg {
|
|
|
84
117
|
netRawTokenOut = _swapExactIn(path, netBaseTokenOut, receiver);
|
|
85
118
|
require(netRawTokenOut >= minRawTokenOut, "insufficient out");
|
|
86
119
|
}
|
|
120
|
+
|
|
121
|
+
emit RedeemScyToRawToken(msg.sender, SCY, netScyIn, path[path.length - 1], netRawTokenOut);
|
|
87
122
|
}
|
|
88
123
|
|
|
89
124
|
/**
|
|
90
|
-
* @notice swap rawToken to baseToken -> convert to SCY -> convert to
|
|
125
|
+
* @notice swap rawToken to baseToken -> convert to SCY -> convert to PT + YT
|
|
91
126
|
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
92
127
|
* @dev inner working of this function:
|
|
93
|
-
- same as mintScyFromRawToken, except the receiver of SCY will be the YT contract, then
|
|
94
|
-
will be called, minting
|
|
128
|
+
- same as mintScyFromRawToken, except the receiver of SCY will be the YT contract, then mintPY
|
|
129
|
+
will be called, minting PT + YT directly to receiver
|
|
95
130
|
*/
|
|
96
|
-
function
|
|
131
|
+
function _mintPyFromRawToken(
|
|
97
132
|
uint256 netRawTokenIn,
|
|
98
133
|
address YT,
|
|
99
|
-
uint256
|
|
134
|
+
uint256 minPyOut,
|
|
100
135
|
address receiver,
|
|
101
136
|
address[] calldata path,
|
|
102
137
|
bool doPull
|
|
103
|
-
) internal returns (uint256
|
|
138
|
+
) internal returns (uint256 netPyOut) {
|
|
104
139
|
address SCY = IPYieldToken(YT).SCY();
|
|
105
140
|
_mintScyFromRawToken(netRawTokenIn, SCY, 1, YT, path, doPull);
|
|
106
|
-
|
|
107
|
-
require(
|
|
141
|
+
netPyOut = IPYieldToken(YT).mintPY(receiver, receiver);
|
|
142
|
+
require(netPyOut >= minPyOut, "insufficient PY out");
|
|
143
|
+
emit MintPyFromRawToken(msg.sender, path[0], netRawTokenIn, YT, netPyOut);
|
|
108
144
|
}
|
|
109
145
|
|
|
110
146
|
/**
|
|
111
|
-
* @notice redeem
|
|
147
|
+
* @notice redeem PT + YT to SCY -> redeem SCY to baseToken -> swap baseToken to rawToken
|
|
112
148
|
* @param path the path to swap from rawToken to baseToken. path = [baseToken] if no swap is needed
|
|
113
149
|
* @dev inner working of this function:
|
|
114
|
-
-
|
|
115
|
-
-
|
|
150
|
+
- PT (+ YT if not expired) is transferred to the YT contract
|
|
151
|
+
- redeemPY is called, redeem all outcome SCY to the SCY contract
|
|
116
152
|
- The rest is the same as redeemScyToRawToken (except the first SCY transfer is skipped)
|
|
117
153
|
*/
|
|
118
|
-
function
|
|
154
|
+
function _redeemPyToRawToken(
|
|
119
155
|
address YT,
|
|
120
|
-
uint256
|
|
156
|
+
uint256 netPyIn,
|
|
121
157
|
uint256 minRawTokenOut,
|
|
122
158
|
address receiver,
|
|
123
159
|
address[] memory path,
|
|
124
160
|
bool doPull
|
|
125
161
|
) internal returns (uint256 netRawTokenOut) {
|
|
126
|
-
address
|
|
162
|
+
address PT = IPYieldToken(YT).PT();
|
|
127
163
|
address SCY = IPYieldToken(YT).SCY();
|
|
128
164
|
|
|
129
165
|
if (doPull) {
|
|
130
|
-
bool isNeedToBurnYt = (IPBaseToken(YT).isExpired()
|
|
131
|
-
IERC20(
|
|
132
|
-
if (isNeedToBurnYt) IERC20(YT).safeTransferFrom(msg.sender, YT,
|
|
166
|
+
bool isNeedToBurnYt = (!IPBaseToken(YT).isExpired());
|
|
167
|
+
IERC20(PT).safeTransferFrom(msg.sender, YT, netPyIn);
|
|
168
|
+
if (isNeedToBurnYt) IERC20(YT).safeTransferFrom(msg.sender, YT, netPyIn);
|
|
133
169
|
}
|
|
134
170
|
|
|
135
|
-
IPYieldToken(YT).
|
|
171
|
+
IPYieldToken(YT).redeemPY(SCY); // ignore return
|
|
136
172
|
|
|
137
173
|
netRawTokenOut = _redeemScyToRawToken(SCY, 0, minRawTokenOut, receiver, path, false);
|
|
174
|
+
|
|
175
|
+
emit RedeemPyToRawToken(msg.sender, YT, netPyIn, path[path.length - 1], netRawTokenOut);
|
|
138
176
|
}
|
|
139
177
|
}
|
|
@@ -6,11 +6,11 @@ import "../../../interfaces/IPMarket.sol";
|
|
|
6
6
|
import "../../../SuperComposableYield/SCYUtils.sol";
|
|
7
7
|
import "../../../libraries/math/MarketApproxLib.sol";
|
|
8
8
|
import "../../../libraries/math/MarketMathAux.sol";
|
|
9
|
-
import "./
|
|
9
|
+
import "./ActionSCYAndPYBase.sol";
|
|
10
10
|
import "./ActionType.sol";
|
|
11
11
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
12
12
|
|
|
13
|
-
abstract contract ActionSCYAndYTBase is
|
|
13
|
+
abstract contract ActionSCYAndYTBase is ActionSCYAndPYBase, ActionType {
|
|
14
14
|
using Math for uint256;
|
|
15
15
|
using Math for int256;
|
|
16
16
|
using MarketMathCore for MarketState;
|
|
@@ -19,6 +19,8 @@ abstract contract ActionSCYAndYTBase is ActionSCYAndYOBase, ActionType {
|
|
|
19
19
|
using SafeERC20 for ISuperComposableYield;
|
|
20
20
|
using SafeERC20 for IPYieldToken;
|
|
21
21
|
|
|
22
|
+
event SwapYT(address indexed user, int256 ytToAccount, int256 scyToAccount);
|
|
23
|
+
|
|
22
24
|
function _swapExactScyForYt(
|
|
23
25
|
address receiver,
|
|
24
26
|
address market,
|
|
@@ -40,19 +42,21 @@ abstract contract ActionSCYAndYTBase is ActionSCYAndYOBase, ActionType {
|
|
|
40
42
|
SCY.safeTransferFrom(msg.sender, address(YT), exactScyIn);
|
|
41
43
|
}
|
|
42
44
|
|
|
43
|
-
IPMarket(market).
|
|
44
|
-
|
|
45
|
-
netYtOut, //
|
|
45
|
+
IPMarket(market).swapExactPtForScy(
|
|
46
|
+
address(YT),
|
|
47
|
+
netYtOut, // exactPtIn = netYtOut
|
|
46
48
|
1,
|
|
47
49
|
abi.encode(ACTION_TYPE.SwapExactScyForYt, receiver)
|
|
48
|
-
);
|
|
50
|
+
); // ignore-return
|
|
51
|
+
|
|
52
|
+
emit SwapYT(receiver, netYtOut.Int(), exactScyIn.neg());
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
/**
|
|
52
56
|
* @dev inner working of this function:
|
|
53
57
|
- YT is transferred to the YT contract
|
|
54
|
-
- market.swap is called, which will transfer
|
|
55
|
-
- callback will call YT's
|
|
58
|
+
- market.swap is called, which will transfer PT directly to the YT contract, and callback is invoked
|
|
59
|
+
- callback will call YT's redeemPY, which will redeem the outcome SCY to this router, then
|
|
56
60
|
all SCY owed to the market will be paid, the rest is transferred to the receiver
|
|
57
61
|
*/
|
|
58
62
|
function _swapExactYtForScy(
|
|
@@ -70,21 +74,23 @@ abstract contract ActionSCYAndYTBase is ActionSCYAndYOBase, ActionType {
|
|
|
70
74
|
YT.safeTransferFrom(msg.sender, address(YT), exactYtIn);
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
IPMarket(market).
|
|
74
|
-
|
|
75
|
-
exactYtIn, //
|
|
77
|
+
IPMarket(market).swapScyForExactPt(
|
|
78
|
+
address(YT),
|
|
79
|
+
exactYtIn, // exactPtOut = exactYtIn
|
|
76
80
|
type(uint256).max,
|
|
77
81
|
abi.encode(ACTION_TYPE.SwapExactYtForScy, receiver)
|
|
78
|
-
);
|
|
82
|
+
); // ignore return
|
|
79
83
|
|
|
80
84
|
netScyOut = SCY.balanceOf(receiver) - preBalanceScy;
|
|
81
85
|
require(netScyOut >= minScyOut, "INSUFFICIENT_SCY_OUT");
|
|
86
|
+
|
|
87
|
+
emit SwapYT(receiver, exactYtIn.neg(), netScyOut.Int());
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
/**
|
|
85
91
|
* @dev inner working of this function:
|
|
86
92
|
- market.swap is called, which will transfer SCY directly to the YT contract, and callback is invoked
|
|
87
|
-
- callback will pull more SCY if necessary, do call YT's
|
|
93
|
+
- callback will pull more SCY if necessary, do call YT's mintPY, which will mint PT to the market & YT to the receiver
|
|
88
94
|
*/
|
|
89
95
|
function _swapScyForExactYt(
|
|
90
96
|
address receiver,
|
|
@@ -92,20 +98,22 @@ abstract contract ActionSCYAndYTBase is ActionSCYAndYOBase, ActionType {
|
|
|
92
98
|
uint256 exactYtOut,
|
|
93
99
|
uint256 maxScyIn
|
|
94
100
|
) internal returns (uint256 netScyIn) {
|
|
95
|
-
(ISuperComposableYield SCY, , ) = IPMarket(market).readTokens();
|
|
101
|
+
(ISuperComposableYield SCY, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
96
102
|
|
|
97
103
|
uint256 preBalanceScy = SCY.balanceOf(receiver);
|
|
98
104
|
|
|
99
|
-
IPMarket(market).
|
|
100
|
-
|
|
101
|
-
exactYtOut, //
|
|
105
|
+
IPMarket(market).swapExactPtForScy(
|
|
106
|
+
address(YT),
|
|
107
|
+
exactYtOut, // exactPtIn = exactYtOut
|
|
102
108
|
1,
|
|
103
109
|
abi.encode(ACTION_TYPE.SwapSCYForExactYt, msg.sender, receiver)
|
|
104
|
-
);
|
|
110
|
+
); // ignore return
|
|
105
111
|
|
|
106
112
|
netScyIn = preBalanceScy - SCY.balanceOf(receiver);
|
|
107
113
|
|
|
108
114
|
require(netScyIn <= maxScyIn, "exceed out limit");
|
|
115
|
+
|
|
116
|
+
emit SwapYT(receiver, exactYtOut.Int(), netScyIn.neg());
|
|
109
117
|
}
|
|
110
118
|
|
|
111
119
|
function _swapYtForExactScy(
|
|
@@ -129,11 +137,13 @@ abstract contract ActionSCYAndYTBase is ActionSCYAndYOBase, ActionType {
|
|
|
129
137
|
YT.safeTransferFrom(msg.sender, address(YT), netYtIn);
|
|
130
138
|
}
|
|
131
139
|
|
|
132
|
-
IPMarket(market).
|
|
140
|
+
IPMarket(market).swapScyForExactPt(
|
|
133
141
|
address(YT),
|
|
134
|
-
netYtIn, //
|
|
142
|
+
netYtIn, // exactPtOut = netYtIn
|
|
135
143
|
type(uint256).max,
|
|
136
144
|
abi.encode(ACTION_TYPE.SwapYtForExactScy, receiver)
|
|
137
|
-
);
|
|
145
|
+
); // ignore return
|
|
146
|
+
|
|
147
|
+
emit SwapYT(receiver, netYtIn.neg(), exactScyOut.Int());
|
|
138
148
|
}
|
|
139
149
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
3
|
|
|
4
|
+
import "../libraries/math/MarketApproxLib.sol";
|
|
5
|
+
|
|
4
6
|
interface IPActionCore {
|
|
5
7
|
function addLiquidity(
|
|
6
8
|
address receiver,
|
|
7
9
|
address market,
|
|
8
10
|
uint256 scyDesired,
|
|
9
|
-
uint256
|
|
11
|
+
uint256 ptDesired,
|
|
10
12
|
uint256 minLpOut
|
|
11
13
|
)
|
|
12
14
|
external
|
|
@@ -21,41 +23,35 @@ interface IPActionCore {
|
|
|
21
23
|
address market,
|
|
22
24
|
uint256 lpToRemove,
|
|
23
25
|
uint256 scyOutMin,
|
|
24
|
-
uint256
|
|
26
|
+
uint256 ptOutMin
|
|
25
27
|
) external returns (uint256, uint256);
|
|
26
28
|
|
|
27
|
-
function
|
|
29
|
+
function swapExactPtForScy(
|
|
28
30
|
address receiver,
|
|
29
31
|
address market,
|
|
30
|
-
uint256
|
|
32
|
+
uint256 exactPtIn,
|
|
31
33
|
uint256 minScyOut
|
|
32
34
|
) external returns (uint256);
|
|
33
35
|
|
|
34
|
-
function
|
|
36
|
+
function swapPtForExactScy(
|
|
35
37
|
address receiver,
|
|
36
38
|
address market,
|
|
37
39
|
uint256 exactScyOut,
|
|
38
|
-
|
|
39
|
-
uint256 otInGuessMax,
|
|
40
|
-
uint256 maxIteration,
|
|
41
|
-
uint256 eps
|
|
40
|
+
ApproxParams memory approx
|
|
42
41
|
) external returns (uint256);
|
|
43
42
|
|
|
44
|
-
function
|
|
43
|
+
function swapScyForExactPt(
|
|
45
44
|
address receiver,
|
|
46
45
|
address market,
|
|
47
|
-
uint256
|
|
46
|
+
uint256 exactPtOut,
|
|
48
47
|
uint256 maxScyIn
|
|
49
48
|
) external returns (uint256);
|
|
50
49
|
|
|
51
|
-
function
|
|
50
|
+
function swapExactScyForPt(
|
|
52
51
|
address receiver,
|
|
53
52
|
address market,
|
|
54
53
|
uint256 exactScyIn,
|
|
55
|
-
|
|
56
|
-
uint256 otOutguessMax,
|
|
57
|
-
uint256 maxIteration,
|
|
58
|
-
uint256 eps
|
|
54
|
+
ApproxParams memory approx
|
|
59
55
|
) external returns (uint256);
|
|
60
56
|
|
|
61
57
|
function mintScyFromRawToken(
|
|
@@ -74,35 +70,32 @@ interface IPActionCore {
|
|
|
74
70
|
address[] memory path
|
|
75
71
|
) external returns (uint256);
|
|
76
72
|
|
|
77
|
-
function
|
|
73
|
+
function mintPyFromRawToken(
|
|
78
74
|
uint256 netRawTokenIn,
|
|
79
75
|
address YT,
|
|
80
|
-
uint256
|
|
76
|
+
uint256 minPyOut,
|
|
81
77
|
address receiver,
|
|
82
78
|
address[] calldata path
|
|
83
79
|
) external returns (uint256);
|
|
84
80
|
|
|
85
|
-
function
|
|
81
|
+
function redeemPyToRawToken(
|
|
86
82
|
address YT,
|
|
87
|
-
uint256
|
|
83
|
+
uint256 netPyIn,
|
|
88
84
|
uint256 minRawTokenOut,
|
|
89
85
|
address receiver,
|
|
90
86
|
address[] memory path
|
|
91
87
|
) external returns (uint256);
|
|
92
88
|
|
|
93
|
-
function
|
|
89
|
+
function swapExactRawTokenForPt(
|
|
94
90
|
uint256 exactRawTokenIn,
|
|
95
91
|
address receiver,
|
|
96
92
|
address[] calldata path,
|
|
97
93
|
address market,
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
uint256 maxIteration,
|
|
101
|
-
uint256 eps
|
|
102
|
-
) external returns (uint256 netOtOut);
|
|
94
|
+
ApproxParams memory approx
|
|
95
|
+
) external returns (uint256 netPtOut);
|
|
103
96
|
|
|
104
|
-
function
|
|
105
|
-
uint256
|
|
97
|
+
function swapExactPtForRawToken(
|
|
98
|
+
uint256 exactPtIn,
|
|
106
99
|
address receiver,
|
|
107
100
|
address[] calldata path,
|
|
108
101
|
address market,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
interface IPActionRedeem {
|
|
5
|
+
function redeemDueIncome(
|
|
6
|
+
address user,
|
|
7
|
+
address[] calldata scys,
|
|
8
|
+
address[] calldata yieldTokens,
|
|
9
|
+
address[] calldata /*gauges*/
|
|
10
|
+
)
|
|
11
|
+
external
|
|
12
|
+
returns (
|
|
13
|
+
uint256[][] memory scyRewards,
|
|
14
|
+
uint256[] memory ytInterests,
|
|
15
|
+
uint256[][] memory ytRewards
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
3
|
|
|
4
|
+
import "../libraries/math/MarketApproxLib.sol";
|
|
5
|
+
|
|
4
6
|
interface IPActionYT {
|
|
5
7
|
function swapExactYtForScy(
|
|
6
8
|
address receiver,
|
|
@@ -20,20 +22,14 @@ interface IPActionYT {
|
|
|
20
22
|
address receiver,
|
|
21
23
|
address market,
|
|
22
24
|
uint256 exactScyIn,
|
|
23
|
-
|
|
24
|
-
uint256 netYtOutGuessMax,
|
|
25
|
-
uint256 maxIteration,
|
|
26
|
-
uint256 eps
|
|
25
|
+
ApproxParams memory approx
|
|
27
26
|
) external returns (uint256 netYtOut);
|
|
28
27
|
|
|
29
28
|
function swapYtForExactScy(
|
|
30
29
|
address receiver,
|
|
31
30
|
address market,
|
|
32
31
|
uint256 exactScyOut,
|
|
33
|
-
|
|
34
|
-
uint256 netYtInGuessMax,
|
|
35
|
-
uint256 maxIteration,
|
|
36
|
-
uint256 eps
|
|
32
|
+
ApproxParams memory approx
|
|
37
33
|
) external returns (uint256 netYtIn);
|
|
38
34
|
|
|
39
35
|
function swapExactRawTokenForYt(
|
|
@@ -41,10 +37,7 @@ interface IPActionYT {
|
|
|
41
37
|
address receiver,
|
|
42
38
|
address[] calldata path,
|
|
43
39
|
address market,
|
|
44
|
-
|
|
45
|
-
uint256 netYtOutGuessMax,
|
|
46
|
-
uint256 maxIteration,
|
|
47
|
-
uint256 eps
|
|
40
|
+
ApproxParams memory approx
|
|
48
41
|
) external returns (uint256 netYtOut);
|
|
49
42
|
|
|
50
43
|
function swapExactYtForRawToken(
|