@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.
Files changed (45) hide show
  1. package/contracts/SuperComposableYield/ISuperComposableYield.sol +2 -0
  2. package/contracts/SuperComposableYield/implementations/RewardManager.sol +35 -20
  3. package/contracts/SuperComposableYield/implementations/SCYBase.sol +39 -19
  4. package/contracts/SuperComposableYield/implementations/SCYBaseWithRewards.sol +26 -14
  5. package/contracts/core/PendleBaseToken.sol +2 -2
  6. package/contracts/core/PendleMarket.sol +145 -61
  7. package/contracts/core/PendleMarketFactory.sol +30 -19
  8. package/contracts/core/{PendleOwnershipToken.sol → PendlePrincipalToken.sol} +14 -2
  9. package/contracts/core/PendleRouter.sol +23 -9
  10. package/contracts/core/PendleSCYImpl/AaveV3/PendleAaveV3SCY.sol +21 -20
  11. package/contracts/core/PendleSCYImpl/PendleBenQiErc20SCY.sol +22 -16
  12. package/contracts/core/PendleSCYImpl/PendleBtrflySCY.sol +13 -13
  13. package/contracts/core/PendleSCYImpl/PendleStETHSCY.sol +107 -0
  14. package/contracts/core/PendleSCYImpl/PendleYearnVaultSCY.sol +14 -15
  15. package/contracts/core/PendleYieldContractFactory.sol +29 -14
  16. package/contracts/core/PendleYieldToken.sol +130 -76
  17. package/contracts/core/RouterStatic.sol +16 -157
  18. package/contracts/core/actions/ActionCallback.sol +36 -18
  19. package/contracts/core/actions/ActionCore.sol +41 -88
  20. package/contracts/core/actions/ActionRedeem.sol +36 -0
  21. package/contracts/core/actions/ActionYT.sol +41 -59
  22. package/contracts/core/actions/base/{ActionSCYAndOTBase.sol → ActionSCYAndPTBase.sol} +59 -45
  23. package/contracts/core/actions/base/{ActionSCYAndYOBase.sol → ActionSCYAndPYBase.sol} +57 -19
  24. package/contracts/core/actions/base/ActionSCYAndYTBase.sol +31 -21
  25. package/contracts/interfaces/IPActionCore.sol +21 -28
  26. package/contracts/interfaces/IPActionRedeem.sol +17 -0
  27. package/contracts/interfaces/IPActionYT.sol +5 -12
  28. package/contracts/interfaces/IPAllAction.sol +2 -2
  29. package/contracts/interfaces/IPMarket.sol +33 -10
  30. package/contracts/interfaces/IPMarketAddRemoveCallback.sol +2 -2
  31. package/contracts/interfaces/IPMarketFactory.sol +3 -1
  32. package/contracts/interfaces/IPMarketSwapCallback.sol +1 -1
  33. package/contracts/interfaces/{IPOwnershipToken.sol → IPPrincipalToken.sol} +1 -1
  34. package/contracts/interfaces/IPRouterStatic.sol +7 -82
  35. package/contracts/interfaces/IPYieldContractFactory.sol +10 -2
  36. package/contracts/interfaces/IPYieldToken.sol +14 -5
  37. package/contracts/interfaces/IWstETH.sol +10 -0
  38. package/contracts/libraries/JoeLibrary.sol +1 -1
  39. package/contracts/libraries/math/LogExpMath.sol +1 -1
  40. package/contracts/libraries/math/MarketApproxLib.sol +128 -88
  41. package/contracts/libraries/math/MarketMathAux.sol +13 -13
  42. package/contracts/libraries/math/MarketMathCore.sol +62 -93
  43. package/contracts/libraries/math/Math.sol +14 -2
  44. package/contracts/periphery/PendleGovernanceManager.sol +5 -3
  45. package/package.json +3 -2
@@ -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 ActionSCYAndOTBase {
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 & OT, the receiver will receive LP before
24
- msg.sender is required to pay SCY & OT
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 & ot from msg.sender to the market, and finish the callback
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 otDesired,
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 otUsed
42
+ uint256 ptUsed
43
43
  )
