@pendle/core-v2 0.4.0 → 0.5.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/implementations/IRewardManager.sol +16 -0
- package/contracts/SuperComposableYield/implementations/RewardManager.sol +24 -5
- package/contracts/core/PendleMarket.sol +10 -18
- package/contracts/core/PendleMarketFactory.sol +49 -22
- package/contracts/core/PendleRouter.sol +74 -0
- package/contracts/core/PendleYieldToken.sol +20 -12
- package/contracts/core/{router/PendleRouterStaticUpg.sol → RouterStatic.sol} +6 -6
- package/contracts/core/actions/ActionCallback.sol +101 -0
- package/contracts/core/{router/PendleRouterCoreUpg.sol → actions/ActionCore.sol} +6 -10
- package/contracts/core/{router/PendleRouterYTUpg.sol → actions/ActionYT.sol} +6 -11
- package/contracts/core/{router/base/PendleRouterOTBaseUpg.sol → actions/base/ActionSCYAndOTBase.sol} +1 -5
- package/contracts/core/{router/base/PendleRouterSCYAndForgeBaseUpg.sol → actions/base/ActionSCYAndYOBase.sol} +3 -5
- package/contracts/core/{router/base/PendleRouterYTBaseUpg.sol → actions/base/ActionSCYAndYTBase.sol} +7 -99
- package/contracts/core/actions/base/ActionType.sol +11 -0
- package/contracts/interfaces/{IPRouterCore.sol → IPActionCore.sol} +1 -1
- package/contracts/interfaces/{IPRouterYT.sol → IPActionYT.sol} +1 -3
- package/contracts/interfaces/IPAllAction.sol +9 -0
- package/contracts/interfaces/IPMarketFactory.sol +11 -0
- package/contracts/interfaces/IPYieldToken.sol +21 -3
- package/contracts/libraries/math/MarketMathCore.sol +3 -2
- package/package.json +1 -1
- package/typechain-types/{PendleRouterYTBaseUpg.ts → ActionCallback.ts} +5 -5
- package/typechain-types/{PendleRouterCoreUpg.ts → ActionCore.ts} +5 -5
- package/typechain-types/{PendleRouterSCYAndForgeBaseUpg.ts → ActionSCYAndYOBase.ts} +5 -6
- package/typechain-types/{BoringOwnableData.ts → ActionSCYAndYTBase.ts} +21 -24
- package/typechain-types/{PendleRouterStaticUpg.ts → ActionStatic.ts} +5 -5
- package/typechain-types/{IPRouterYT.ts → ActionYT.ts} +27 -42
- package/typechain-types/IPActionAll.ts +1431 -0
- package/typechain-types/{IPRouterCore.ts → IPActionCore.ts} +5 -5
- package/typechain-types/{IPRouterView.ts → IPActionStatic.ts} +57 -5
- package/typechain-types/{PendleRouterYTUpg.ts → IPActionYT.ts} +5 -97
- package/typechain-types/IPAllAction.ts +1431 -0
- package/typechain-types/IPMarket.ts +3 -0
- package/typechain-types/IPMarketFactory.ts +46 -0
- package/typechain-types/IPYieldToken.ts +342 -14
- package/typechain-types/IRewardManager.ts +178 -0
- package/typechain-types/PendleAaveV3SCY.ts +70 -64
- package/typechain-types/PendleBenQiErc20SCY.ts +70 -64
- package/typechain-types/PendleMarket.ts +3 -59
- package/typechain-types/PendleMarketFactory.ts +150 -24
- package/typechain-types/{PendleRouterProxy.ts → PendleRouter.ts} +29 -39
- package/typechain-types/PendleYieldToken.ts +116 -101
- package/typechain-types/RewardManager.ts +48 -42
- package/typechain-types/RouterStatic.ts +828 -0
- package/typechain-types/SCYBaseWithRewards.ts +70 -64
- package/typechain-types/factories/ActionCallback__factory.ts +116 -0
- package/typechain-types/factories/ActionCore__factory.ts +632 -0
- package/typechain-types/factories/{PendleRouterSCYAndForgeBaseUpg__factory.ts → ActionSCYAndYOBase__factory.ts} +8 -12
- package/typechain-types/factories/ActionSCYAndYTBase__factory.ts +52 -0
- package/typechain-types/factories/ActionStatic__factory.ts +308 -0
- package/typechain-types/factories/ActionYT__factory.ts +370 -0
- package/typechain-types/factories/IPActionAll__factory.ts +983 -0
- package/typechain-types/factories/{IPRouterCore__factory.ts → IPActionCore__factory.ts} +6 -6
- package/typechain-types/factories/{IPRouterView__factory.ts → IPActionStatic__factory.ts} +38 -6
- package/typechain-types/factories/{IPRouterYT__factory.ts → IPActionYT__factory.ts} +6 -29
- package/typechain-types/factories/IPAllAction__factory.ts +983 -0
- package/typechain-types/factories/IPMarketFactory__factory.ts +28 -0
- package/typechain-types/factories/IPMarket__factory.ts +7 -2
- package/typechain-types/factories/IPYieldToken__factory.ts +158 -1
- package/typechain-types/factories/IRewardManager__factory.ts +92 -0
- package/typechain-types/factories/PendleAaveV3SCY__factory.ts +34 -34
- package/typechain-types/factories/PendleBenQiErc20SCY__factory.ts +34 -34
- package/typechain-types/factories/PendleBtrflyScy__factory.ts +1 -1
- package/typechain-types/factories/PendleMarketFactory__factory.ts +112 -17
- package/typechain-types/factories/PendleMarket__factory.ts +8 -69
- package/typechain-types/factories/PendleRouter__factory.ts +282 -0
- package/typechain-types/factories/PendleYearnVaultScy__factory.ts +1 -1
- package/typechain-types/factories/PendleYieldContractFactory__factory.ts +1 -1
- package/typechain-types/factories/PendleYieldToken__factory.ts +58 -58
- package/typechain-types/factories/RewardManager__factory.ts +18 -18
- package/typechain-types/factories/RouterStatic__factory.ts +883 -0
- package/typechain-types/factories/SCYBaseWithRewards__factory.ts +33 -33
- package/typechain-types/hardhat.d.ts +93 -75
- package/typechain-types/index.ts +22 -18
- package/contracts/core/router/PendleRouterProxy.sol +0 -84
- package/contracts/interfaces/IPFlashCallBack.sol +0 -10
- package/typechain-types/BoringOwnable.ts +0 -194
- package/typechain-types/BoringOwnableUpg.ts +0 -194
- package/typechain-types/BoringOwnableUpgData.ts +0 -100
- package/typechain-types/IPFlashCallback.ts +0 -115
- package/typechain-types/IPermissionsV2.ts +0 -87
- package/typechain-types/PendleRouterViewUpg.ts +0 -307
- package/typechain-types/PermissionsV2.ts +0 -87
- package/typechain-types/factories/BoringOwnableData__factory.ts +0 -90
- package/typechain-types/factories/BoringOwnableUpgData__factory.ts +0 -94
- package/typechain-types/factories/BoringOwnableUpg__factory.ts +0 -139
- package/typechain-types/factories/BoringOwnable__factory.ts +0 -149
- package/typechain-types/factories/IPFlashCallback__factory.ts +0 -49
- package/typechain-types/factories/IPermissionsV2__factory.ts +0 -39
- package/typechain-types/factories/PendleRouterCoreUpg__factory.ts +0 -635
- package/typechain-types/factories/PendleRouterProxy__factory.ts +0 -285
- package/typechain-types/factories/PendleRouterStaticUpg__factory.ts +0 -315
- package/typechain-types/factories/PendleRouterViewUpg__factory.ts +0 -265
- package/typechain-types/factories/PendleRouterYTBaseUpg__factory.ts +0 -66
- package/typechain-types/factories/PendleRouterYTUpg__factory.ts +0 -422
- package/typechain-types/factories/PermissionsV2__factory.ts +0 -36
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
interface IRewardManager {
|
|
5
|
+
function getGlobalReward(address rewardToken)
|
|
6
|
+
external
|
|
7
|
+
view
|
|
8
|
+
returns (uint256 index, uint256 lastBalance);
|
|
9
|
+
|
|
10
|
+
function getUserReward(address user, address rewardToken)
|
|
11
|
+
external
|
|
12
|
+
view
|
|
13
|
+
returns (uint256 lastIndex, uint256 accruedReward);
|
|
14
|
+
|
|
15
|
+
function getRewardTokens() external view returns (address[] memory);
|
|
16
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
3
|
import "../ISuperComposableYield.sol";
|
|
4
|
+
import "./IRewardManager.sol";
|
|
4
5
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
5
6
|
import "../../libraries/math/Math.sol";
|
|
6
7
|
|
|
7
|
-
abstract contract RewardManager {
|
|
8
|
+
abstract contract RewardManager is IRewardManager {
|
|
8
9
|
using SafeERC20 for IERC20;
|
|
9
10
|
using Math for uint256;
|
|
10
11
|
|
|
@@ -20,8 +21,28 @@ abstract contract RewardManager {
|
|
|
20
21
|
|
|
21
22
|
uint256 internal constant INITIAL_REWARD_INDEX = 1;
|
|
22
23
|
|
|
23
|
-
mapping(address => GlobalReward)
|
|
24
|
-
mapping(address => mapping(address => UserReward))
|
|
24
|
+
mapping(address => GlobalReward) internal globalReward;
|
|
25
|
+
mapping(address => mapping(address => UserReward)) internal userReward;
|
|
26
|
+
|
|
27
|
+
function getGlobalReward(address rewardToken)
|
|
28
|
+
external
|
|
29
|
+
view
|
|
30
|
+
returns (uint256 index, uint256 lastBalance)
|
|
31
|
+
{
|
|
32
|
+
GlobalReward memory reward = globalReward[rewardToken];
|
|
33
|
+
return (reward.index, reward.lastBalance);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function getUserReward(address user, address rewardToken)
|
|
37
|
+
external
|
|
38
|
+
view
|
|
39
|
+
returns (uint256 lastIndex, uint256 accruedReward)
|
|
40
|
+
{
|
|
41
|
+
UserReward memory reward = userReward[user][rewardToken];
|
|
42
|
+
return (reward.lastIndex, reward.accruedReward);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getRewardTokens() public view virtual override returns (address[] memory);
|
|
25
46
|
|
|
26
47
|
function _doTransferOutRewardsForUser(address user, address receiver)
|
|
27
48
|
internal
|
|
@@ -111,7 +132,5 @@ abstract contract RewardManager {
|
|
|
111
132
|
}
|
|
112
133
|
}
|
|
113
134
|
|
|
114
|
-
function getRewardTokens() public view virtual returns (address[] memory);
|
|
115
|
-
|
|
116
135
|
function _redeemExternalReward() internal virtual;
|
|
117
136
|
}
|
|
@@ -34,31 +34,19 @@ contract PendleMarket is PendleBaseToken, IPMarket, ReentrancyGuard {
|
|
|
34
34
|
address public immutable YT;
|
|
35
35
|
|
|
36
36
|
int256 public immutable scalarRoot;
|
|
37
|
-
uint256 public immutable feeRateRoot; // allow fee to be changable?
|
|
38
37
|
int256 public immutable initialAnchor;
|
|
39
38
|
|
|
40
|
-
uint256 public immutable rateOracleTimeWindow;
|
|
41
|
-
int8 public immutable reserveFeePercent;
|
|
42
|
-
|
|
43
39
|
MarketStorage public marketStorage;
|
|
44
40
|
|
|
45
41
|
constructor(
|
|
46
42
|
address _OT,
|
|
47
|
-
uint256 _rateOracleTimeWindow,
|
|
48
|
-
uint256 _feeRateRoot,
|
|
49
43
|
int256 _scalarRoot,
|
|
50
|
-
int256 _initialAnchor
|
|
51
|
-
uint8 _reserveFeePercent
|
|
44
|
+
int256 _initialAnchor
|
|
52
45
|
) PendleBaseToken(NAME, SYMBOL, 18, IPOwnershipToken(_OT).expiry()) {
|
|
53
46
|
OT = _OT;
|
|
54
47
|
SCY = IPOwnershipToken(_OT).SCY();
|
|
55
48
|
YT = IPOwnershipToken(_OT).YT();
|
|
56
|
-
feeRateRoot = _feeRateRoot;
|
|
57
49
|
scalarRoot = _scalarRoot;
|
|
58
|
-
rateOracleTimeWindow = _rateOracleTimeWindow;
|
|
59
|
-
|
|
60
|
-
require(_reserveFeePercent <= 100, "invalid fee rate");
|
|
61
|
-
reserveFeePercent = int8(_reserveFeePercent);
|
|
62
50
|
initialAnchor = _initialAnchor;
|
|
63
51
|
}
|
|
64
52
|
|
|
@@ -154,7 +142,7 @@ contract PendleMarket is PendleBaseToken, IPMarket, ReentrancyGuard {
|
|
|
154
142
|
);
|
|
155
143
|
require(netScyOut >= minScyOut, "insufficient scy out");
|
|
156
144
|
IERC20(SCY).safeTransfer(receiver, netScyOut);
|
|
157
|
-
IERC20(SCY).safeTransfer(
|
|
145
|
+
IERC20(SCY).safeTransfer(market.treasury, netScyToReserve);
|
|
158
146
|
|
|
159
147
|
if (data.length > 0) {
|
|
160
148
|
IPMarketSwapCallback(msg.sender).swapCallback(exactOtIn.neg(), netScyOut.Int(), data);
|
|
@@ -183,7 +171,7 @@ contract PendleMarket is PendleBaseToken, IPMarket, ReentrancyGuard {
|
|
|
183
171
|
);
|
|
184
172
|
require(netScyIn <= maxScyIn, "scy in exceed limit");
|
|
185
173
|
IERC20(OT).safeTransfer(receiver, exactOtOut);
|
|
186
|
-
IERC20(SCY).safeTransfer(
|
|
174
|
+
IERC20(SCY).safeTransfer(market.treasury, netScyToReserve);
|
|
187
175
|
|
|
188
176
|
if (data.length > 0) {
|
|
189
177
|
IPMarketSwapCallback(msg.sender).swapCallback(exactOtOut.Int(), netScyIn.neg(), data);
|
|
@@ -206,11 +194,15 @@ contract PendleMarket is PendleBaseToken, IPMarket, ReentrancyGuard {
|
|
|
206
194
|
market.totalScy = store.totalScy;
|
|
207
195
|
market.totalLp = totalSupply().Int();
|
|
208
196
|
market.oracleRate = store.oracleRate;
|
|
209
|
-
|
|
197
|
+
|
|
198
|
+
(
|
|
199
|
+
market.treasury,
|
|
200
|
+
market.feeRateRoot,
|
|
201
|
+
market.rateOracleTimeWindow,
|
|
202
|
+
market.reserveFeePercent
|
|
203
|
+
) = IPMarketFactory(factory).marketConfig();
|
|
210
204
|
|
|
211
205
|
market.scalarRoot = scalarRoot;
|
|
212
|
-
market.feeRateRoot = feeRateRoot;
|
|
213
|
-
market.rateOracleTimeWindow = rateOracleTimeWindow;
|
|
214
206
|
market.expiry = expiry;
|
|
215
207
|
|
|
216
208
|
market.lastImpliedRate = store.lastImpliedRate;
|
|
@@ -10,24 +10,40 @@ import "./PendleMarket.sol";
|
|
|
10
10
|
contract PendleMarketFactory is PermissionsV2Upg, IPMarketFactory {
|
|
11
11
|
using EnumerableSet for EnumerableSet.AddressSet;
|
|
12
12
|
|
|
13
|
+
struct MarketConfig {
|
|
14
|
+
address treasury; // 160 bit
|
|
15
|
+
uint96 feeRateRoot; // 96 bit
|
|
16
|
+
// 1 SLOT
|
|
17
|
+
uint32 rateOracleTimeWindow;
|
|
18
|
+
uint8 reserveFeePercent;
|
|
19
|
+
}
|
|
20
|
+
|
|
13
21
|
mapping(address => EnumerableSet.AddressSet) internal markets;
|
|
14
22
|
|
|
15
23
|
address public immutable yieldContractFactory;
|
|
16
|
-
address public treasury;
|
|
17
24
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
MarketConfig public marketConfig;
|
|
26
|
+
|
|
27
|
+
constructor(
|
|
28
|
+
address _governanceManager,
|
|
29
|
+
address _yieldContractFactory,
|
|
30
|
+
address _treasury,
|
|
31
|
+
uint96 _feeRateRoot,
|
|
32
|
+
uint32 _rateOracleTimeWindow,
|
|
33
|
+
uint8 _reserveFeePercent
|
|
34
|
+
) PermissionsV2Upg(_governanceManager) {
|
|
21
35
|
yieldContractFactory = _yieldContractFactory;
|
|
36
|
+
|
|
37
|
+
setTreasury(_treasury);
|
|
38
|
+
setFeeRateRoot(_feeRateRoot);
|
|
39
|
+
setRateOracleTimeWindow(_rateOracleTimeWindow);
|
|
40
|
+
setReserveFeePercent(_reserveFeePercent);
|
|
22
41
|
}
|
|
23
42
|
|
|
24
43
|
function createNewMarket(
|
|
25
44
|
address OT,
|
|
26
|
-
uint256 feeRateRoot,
|
|
27
45
|
int256 scalarRoot,
|
|
28
|
-
int256 initialAnchor
|
|
29
|
-
uint8 reserveFeePercent,
|
|
30
|
-
uint256 rateOracleTimeWindow
|
|
46
|
+
int256 initialAnchor
|
|
31
47
|
) external returns (address market) {
|
|
32
48
|
address SCY = IPOwnershipToken(OT).SCY();
|
|
33
49
|
uint256 expiry = IPOwnershipToken(OT).expiry();
|
|
@@ -37,25 +53,36 @@ contract PendleMarketFactory is PermissionsV2Upg, IPMarketFactory {
|
|
|
37
53
|
"INVALID_OT"
|
|
38
54
|
);
|
|
39
55
|
|
|
40
|
-
market = address(
|
|
41
|
-
new PendleMarket(
|
|
42
|
-
OT,
|
|
43
|
-
rateOracleTimeWindow,
|
|
44
|
-
feeRateRoot,
|
|
45
|
-
scalarRoot,
|
|
46
|
-
initialAnchor,
|
|
47
|
-
reserveFeePercent
|
|
48
|
-
)
|
|
49
|
-
);
|
|
56
|
+
market = address(new PendleMarket(OT, scalarRoot, initialAnchor));
|
|
50
57
|
markets[OT].add(market);
|
|
51
58
|
}
|
|
52
59
|
|
|
53
|
-
function setTreasury(address newTreasury) external onlyGovernance {
|
|
54
|
-
treasury = newTreasury;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
60
|
function isValidMarket(address market) external view returns (bool) {
|
|
58
61
|
address OT = IPMarket(market).OT();
|
|
59
62
|
return markets[OT].contains(market);
|
|
60
63
|
}
|
|
64
|
+
|
|
65
|
+
function treasury() external view returns (address) {
|
|
66
|
+
return marketConfig.treasury;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function setTreasury(address newTreasury) public onlyGovernance {
|
|
70
|
+
require(newTreasury != address(0), "zero address");
|
|
71
|
+
marketConfig.treasury = newTreasury;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function setFeeRateRoot(uint96 newFeeRateRoot) public onlyGovernance {
|
|
75
|
+
// TODO: hard cap on the fee
|
|
76
|
+
marketConfig.feeRateRoot = newFeeRateRoot;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function setRateOracleTimeWindow(uint32 newRateOracleTimeWindow) public onlyGovernance {
|
|
80
|
+
// TODO: hard min for the time window
|
|
81
|
+
marketConfig.rateOracleTimeWindow = newRateOracleTimeWindow;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function setReserveFeePercent(uint8 newReserveFeePercent) public onlyGovernance {
|
|
85
|
+
require(newReserveFeePercent <= 100, "invalid fee rate");
|
|
86
|
+
marketConfig.reserveFeePercent = newReserveFeePercent;
|
|
87
|
+
}
|
|
61
88
|
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
5
|
+
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
6
|
+
import "@openzeppelin/contracts/proxy/Proxy.sol";
|
|
7
|
+
import "../interfaces/IPActionCore.sol";
|
|
8
|
+
import "../interfaces/IPActionYT.sol";
|
|
9
|
+
import "../interfaces/IPRouterStatic.sol";
|
|
10
|
+
import "../interfaces/IPMarketSwapCallback.sol";
|
|
11
|
+
import "../periphery/PermissionsV2Upg.sol";
|
|
12
|
+
|
|
13
|
+
/// @dev this contract will be deployed behind an ERC1967 proxy
|
|
14
|
+
/// calls to the ERC1967 proxy will be resolved at this contract, and proxied again to the
|
|
15
|
+
/// corresponding implementation contracts
|
|
16
|
+
|
|
17
|
+
// solhint-disable no-empty-blocks
|
|
18
|
+
contract PendleRouter is Proxy, Initializable, UUPSUpgradeable, PermissionsV2Upg {
|
|
19
|
+
address public immutable ACTION_CORE;
|
|
20
|
+
address public immutable ACTION_YT;
|
|
21
|
+
address public immutable ACTION_CALLBACK;
|
|
22
|
+
|
|
23
|
+
constructor(
|
|
24
|
+
address _ACTION_CORE,
|
|
25
|
+
address _ACTION_YT,
|
|
26
|
+
address _ACTION_CALLBACK,
|
|
27
|
+
address _governanceManager
|
|
28
|
+
) PermissionsV2Upg(_governanceManager) initializer {
|
|
29
|
+
ACTION_CORE = _ACTION_CORE;
|
|
30
|
+
ACTION_YT = _ACTION_YT;
|
|
31
|
+
ACTION_CALLBACK = _ACTION_CALLBACK;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function initialize() external initializer {
|
|
35
|
+
__UUPSUpgradeable_init();
|
|
36
|
+
// no need to initialize PermissionsV2Upg
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function getRouterImplementation(bytes4 sig) public view returns (address) {
|
|
40
|
+
if (
|
|
41
|
+
sig == IPActionCore.mintScyFromRawToken.selector ||
|
|
42
|
+
sig == IPActionCore.redeemScyToRawToken.selector ||
|
|
43
|
+
sig == IPActionCore.mintYoFromRawToken.selector ||
|
|
44
|
+
sig == IPActionCore.redeemYoToRawToken.selector ||
|
|
45
|
+
sig == IPActionCore.addLiquidity.selector ||
|
|
46
|
+
sig == IPActionCore.removeLiquidity.selector ||
|
|
47
|
+
sig == IPActionCore.swapExactOtForScy.selector ||
|
|
48
|
+
sig == IPActionCore.swapOtForExactScy.selector ||
|
|
49
|
+
sig == IPActionCore.swapScyForExactOt.selector ||
|
|
50
|
+
sig == IPActionCore.swapExactScyForOt.selector ||
|
|
51
|
+
sig == IPActionCore.swapExactRawTokenForOt.selector ||
|
|
52
|
+
sig == IPActionCore.swapExactOtForRawToken.selector
|
|
53
|
+
) {
|
|
54
|
+
return ACTION_CORE;
|
|
55
|
+
} else if (
|
|
56
|
+
sig == IPActionYT.swapExactYtForScy.selector ||
|
|
57
|
+
sig == IPActionYT.swapScyForExactYt.selector ||
|
|
58
|
+
sig == IPActionYT.swapExactScyForYt.selector ||
|
|
59
|
+
sig == IPActionYT.swapExactRawTokenForYt.selector ||
|
|
60
|
+
sig == IPActionYT.swapExactYtForRawToken.selector
|
|
61
|
+
) {
|
|
62
|
+
return ACTION_YT;
|
|
63
|
+
} else if (sig == IPMarketSwapCallback.swapCallback.selector) {
|
|
64
|
+
return ACTION_CALLBACK;
|
|
65
|
+
}
|
|
66
|
+
require(false, "invalid market sig");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function _implementation() internal view override returns (address) {
|
|
70
|
+
return getRouterImplementation(msg.sig);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function _authorizeUpgrade(address newImplementation) internal override onlyGovernance {}
|
|
74
|
+
}
|
|
@@ -19,11 +19,11 @@ It has been proven and tested that impliedScyBalance will not change over time,
|
|
|
19
19
|
|
|
20
20
|
Due to this, it is required to update users' accruedReward STRICTLY BEFORE redeeming their interest.
|
|
21
21
|
*/
|
|
22
|
-
contract PendleYieldToken is PendleBaseToken,
|
|
22
|
+
contract PendleYieldToken is PendleBaseToken, RewardManager, IPYieldToken {
|
|
23
23
|
using Math for uint256;
|
|
24
24
|
using SafeERC20 for IERC20;
|
|
25
25
|
|
|
26
|
-
struct
|
|
26
|
+
struct InterestData {
|
|
27
27
|
uint256 lastScyIndex;
|
|
28
28
|
uint256 dueInterest;
|
|
29
29
|
}
|
|
@@ -40,7 +40,7 @@ contract PendleYieldToken is PendleBaseToken, IPYieldToken, RewardManager {
|
|
|
40
40
|
mapping(address => uint256) public totalRewardsPostExpiry;
|
|
41
41
|
uint256 public totalProtocolFee;
|
|
42
42
|
|
|
43
|
-
mapping(address =>
|
|
43
|
+
mapping(address => InterestData) internal interestData;
|
|
44
44
|
|
|
45
45
|
constructor(
|
|
46
46
|
address _SCY,
|
|
@@ -118,13 +118,13 @@ contract PendleYieldToken is PendleBaseToken, IPYieldToken, RewardManager {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
function updateUserInterest(address user) public {
|
|
121
|
-
uint256 prevIndex =
|
|
121
|
+
uint256 prevIndex = interestData[user].lastScyIndex;
|
|
122
122
|
|
|
123
123
|
uint256 currentIndex = getScyIndexBeforeExpiry();
|
|
124
124
|
|
|
125
125
|
if (prevIndex == currentIndex) return;
|
|
126
126
|
if (prevIndex == 0) {
|
|
127
|
-
|
|
127
|
+
interestData[user].lastScyIndex = currentIndex;
|
|
128
128
|
return;
|
|
129
129
|
}
|
|
130
130
|
|
|
@@ -134,8 +134,16 @@ contract PendleYieldToken is PendleBaseToken, IPYieldToken, RewardManager {
|
|
|
134
134
|
prevIndex * currentIndex
|
|
135
135
|
);
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
interestData[user].dueInterest += interestFromYT;
|
|
138
|
+
interestData[user].lastScyIndex = currentIndex;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function getInterestData(address user)
|
|
142
|
+
external
|
|
143
|
+
view
|
|
144
|
+
returns (uint256 lastScyIndex, uint256 dueInterest)
|
|
145
|
+
{
|
|
146
|
+
return (interestData[user].lastScyIndex, interestData[user].dueInterest);
|
|
139
147
|
}
|
|
140
148
|
|
|
141
149
|
function _updateGlobalReward(address[] memory rewardTokens, uint256 totalSupply)
|
|
@@ -165,8 +173,8 @@ contract PendleYieldToken is PendleBaseToken, IPYieldToken, RewardManager {
|
|
|
165
173
|
}
|
|
166
174
|
|
|
167
175
|
function _doTransferOutDueInterest(address user) internal returns (uint256 interestOut) {
|
|
168
|
-
uint256 interestPreFee =
|
|
169
|
-
|
|
176
|
+
uint256 interestPreFee = interestData[user].dueInterest;
|
|
177
|
+
interestData[user].dueInterest = 0;
|
|
170
178
|
|
|
171
179
|
uint256 feeRate = IPYieldContractFactory(factory).interestFeeRate();
|
|
172
180
|
uint256 feeAmount = interestPreFee.mulDown(feeRate);
|
|
@@ -185,7 +193,7 @@ contract PendleYieldToken is PendleBaseToken, IPYieldToken, RewardManager {
|
|
|
185
193
|
public
|
|
186
194
|
view
|
|
187
195
|
virtual
|
|
188
|
-
override(RewardManager)
|
|
196
|
+
override(RewardManager, IRewardManager)
|
|
189
197
|
returns (address[] memory)
|
|
190
198
|
{
|
|
191
199
|
return ISuperComposableYield(SCY).getRewardTokens();
|
|
@@ -247,9 +255,9 @@ contract PendleYieldToken is PendleBaseToken, IPYieldToken, RewardManager {
|
|
|
247
255
|
}
|
|
248
256
|
|
|
249
257
|
function getImpliedScyBalance(address user) public view returns (uint256) {
|
|
250
|
-
uint256 scyIndex =
|
|
258
|
+
uint256 scyIndex = interestData[user].lastScyIndex;
|
|
251
259
|
if (scyIndex == 0) return 0;
|
|
252
|
-
return SCYUtils.assetToScy(scyIndex, balanceOf(user)) +
|
|
260
|
+
return SCYUtils.assetToScy(scyIndex, balanceOf(user)) + interestData[user].dueInterest;
|
|
253
261
|
}
|
|
254
262
|
|
|
255
263
|
function _beforeTokenTransfer(
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
3
|
|
|
4
|
-
import "
|
|
5
|
-
import "
|
|
6
|
-
import "
|
|
7
|
-
import "
|
|
8
|
-
import "
|
|
4
|
+
import "../interfaces/IPRouterStatic.sol";
|
|
5
|
+
import "../interfaces/IPMarket.sol";
|
|
6
|
+
import "../interfaces/IPYieldContractFactory.sol";
|
|
7
|
+
import "../interfaces/IPMarketFactory.sol";
|
|
8
|
+
import "../libraries/math/MarketMathAux.sol";
|
|
9
9
|
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
10
10
|
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
11
11
|
|
|
12
|
-
contract
|
|
12
|
+
contract RouterStatic is IPRouterStatic {
|
|
13
13
|
using MarketMathCore for MarketState;
|
|
14
14
|
using MarketMathAux for MarketState;
|
|
15
15
|
using Math for uint256;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
|
|
4
|
+
import "../../interfaces/IPMarketFactory.sol";
|
|
5
|
+
import "../../interfaces/IPMarket.sol";
|
|
6
|
+
import "../../interfaces/IPMarketAddRemoveCallback.sol";
|
|
7
|
+
import "../../interfaces/IPMarketSwapCallback.sol";
|
|
8
|
+
import "../../SuperComposableYield/SCYUtils.sol";
|
|
9
|
+
import "../../libraries/math/MarketApproxLib.sol";
|
|
10
|
+
import "../../libraries/math/MarketMathAux.sol";
|
|
11
|
+
import "./base/ActionSCYAndYOBase.sol";
|
|
12
|
+
import "./base/ActionType.sol";
|
|
13
|
+
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
14
|
+
|
|
15
|
+
contract ActionCallback is IPMarketSwapCallback, ActionType {
|
|
16
|
+
address public immutable marketFactory;
|
|
17
|
+
using Math for int256;
|
|
18
|
+
using Math for uint256;
|
|
19
|
+
using SafeERC20 for ISuperComposableYield;
|
|
20
|
+
using SafeERC20 for IPYieldToken;
|
|
21
|
+
|
|
22
|
+
modifier onlyPendleMarket(address market) {
|
|
23
|
+
require(IPMarketFactory(marketFactory).isValidMarket(market), "INVALID_MARKET");
|
|
24
|
+
_;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
28
|
+
constructor(address _marketFactory) {
|
|
29
|
+
marketFactory = _marketFactory;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function swapCallback(
|
|
33
|
+
int256 otToAccount,
|
|
34
|
+
int256 scyToAccount,
|
|
35
|
+
bytes calldata data
|
|
36
|
+
) external override onlyPendleMarket(msg.sender) {
|
|
37
|
+
(ACTION_TYPE swapType, ) = abi.decode(data, (ACTION_TYPE, bytes));
|
|
38
|
+
|
|
39
|
+
if (swapType == ACTION_TYPE.SwapExactScyForYt) {
|
|
40
|
+
_swapExactScyForYt_callback(msg.sender, data);
|
|
41
|
+
} else if (swapType == ACTION_TYPE.SwapSCYForExactYt) {
|
|
42
|
+
_swapScyForExactYt_callback(msg.sender, otToAccount, scyToAccount, data);
|
|
43
|
+
} else if (
|
|
44
|
+
swapType == ACTION_TYPE.SwapYtForExactScy || swapType == ACTION_TYPE.SwapExactYtForScy
|
|
45
|
+
) {
|
|
46
|
+
_swapYtForScy_callback(msg.sender, scyToAccount, data);
|
|
47
|
+
} else {
|
|
48
|
+
require(false, "unknown swapType");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function _swapExactScyForYt_callback(address market, bytes calldata data) internal {
|
|
53
|
+
(, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
54
|
+
(, address receiver) = abi.decode(data, (ACTION_TYPE, address));
|
|
55
|
+
|
|
56
|
+
YT.mintYO(market, receiver);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function _swapScyForExactYt_callback(
|
|
60
|
+
address market,
|
|
61
|
+
int256 otToAccount,
|
|
62
|
+
int256 scyToAccount,
|
|
63
|
+
bytes calldata data
|
|
64
|
+
) internal {
|
|
65
|
+
(, address payer, address receiver) = abi.decode(data, (ACTION_TYPE, address, address));
|
|
66
|
+
(ISuperComposableYield SCY, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
67
|
+
|
|
68
|
+
uint256 otOwed = otToAccount.neg().Uint();
|
|
69
|
+
uint256 scyReceived = scyToAccount.Uint();
|
|
70
|
+
|
|
71
|
+
// otOwed = totalAsset
|
|
72
|
+
uint256 scyNeedTotal = SCYUtils.assetToScy(SCY.scyIndexCurrent(), otOwed);
|
|
73
|
+
|
|
74
|
+
uint256 netScyToPull = scyNeedTotal.subMax0(scyReceived);
|
|
75
|
+
SCY.safeTransferFrom(payer, address(YT), netScyToPull);
|
|
76
|
+
|
|
77
|
+
YT.mintYO(market, receiver);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
@dev receive OT -> pair with YT to redeem SCY -> payback SCY
|
|
82
|
+
*/
|
|
83
|
+
function _swapYtForScy_callback(
|
|
84
|
+
address market,
|
|
85
|
+
int256 scyToAccount,
|
|
86
|
+
bytes calldata data
|
|
87
|
+
) internal {
|
|
88
|
+
(, address receiver) = abi.decode(data, (ACTION_TYPE, address));
|
|
89
|
+
(ISuperComposableYield SCY, , IPYieldToken YT) = IPMarket(market).readTokens();
|
|
90
|
+
|
|
91
|
+
uint256 scyOwed = scyToAccount.neg().Uint();
|
|
92
|
+
|
|
93
|
+
uint256 netScyReceived = YT.redeemYO(address(this));
|
|
94
|
+
|
|
95
|
+
SCY.safeTransfer(market, scyOwed);
|
|
96
|
+
|
|
97
|
+
if (receiver != address(this)) {
|
|
98
|
+
SCY.safeTransfer(receiver, netScyReceived - scyOwed);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -1,18 +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/
|
|
4
|
+
import "./base/ActionSCYAndOTBase.sol";
|
|
5
|
+
import "./base/ActionSCYAndYOBase.sol";
|
|
6
6
|
import "../../interfaces/IPOwnershipToken.sol";
|
|
7
7
|
import "../../interfaces/IPYieldToken.sol";
|
|
8
|
-
import "../../interfaces/
|
|
8
|
+
import "../../interfaces/IPActionCore.sol";
|
|
9
9
|
import "../../libraries/math/MarketMathAux.sol";
|
|
10
10
|
|
|
11
|
-
contract
|
|
12
|
-
IPRouterCore,
|
|
13
|
-
PendleRouterSCYAndForgeBaseUpg,
|
|
14
|
-
PendleRouterOTBaseUpg
|
|
15
|
-
{
|
|
11
|
+
contract ActionCore is IPActionCore, ActionSCYAndOTBase, ActionSCYAndYOBase {
|
|
16
12
|
using MarketMathCore for MarketState;
|
|
17
13
|
using MarketMathAux for MarketState;
|
|
18
14
|
using Math for uint256;
|
|
@@ -24,8 +20,8 @@ contract PendleRouterCoreUpg is
|
|
|
24
20
|
address _joeFactory,
|
|
25
21
|
address _marketFactory
|
|
26
22
|
)
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
ActionSCYAndYOBase(_joeRouter, _joeFactory)
|
|
24
|
+
ActionSCYAndOTBase()
|
|
29
25
|
//solhint-disable-next-line no-empty-blocks
|
|
30
26
|
{
|
|
31
27
|
|
|
@@ -1,27 +1,22 @@
|
|
|
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/PendleRouterYTBaseUpg.sol";
|
|
4
|
+
import "./base/ActionSCYAndYTBase.sol";
|
|
6
5
|
import "../../interfaces/IPOwnershipToken.sol";
|
|
7
6
|
import "../../interfaces/IPYieldToken.sol";
|
|
8
|
-
import "../../interfaces/
|
|
7
|
+
import "../../interfaces/IPActionYT.sol";
|
|
9
8
|
import "../../libraries/math/MarketMathAux.sol";
|
|
10
9
|
|
|
11
|
-
contract
|
|
10
|
+
contract ActionYT is IPActionYT, ActionSCYAndYTBase {
|
|
12
11
|
using MarketMathCore for MarketState;
|
|
13
12
|
using MarketMathAux for MarketState;
|
|
14
13
|
using Math for uint256;
|
|
15
14
|
using Math for int256;
|
|
16
15
|
|
|
17
16
|
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
18
|
-
constructor(
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
address _marketFactory
|
|
22
|
-
)
|
|
23
|
-
PendleRouterSCYAndForgeBaseUpg(_joeRouter, _joeFactory)
|
|
24
|
-
PendleRouterYTBaseUpg(_marketFactory)
|
|
17
|
+
constructor(address _joeRouter, address _joeFactory)
|
|
18
|
+
ActionSCYAndYOBase(_joeRouter, _joeFactory)
|
|
19
|
+
ActionSCYAndYTBase()
|
|
25
20
|
//solhint-disable-next-line no-empty-blocks
|
|
26
21
|
{
|
|
27
22
|
|
package/contracts/core/{router/base/PendleRouterOTBaseUpg.sol → actions/base/ActionSCYAndOTBase.sol}
RENAMED
|
@@ -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 ActionSCYAndOTBase {
|
|
13
13
|
using Math for uint256;
|
|
14
14
|
using Math for int256;
|
|
15
15
|
using MarketMathCore for MarketState;
|
|
@@ -18,10 +18,6 @@ abstract contract PendleRouterOTBaseUpg {
|
|
|
18
18
|
using SafeERC20 for IERC20;
|
|
19
19
|
|
|
20
20
|
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
21
|
-
constructor() //solhint-disable-next-line no-empty-blocks
|
|
22
|
-
{
|
|
23
|
-
|
|
24
|
-
}
|
|
25
21
|
|
|
26
22
|
/**
|
|
27
23
|
* @notice addLiquidity to the market, using both SCY & OT, the receiver will receive LP before
|
|
@@ -6,16 +6,14 @@ import "../../../periphery/PendleJoeSwapHelperUpg.sol";
|
|
|
6
6
|
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
11
|
using SafeERC20 for IERC20;
|
|
11
12
|
|
|
12
13
|
/// @dev since this contract will be proxied, it must not contains non-immutable variables
|
|
13
14
|
constructor(address _joeRouter, address _joeFactory)
|
|
14
15
|
PendleJoeSwapHelperUpg(_joeRouter, _joeFactory)
|
|
15
|
-
|
|
16
|
-
{
|
|
17
|
-
|
|
18
|
-
}
|
|
16
|
+
{}
|
|
19
17
|
|
|
20
18
|
/**
|
|
21
19
|
* @notice swap rawToken to baseToken -> baseToken to mint SCY
|