@pendle/core-v2 0.5.1-beta-5 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +51 -51
- 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 +19 -19
- 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/IPRouterStatic.ts +480 -0
- package/typechain-types/RouterStatic.ts +484 -4
- package/typechain-types/factories/IPRouterStatic__factory.ts +616 -0
- package/typechain-types/factories/PendleRouter__factory.ts +1 -1
- package/typechain-types/factories/RouterStatic__factory.ts +619 -3
- package/typechain-types/ActionSCYAndYOBase.ts +0 -223
- package/typechain-types/PendleRouterRedeemUpg.ts +0 -125
- package/typechain-types/factories/ActionSCYAndYOBase__factory.ts +0 -200
- package/typechain-types/factories/PendleRouterRedeemUpg__factory.ts +0 -112
|
@@ -19,6 +19,8 @@ abstract contract RewardManager is IRewardManager {
|
|
|
19
19
|
uint256 accruedReward;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
uint256 public lastRewardUpdateBlock;
|
|
23
|
+
|
|
22
24
|
uint256 internal constant INITIAL_REWARD_INDEX = 1;
|
|
23
25
|
|
|
24
26
|
mapping(address => GlobalReward) internal globalReward;
|
|
@@ -66,22 +68,18 @@ abstract contract RewardManager is IRewardManager {
|
|
|
66
68
|
}
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
function _updateUserReward(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
uint256 totalSupply
|
|
73
|
-
) internal virtual {
|
|
74
|
-
address[] memory rewardTokens = getRewardTokens();
|
|
75
|
-
_updateGlobalReward(rewardTokens, totalSupply);
|
|
76
|
-
_updateUserRewardSkipGlobal(rewardTokens, user, balanceOfUser);
|
|
71
|
+
function _updateUserReward(address user) internal virtual {
|
|
72
|
+
_updateGlobalReward();
|
|
73
|
+
_updateUserRewardSkipGlobal(user);
|
|
77
74
|
}
|
|
78
75
|
|
|
79
|
-
function _updateGlobalReward(
|
|
80
|
-
|
|
81
|
-
virtual
|
|
82
|
-
{
|
|
76
|
+
function _updateGlobalReward() internal virtual {
|
|
77
|
+
if (!_shouldUpdateGlobalReward()) return;
|
|
83
78
|
_redeemExternalReward();
|
|
84
79
|
|
|
80
|
+
uint256 totalShares = _rewardSharesTotal();
|
|
81
|
+
|
|
82
|
+
address[] memory rewardTokens = getRewardTokens();
|
|
85
83
|
_initGlobalReward(rewardTokens);
|
|
86
84
|
|
|
87
85
|
for (uint256 i = 0; i < rewardTokens.length; ++i) {
|
|
@@ -89,20 +87,20 @@ abstract contract RewardManager is IRewardManager {
|
|
|
89
87
|
|
|
90
88
|
uint256 currentRewardBalance = IERC20(token).balanceOf(address(this));
|
|
91
89
|
|
|
92
|
-
if (
|
|
90
|
+
if (totalShares != 0) {
|
|
93
91
|
globalReward[token].index += (currentRewardBalance -
|
|
94
|
-
globalReward[token].lastBalance).divDown(
|
|
92
|
+
globalReward[token].lastBalance).divDown(totalShares);
|
|
95
93
|
}
|
|
96
94
|
|
|
97
95
|
globalReward[token].lastBalance = currentRewardBalance;
|
|
98
96
|
}
|
|
99
97
|
}
|
|
100
98
|
|
|
101
|
-
function _updateUserRewardSkipGlobal(
|
|
102
|
-
address[] memory rewardTokens
|
|
103
|
-
|
|
104
|
-
uint256
|
|
105
|
-
|
|
99
|
+
function _updateUserRewardSkipGlobal(address user) internal virtual {
|
|
100
|
+
address[] memory rewardTokens = getRewardTokens();
|
|
101
|
+
|
|
102
|
+
uint256 userShares = _rewardSharesUser(user);
|
|
103
|
+
|
|
106
104
|
for (uint256 i = 0; i < rewardTokens.length; ++i) {
|
|
107
105
|
address token = rewardTokens[i];
|
|
108
106
|
|
|
@@ -117,7 +115,7 @@ abstract contract RewardManager is IRewardManager {
|
|
|
117
115
|
}
|
|
118
116
|
|
|
119
117
|
uint256 rewardAmountPerUnit = globalReward[token].index - userLastIndex;
|
|
120
|
-
uint256 rewardFromUnit =
|
|
118
|
+
uint256 rewardFromUnit = userShares.mulDown(rewardAmountPerUnit);
|
|
121
119
|
|
|
122
120
|
userReward[user][token].accruedReward += rewardFromUnit;
|
|
123
121
|
userReward[user][token].lastIndex = globalReward[token].index;
|
|
@@ -132,5 +130,22 @@ abstract contract RewardManager is IRewardManager {
|
|
|
132
130
|
}
|
|
133
131
|
}
|
|
134
132
|
|
|
133
|
+
function _shouldUpdateGlobalReward() internal virtual returns (bool) {
|
|
134
|
+
if (lastRewardUpdateBlock == block.number) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
lastRewardUpdateBlock = block.number;
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/// @dev to be overriden if there is rewards
|
|
135
142
|
function _redeemExternalReward() internal virtual;
|
|
143
|
+
|
|
144
|
+
/// @dev to be overriden if there is rewards
|
|
145
|
+
function _rewardSharesTotal() internal virtual returns (uint256);
|
|
146
|
+
|
|
147
|
+
/// @dev to be overriden if there is rewards
|
|
148
|
+
function _rewardSharesUser(
|
|
149
|
+
address /*user*/
|
|
150
|
+
) internal virtual returns (uint256);
|
|
136
151
|
}
|
|
@@ -4,21 +4,19 @@ import "../ISuperComposableYield.sol";
|
|
|
4
4
|
import "./RewardManager.sol";
|
|
5
5
|
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
|
6
6
|
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
7
|
+
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
|
|
7
8
|
import "../../libraries/math/Math.sol";
|
|
8
9
|
import "../SCYUtils.sol";
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
# CONDITIONS TO USE THIS PRESET:
|
|
12
|
-
- the token's balance must be static (i.e not increase on its own). Some examples of tokens don't
|
|
13
|
-
satisfy this restriction is AaveV2's aToken
|
|
14
|
-
|
|
15
|
-
*/
|
|
16
|
-
abstract contract SCYBase is ERC20, ISuperComposableYield {
|
|
11
|
+
abstract contract SCYBase is ERC20, ISuperComposableYield, ReentrancyGuard {
|
|
17
12
|
using SafeERC20 for IERC20;
|
|
18
13
|
using Math for uint256;
|
|
19
14
|
|
|
15
|
+
event UpdateScyIndex(uint256 scyIndex);
|
|
16
|
+
|
|
20
17
|
uint8 private immutable _scyDecimals;
|
|
21
18
|
uint8 private immutable _assetDecimals;
|
|
19
|
+
bytes32 private immutable _assetId;
|
|
22
20
|
|
|
23
21
|
mapping(address => uint256) internal lastBalanceOf;
|
|
24
22
|
|
|
@@ -26,10 +24,12 @@ abstract contract SCYBase is ERC20, ISuperComposableYield {
|
|
|
26
24
|
string memory _name,
|
|
27
25
|
string memory _symbol,
|
|
28
26
|
uint8 __scyDecimals,
|
|
29
|
-
uint8 __assetDecimals
|
|
27
|
+
uint8 __assetDecimals,
|
|
28
|
+
bytes32 __assetId
|
|
30
29
|
) ERC20(_name, _symbol) {
|
|
31
30
|
_scyDecimals = __scyDecimals;
|
|
32
31
|
_assetDecimals = __assetDecimals;
|
|
32
|
+
_assetId = __assetId;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/*///////////////////////////////////////////////////////////////
|
|
@@ -41,9 +41,9 @@ abstract contract SCYBase is ERC20, ISuperComposableYield {
|
|
|
41
41
|
address baseTokenIn,
|
|
42
42
|
uint256 amountBaseToPull,
|
|
43
43
|
uint256 minAmountScyOut
|
|
44
|
-
) external returns (uint256 amountScyOut) {
|
|
44
|
+
) external nonReentrant returns (uint256 amountScyOut) {
|
|
45
45
|
IERC20(baseTokenIn).safeTransferFrom(msg.sender, address(this), amountBaseToPull);
|
|
46
|
-
amountScyOut =
|
|
46
|
+
amountScyOut = _mintFresh(receiver, baseTokenIn, minAmountScyOut);
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
function redeem(
|
|
@@ -51,16 +51,32 @@ abstract contract SCYBase is ERC20, ISuperComposableYield {
|
|
|
51
51
|
address baseTokenOut,
|
|
52
52
|
uint256 amountScyToPull,
|
|
53
53
|
uint256 minAmountBaseOut
|
|
54
|
-
) external returns (uint256 amountBaseOut) {
|
|
54
|
+
) external nonReentrant returns (uint256 amountBaseOut) {
|
|
55
55
|
transferFrom(msg.sender, address(this), amountScyToPull);
|
|
56
|
-
amountBaseOut =
|
|
56
|
+
amountBaseOut = _redeemFresh(receiver, baseTokenOut, minAmountBaseOut);
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
function mintNoPull(
|
|
60
60
|
address receiver,
|
|
61
61
|
address baseTokenIn,
|
|
62
62
|
uint256 minAmountScyOut
|
|
63
|
-
)
|
|
63
|
+
) external virtual override nonReentrant returns (uint256) {
|
|
64
|
+
return _mintFresh(receiver, baseTokenIn, minAmountScyOut);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function redeemNoPull(
|
|
68
|
+
address receiver,
|
|
69
|
+
address baseTokenOut,
|
|
70
|
+
uint256 minAmountBaseOut
|
|
71
|
+
) external virtual override nonReentrant returns (uint256) {
|
|
72
|
+
return _redeemFresh(receiver, baseTokenOut, minAmountBaseOut);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function _mintFresh(
|
|
76
|
+
address receiver,
|
|
77
|
+
address baseTokenIn,
|
|
78
|
+
uint256 minAmountScyOut
|
|
79
|
+
) internal virtual returns (uint256 amountScyOut) {
|
|
64
80
|
require(isValidBaseToken(baseTokenIn), "invalid base token");
|
|
65
81
|
|
|
66
82
|
uint256 amountBaseIn = _afterReceiveToken(baseTokenIn);
|
|
@@ -72,11 +88,11 @@ abstract contract SCYBase is ERC20, ISuperComposableYield {
|
|
|
72
88
|
_mint(receiver, amountScyOut);
|
|
73
89
|
}
|
|
74
90
|
|
|
75
|
-
function
|
|
91
|
+
function _redeemFresh(
|
|
76
92
|
address receiver,
|
|
77
93
|
address baseTokenOut,
|
|
78
94
|
uint256 minAmountBaseOut
|
|
79
|
-
)
|
|
95
|
+
) internal virtual returns (uint256 amountBaseOut) {
|
|
80
96
|
require(isValidBaseToken(baseTokenOut), "invalid base token");
|
|
81
97
|
|
|
82
98
|
uint256 amountScyRedeem = balanceOf(address(this));
|
|
@@ -105,9 +121,9 @@ abstract contract SCYBase is ERC20, ISuperComposableYield {
|
|
|
105
121
|
SCY-INDEX
|
|
106
122
|
//////////////////////////////////////////////////////////////*/
|
|
107
123
|
|
|
108
|
-
function scyIndexCurrent()
|
|
124
|
+
function scyIndexCurrent() external virtual override returns (uint256 res);
|
|
109
125
|
|
|
110
|
-
function scyIndexStored()
|
|
126
|
+
function scyIndexStored() external view virtual override returns (uint256 res);
|
|
111
127
|
|
|
112
128
|
/*///////////////////////////////////////////////////////////////
|
|
113
129
|
MISC METADATA FUNCTIONS
|
|
@@ -117,11 +133,15 @@ abstract contract SCYBase is ERC20, ISuperComposableYield {
|
|
|
117
133
|
return _scyDecimals;
|
|
118
134
|
}
|
|
119
135
|
|
|
120
|
-
function assetDecimals()
|
|
136
|
+
function assetDecimals() external view virtual returns (uint8) {
|
|
121
137
|
return _assetDecimals;
|
|
122
138
|
}
|
|
123
139
|
|
|
124
|
-
function
|
|
140
|
+
function assetId() external view returns (bytes32) {
|
|
141
|
+
return _assetId;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function getBaseTokens() external view virtual override returns (address[] memory res);
|
|
125
145
|
|
|
126
146
|
function isValidBaseToken(address token) public view virtual override returns (bool);
|
|
127
147
|
|
|
@@ -17,14 +17,16 @@ abstract contract SCYBaseWithRewards is SCYBase, RewardManager {
|
|
|
17
17
|
using SafeERC20 for IERC20;
|
|
18
18
|
using Math for uint256;
|
|
19
19
|
|
|
20
|
+
event RedeemReward(address indexed user, uint256[] rewardsOut);
|
|
21
|
+
|
|
20
22
|
constructor(
|
|
21
23
|
string memory _name,
|
|
22
24
|
string memory _symbol,
|
|
23
25
|
uint8 __scydecimals,
|
|
24
|
-
uint8 __assetDecimals
|
|
26
|
+
uint8 __assetDecimals,
|
|
27
|
+
bytes32 __assetId
|
|
25
28
|
)
|
|
26
|
-
SCYBase(_name, _symbol, __scydecimals, __assetDecimals)
|
|
27
|
-
RewardManager()
|
|
29
|
+
SCYBase(_name, _symbol, __scydecimals, __assetDecimals, __assetId)
|
|
28
30
|
// solhint-disable-next-line no-empty-blocks
|
|
29
31
|
{
|
|
30
32
|
|
|
@@ -35,22 +37,23 @@ abstract contract SCYBaseWithRewards is SCYBase, RewardManager {
|
|
|
35
37
|
//////////////////////////////////////////////////////////////*/
|
|
36
38
|
|
|
37
39
|
function redeemReward(address user)
|
|
38
|
-
|
|
40
|
+
external
|
|
39
41
|
virtual
|
|
40
42
|
override
|
|
43
|
+
nonReentrant
|
|
41
44
|
returns (uint256[] memory outAmounts)
|
|
42
45
|
{
|
|
43
|
-
_updateUserReward(user
|
|
46
|
+
_updateUserReward(user);
|
|
44
47
|
outAmounts = _doTransferOutRewardsForUser(user, user);
|
|
48
|
+
emit RedeemReward(user, outAmounts);
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
function updateGlobalReward()
|
|
48
|
-
|
|
49
|
-
_updateGlobalReward(rewardTokens, totalSupply());
|
|
51
|
+
function updateGlobalReward() external virtual override nonReentrant {
|
|
52
|
+
_updateGlobalReward();
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
function updateUserReward(address user)
|
|
53
|
-
_updateUserReward(user
|
|
55
|
+
function updateUserReward(address user) external virtual override nonReentrant {
|
|
56
|
+
_updateUserReward(user);
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
function getRewardTokens()
|
|
@@ -68,9 +71,18 @@ abstract contract SCYBaseWithRewards is SCYBase, RewardManager {
|
|
|
68
71
|
address to,
|
|
69
72
|
uint256 /*amount*/
|
|
70
73
|
) internal virtual override {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
|
|
74
|
+
_updateGlobalReward();
|
|
75
|
+
if (from != address(0)) _updateUserRewardSkipGlobal(from);
|
|
76
|
+
if (to != address(0)) _updateUserRewardSkipGlobal(to);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/// @dev to be overriden if there is rewards
|
|
80
|
+
function _rewardSharesTotal() internal virtual override returns (uint256) {
|
|
81
|
+
return totalSupply();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/// @dev to be overriden if there is rewards
|
|
85
|
+
function _rewardSharesUser(address user) internal virtual override returns (uint256) {
|
|
86
|
+
return balanceOf(user);
|
|
75
87
|
}
|
|
76
88
|
}
|
|
@@ -29,7 +29,7 @@ abstract contract PendleBaseToken is ERC20, IPBaseToken {
|
|
|
29
29
|
return _decimals;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
function isExpired() public view virtual returns (bool
|
|
33
|
-
|
|
32
|
+
function isExpired() public view virtual returns (bool) {
|
|
33
|
+
return block.timestamp >= expiry;
|
|
34
34
|
}
|
|
35
35
|
}
|