44
44
  {
45
- (ISuperComposableYield SCY, IPOwnershipToken OT, ) = IPMarket(market).readTokens();
45
+ (ISuperComposableYield SCY, IPPrincipalToken PT, ) = IPMarket(market).readTokens();
46
46
 
47
47
  MarketState memory state = IPMarket(market).readState(false);
48
- (, netLpOut, scyUsed, otUsed) = state.addLiquidity(
48
+ (, netLpOut, scyUsed, ptUsed) = state.addLiquidity(
49
49
  SCYIndexLib.newIndex(SCY),
50
50
  scyDesired,
51
- otDesired,
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(OT).safeTransferFrom(msg.sender, market, otUsed);
59
+ IERC20(PT).safeTransferFrom(msg.sender, market, ptUsed);
60
60
  }
61
61
 
62
- IPMarket(market).addLiquidity(receiver, otDesired, scyDesired, abi.encode());
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 & OT. The receiver will receive
67
- SCY & OT before msg.sender is required to transfer in the necessary LP
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 & OT is transferred to the receiver, and the router's callback is invoked
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 otOutMin,
78
+ uint256 ptOutMin,
79
79
  bool doPull
80
- ) internal returns (uint256 netScyOut, uint256 netOtOut) {
80
+ ) internal returns (uint256 netScyOut, uint256 netPtOut) {
81
81
  MarketState memory state = IPMarket(market).readState(false);
82
82
 
83
- (netScyOut, netOtOut) = state.removeLiquidity(lpToRemove, false);
83
+ (netScyOut, netPtOut) = state.removeLiquidity(lpToRemove, false);
84
84
  require(netScyOut >= scyOutMin, "insufficient scy out");
85
- require(netOtOut >= otOutMin, "insufficient ot out");
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 OT for SCY, with receiver receiving SCY before msg.sender is required to
96
- transfer the owed OT
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 OT from msg.sender to the market, and finish the callback
100
+ - the router will transfer the necessary PT from msg.sender to the market, and finish the callback
101
101
  */
102
- function _swapExactOtForScy(
102
+ function _swapExactPtForScy(
103
103
  address receiver,
104
104
  address market,
105
- uint256 exactOtIn,
105
+ uint256 exactPtIn,
106
106
  uint256 minScyOut,
107
107
  bool doPull
108
108
  ) internal returns (uint256 netScyOut) {
109
109
  if (doPull) {
110
- address OT = IPMarket(market).OT();
111
- IERC20(OT).safeTransferFrom(msg.sender, market, exactOtIn);
110
+ address PT = IPMarket(market).PT();
111
+ IERC20(PT).safeTransferFrom(msg.sender, market, exactPtIn);
112
112
  }
113
113
 
114
- (netScyOut, ) = IPMarket(market).swapExactOtForScy(
114
+ (netScyOut, ) = IPMarket(market).swapExactPtForScy(
115
115
  receiver,
116
- exactOtIn,
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
- function _swapOtForExactScy(
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 netOtIn) {
136
+ ) internal returns (uint256 netPtIn) {
131
137
  MarketState memory state = IPMarket(market).readState(false);
132
- (ISuperComposableYield SCY, IPOwnershipToken OT, ) = IPMarket(market).readTokens();
138
+ (ISuperComposableYield SCY, IPPrincipalToken PT, ) = IPMarket(market).readTokens();
133
139
 
134
- (netOtIn, ) = state.approxSwapOtForExactScy(
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(OT).safeTransferFrom(msg.sender, market, netOtIn);
148
+ IERC20(PT).safeTransferFrom(msg.sender, market, netPtIn);
143
149
  }
144
150
 
145
- IPMarket(market).swapExactOtForScy(receiver, netOtIn, exactScyOut, abi.encode());
151
+ IPMarket(market).swapExactPtForScy(receiver, netPtIn, exactScyOut, abi.encode()); // ignore return
146
152
  }
147
153
 
148
154
  /**
149
- * @notice swap SCY for exact OT, with receiver receiving OT before msg.sender is required to
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
- - OT is transferred to the receiver, and the router's callback is invoked
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 _swapScyForExactOt(
162
+ function _swapScyForExactPt(
157
163
  address receiver,
158
164
  address market,
159
- uint256 exactOtOut,
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.swapScyForExactOt(
172
+ (netScyIn, ) = state.swapScyForExactPt(
167
173
  SCYIndexLib.newIndex(SCY),
168
- exactOtOut,
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).swapScyForExactOt(receiver, exactOtOut, maxScyIn, abi.encode());
184
+ IPMarket(market).swapScyForExactPt(receiver, exactPtOut, maxScyIn, abi.encode()); // ignore return
179
185
  }
180
186
 
181
- function _swapExactScyForOt(
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 netOtOut) {
201
+ ) internal returns (uint256 netPtOut) {
188
202
  MarketState memory state = IPMarket(market).readState(false);
189
203
  address SCY = IPMarket(market).SCY();
190
204
 
191
- (netOtOut, ) = state.approxSwapExactScyForOt(
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).swapScyForExactOt(receiver, netOtOut, exactScyIn, abi.encode());
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 ActionSCYAndYOBase is PendleJoeSwapHelperUpg {
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 OT + YT
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 mintYO
94
- will be called, minting OT + YT directly to receiver
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 _mintYoFromRawToken(
131
+ function _mintPyFromRawToken(
97
132
  uint256 netRawTokenIn,
98
133
  address YT,
99
- uint256 minYoOut,
134
+ uint256 minPyOut,
100
135
  address receiver,
101
136
  address[] calldata path,
102
137
  bool doPull
103
- ) internal returns (uint256 netYoOut) {
138
+ ) internal returns (uint256 netPyOut) {
104
139
  address SCY = IPYieldToken(YT).SCY();
105
140
  _mintScyFromRawToken(netRawTokenIn, SCY, 1, YT, path, doPull);
106
- netYoOut = IPYieldToken(YT).mintYO(receiver, receiver);
107
- require(netYoOut >= minYoOut, "insufficient YO out");
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 OT + YT to SCY -> redeem SCY to baseToken -> swap baseToken to rawToken
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
- - OT (+ YT if not expired) is transferred to the YT contract
115
- - redeemYO is called, redeem all outcome SCY to the SCY contract
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 _redeemYoToRawToken(
154
+ function _redeemPyToRawToken(
119
155
  address YT,
120
- uint256 netYoIn,
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 OT = IPYieldToken(YT).OT();
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() == false);
131
- IERC20(OT).safeTransferFrom(msg.sender, YT, netYoIn);
132
- if (isNeedToBurnYt) IERC20(YT).safeTransferFrom(msg.sender, YT, netYoIn);
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).redeemYO(SCY);
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 "./ActionSCYAndYOBase.sol";
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 ActionSCYAndYOBase, ActionType {
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).swapExactOtForScy(
44
- receiver,
45
- netYtOut, // exactOtIn = 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 OT directly to the YT contract, and callback is invoked
55
- - callback will call YT's redeemYO, which will redeem the outcome SCY to this router, then
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).swapScyForExactOt(
74
- receiver,
75
- exactYtIn, // exactOtOut = 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 mintYO, which will mint OT to the market & YT to the receiver
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).swapExactOtForScy(
100
- receiver,
101
- exactYtOut, // exactOtIn = 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).swapScyForExactOt(
140
+ IPMarket(market).swapScyForExactPt(
133
141
  address(YT),
134
- netYtIn, // exactOtOut = 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 otDesired,
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 otOutMin
26
+ uint256 ptOutMin
25
27
  ) external returns (uint256, uint256);
26
28
 
27
- function swapExactOtForScy(
29
+ function swapExactPtForScy(
28
30
  address receiver,
29
31
  address market,
30
- uint256 exactOtIn,
32
+ uint256 exactPtIn,
31
33
  uint256 minScyOut
32
34
  ) external returns (uint256);
33
35
 
34
- function swapOtForExactScy(
36
+ function swapPtForExactScy(
35
37
  address receiver,
36
38
  address market,
37
39
  uint256 exactScyOut,
38
- uint256 otInGuessMin,
39
- uint256 otInGuessMax,
40
- uint256 maxIteration,
41
- uint256 eps
40
+ ApproxParams memory approx
42
41
  ) external returns (uint256);
43
42
 
44
- function swapScyForExactOt(
43
+ function swapScyForExactPt(
45
44
  address receiver,
46
45
  address market,
47
- uint256 exactOtOut,
46
+ uint256 exactPtOut,
48
47
  uint256 maxScyIn
49
48
  ) external returns (uint256);
50
49
 
51
- function swapExactScyForOt(
50
+ function swapExactScyForPt(
52
51
  address receiver,
53
52
  address market,
54
53
  uint256 exactScyIn,
55
- uint256 otOutguessMin,
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 mintYoFromRawToken(
73
+ function mintPyFromRawToken(
78
74
  uint256 netRawTokenIn,
79
75
  address YT,
80
- uint256 minYoOut,
76
+ uint256 minPyOut,
81
77
  address receiver,
82
78
  address[] calldata path
83
79
  ) external returns (uint256);
84
80
 
85
- function redeemYoToRawToken(
81
+ function redeemPyToRawToken(
86
82
  address YT,
87
- uint256 netYoIn,
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 swapExactRawTokenForOt(
89
+ function swapExactRawTokenForPt(
94
90
  uint256 exactRawTokenIn,
95
91
  address receiver,
96
92
  address[] calldata path,
97
93
  address market,
98
- uint256 otOutguessMin,
99
- uint256 otOutguessMax,
100
- uint256 maxIteration,
101
- uint256 eps
102
- ) external returns (uint256 netOtOut);
94
+ ApproxParams memory approx
95
+ ) external returns (uint256 netPtOut);
103
96
 
104
- function swapExactOtForRawToken(
105
- uint256 exactOtIn,
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
- uint256 netYtOutGuessMin,
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
- uint256 netYtInGuessMin,
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
- uint256 netYtOutGuessMin,
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(