@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
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
|
-
pragma abicoder v2;
|
|
4
3
|
import "../../../SuperComposableYield/implementations/SCYBaseWithRewards.sol";
|
|
5
4
|
import "../../../interfaces/IAToken.sol";
|
|
6
5
|
import "../../../interfaces/IAavePool.sol";
|
|
@@ -8,6 +7,7 @@ import "../../../interfaces/IAaveRewardsController.sol";
|
|
|
8
7
|
import "./WadRayMath.sol";
|
|
9
8
|
|
|
10
9
|
contract PendleAaveV3SCY is SCYBaseWithRewards {
|
|
10
|
+
using Math for uint256;
|
|
11
11
|
using WadRayMath for uint256;
|
|
12
12
|
using SafeERC20 for IERC20;
|
|
13
13
|
|
|
@@ -17,24 +17,24 @@ contract PendleAaveV3SCY is SCYBaseWithRewards {
|
|
|
17
17
|
address public immutable aToken;
|
|
18
18
|
|
|
19
19
|
uint256 public lastScyIndex;
|
|
20
|
+
uint256 public constant PRECISION_INDEX = 1e9;
|
|
20
21
|
|
|
21
|
-
// WIP: Aave reward controller can config to have more rewardsToken,
|
|
22
|
-
// hence rewardsLength should not be immutable
|
|
23
22
|
constructor(
|
|
24
23
|
string memory _name,
|
|
25
24
|
string memory _symbol,
|
|
26
25
|
uint8 __scydecimals,
|
|
27
26
|
uint8 __assetDecimals,
|
|
27
|
+
bytes32 __assetId,
|
|
28
28
|
address _aavePool,
|
|
29
29
|
address _underlying,
|
|
30
30
|
address _aToken,
|
|
31
31
|
address _rewardsController
|
|
32
|
-
) SCYBaseWithRewards(_name, _symbol, __scydecimals, __assetDecimals) {
|
|
32
|
+
) SCYBaseWithRewards(_name, _symbol, __scydecimals, __assetDecimals, __assetId) {
|
|
33
33
|
aToken = _aToken;
|
|
34
34
|
pool = _aavePool;
|
|
35
35
|
underlying = _underlying;
|
|
36
36
|
rewardsController = _rewardsController;
|
|
37
|
-
IERC20(underlying).safeIncreaseAllowance(
|
|
37
|
+
IERC20(underlying).safeIncreaseAllowance(pool, type(uint256).max);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/*///////////////////////////////////////////////////////////////
|
|
@@ -49,7 +49,7 @@ contract PendleAaveV3SCY is SCYBaseWithRewards {
|
|
|
49
49
|
{
|
|
50
50
|
// aTokenScaled -> scy is 1:1
|
|
51
51
|
if (token == aToken) {
|
|
52
|
-
amountScyOut = amountBase
|
|
52
|
+
amountScyOut = amountBase;
|
|
53
53
|
} else {
|
|
54
54
|
IAavePool(pool).supply(underlying, amountBase, address(this), 0);
|
|
55
55
|
_afterSendToken(underlying);
|
|
@@ -64,9 +64,9 @@ contract PendleAaveV3SCY is SCYBaseWithRewards {
|
|
|
64
64
|
returns (uint256 amountBaseOut)
|
|
65
65
|
{
|
|
66
66
|
if (token == aToken) {
|
|
67
|
-
amountBaseOut = amountScy.rayMul(
|
|
67
|
+
amountBaseOut = amountScy.rayMul(aaveIndexCurrent());
|
|
68
68
|
} else {
|
|
69
|
-
uint256 amountBaseExpected = amountScy.rayMul(
|
|
69
|
+
uint256 amountBaseExpected = amountScy.rayMul(aaveIndexCurrent());
|
|
70
70
|
IAavePool(pool).withdraw(underlying, amountBaseExpected, address(this));
|
|
71
71
|
_afterSendToken(aToken);
|
|
72
72
|
amountBaseOut = _afterReceiveToken(token);
|
|
@@ -78,9 +78,14 @@ contract PendleAaveV3SCY is SCYBaseWithRewards {
|
|
|
78
78
|
//////////////////////////////////////////////////////////////*/
|
|
79
79
|
|
|
80
80
|
function scyIndexCurrent() public virtual override returns (uint256 res) {
|
|
81
|
+
aaveIndexCurrent();
|
|
82
|
+
res = lastScyIndex;
|
|
83
|
+
emit UpdateScyIndex(lastScyIndex);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function aaveIndexCurrent() public returns (uint256 res) {
|
|
81
87
|
res = IAavePool(pool).getReserveNormalizedIncome(underlying);
|
|
82
|
-
lastScyIndex = res;
|
|
83
|
-
return res;
|
|
88
|
+
lastScyIndex = res / PRECISION_INDEX;
|
|
84
89
|
}
|
|
85
90
|
|
|
86
91
|
function scyIndexStored() public view override returns (uint256 res) {
|
|
@@ -88,7 +93,7 @@ contract PendleAaveV3SCY is SCYBaseWithRewards {
|
|
|
88
93
|
}
|
|
89
94
|
|
|
90
95
|
function getRewardTokens() public view override returns (address[] memory res) {
|
|
91
|
-
|
|
96
|
+
res = IAaveRewardsController(rewardsController).getRewardsByAsset(aToken);
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
/*///////////////////////////////////////////////////////////////
|
|
@@ -118,15 +123,11 @@ contract PendleAaveV3SCY is SCYBaseWithRewards {
|
|
|
118
123
|
|
|
119
124
|
/// @dev balance of aToken is saved by scaledBalanceOf instead
|
|
120
125
|
function _afterReceiveToken(address token) internal virtual override returns (uint256 res) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
uint256 curBalance = IERC20(token).balanceOf(address(this));
|
|
127
|
-
res = curBalance - lastBalanceOf[token];
|
|
128
|
-
lastBalanceOf[token] = curBalance;
|
|
129
|
-
}
|
|
126
|
+
uint256 curBalance = (token == aToken)
|
|
127
|
+
? IAToken(aToken).scaledBalanceOf(address(this))
|
|
128
|
+
: IERC20(token).balanceOf(address(this));
|
|
129
|
+
res = curBalance - lastBalanceOf[token];
|
|
130
|
+
lastBalanceOf[token] = curBalance;
|
|
130
131
|
}
|
|
131
132
|
|
|
132
133
|
function _afterSendToken(address token) internal virtual override {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import "../../SuperComposableYield/implementations/SCYBaseWithRewards.sol";
|
|
5
5
|
import "../../interfaces/IQiErc20.sol";
|
|
6
6
|
import "../../interfaces/IBenQiComptroller.sol";
|
|
@@ -15,24 +15,32 @@ contract PendleBenQiErc20SCY is SCYBaseWithRewards {
|
|
|
15
15
|
address public immutable comptroller;
|
|
16
16
|
address public immutable qiToken;
|
|
17
17
|
|
|
18
|
-
uint256 public
|
|
18
|
+
uint256 public override scyIndexStored;
|
|
19
19
|
|
|
20
20
|
constructor(
|
|
21
21
|
string memory _name,
|
|
22
22
|
string memory _symbol,
|
|
23
23
|
uint8 __scydecimals,
|
|
24
24
|
uint8 __assetDecimals,
|
|
25
|
+
bytes32 __assetId,
|
|
25
26
|
address _underlying,
|
|
26
27
|
address _qiToken,
|
|
27
28
|
address _comptroller,
|
|
28
29
|
address _QI,
|
|
29
30
|
address _WAVAX
|
|
30
|
-
) SCYBaseWithRewards(_name, _symbol, __scydecimals, __assetDecimals) {
|
|
31
|
-
|
|
31
|
+
) SCYBaseWithRewards(_name, _symbol, __scydecimals, __assetDecimals, __assetId) {
|
|
32
|
+
require(
|
|
33
|
+
_qiToken != address(0) &&
|
|
34
|
+
_QI != address(0) &&
|
|
35
|
+
_WAVAX != address(0) &&
|
|
36
|
+
_comptroller != address(0),
|
|
37
|
+
"zero address"
|
|
38
|
+
);
|
|
32
39
|
qiToken = _qiToken;
|
|
33
40
|
QI = _QI;
|
|
34
41
|
WAVAX = _WAVAX;
|
|
35
42
|
comptroller = _comptroller;
|
|
43
|
+
underlying = _underlying;
|
|
36
44
|
IERC20(underlying).safeIncreaseAllowance(qiToken, type(uint256).max);
|
|
37
45
|
}
|
|
38
46
|
|
|
@@ -53,7 +61,8 @@ contract PendleBenQiErc20SCY is SCYBaseWithRewards {
|
|
|
53
61
|
if (token == qiToken) {
|
|
54
62
|
amountScyOut = amountBase;
|
|
55
63
|
} else {
|
|
56
|
-
IQiErc20(qiToken).mint(amountBase);
|
|
64
|
+
uint256 errCode = IQiErc20(qiToken).mint(amountBase);
|
|
65
|
+
require(errCode == 0, "mint failed");
|
|
57
66
|
_afterSendToken(underlying);
|
|
58
67
|
amountScyOut = _afterReceiveToken(qiToken);
|
|
59
68
|
}
|
|
@@ -69,7 +78,8 @@ contract PendleBenQiErc20SCY is SCYBaseWithRewards {
|
|
|
69
78
|
amountBaseOut = amountScy;
|
|
70
79
|
} else {
|
|
71
80
|
// must be underlying
|
|
72
|
-
IQiErc20(qiToken).redeem(amountScy);
|
|
81
|
+
uint256 errCode = IQiErc20(qiToken).redeem(amountScy);
|
|
82
|
+
require(errCode == 0, "redeem failed");
|
|
73
83
|
_afterSendToken(qiToken);
|
|
74
84
|
amountBaseOut = _afterReceiveToken(underlying);
|
|
75
85
|
}
|
|
@@ -79,14 +89,10 @@ contract PendleBenQiErc20SCY is SCYBaseWithRewards {
|
|
|
79
89
|
SCY-INDEX
|
|
80
90
|
//////////////////////////////////////////////////////////////*/
|
|
81
91
|
|
|
82
|
-
function scyIndexCurrent() public virtual override returns (uint256
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function scyIndexStored() public view override returns (uint256 res) {
|
|
89
|
-
res = lastScyIndex;
|
|
92
|
+
function scyIndexCurrent() public virtual override returns (uint256) {
|
|
93
|
+
scyIndexStored = IQiToken(qiToken).exchangeRateCurrent();
|
|
94
|
+
emit UpdateScyIndex(scyIndexStored);
|
|
95
|
+
return scyIndexStored;
|
|
90
96
|
}
|
|
91
97
|
|
|
92
98
|
function getRewardTokens() public view override returns (address[] memory res) {
|
|
@@ -105,8 +111,8 @@ contract PendleBenQiErc20SCY is SCYBaseWithRewards {
|
|
|
105
111
|
res[1] = underlying;
|
|
106
112
|
}
|
|
107
113
|
|
|
108
|
-
function isValidBaseToken(address token) public view virtual override returns (bool
|
|
109
|
-
|
|
114
|
+
function isValidBaseToken(address token) public view virtual override returns (bool) {
|
|
115
|
+
return token == underlying || token == qiToken;
|
|
110
116
|
}
|
|
111
117
|
|
|
112
118
|
/*///////////////////////////////////////////////////////////////
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import "../../SuperComposableYield/implementations/SCYBase.sol";
|
|
5
5
|
import "../../interfaces/IWXBTRFLY.sol";
|
|
6
6
|
import "../../interfaces/IREDACTEDStaking.sol";
|
|
@@ -12,17 +12,19 @@ contract PendleBtrflyScy is SCYBase {
|
|
|
12
12
|
address public immutable xBTRFLY;
|
|
13
13
|
address public immutable wxBTRFLY;
|
|
14
14
|
|
|
15
|
-
uint256 public
|
|
15
|
+
uint256 public override scyIndexStored;
|
|
16
16
|
|
|
17
17
|
constructor(
|
|
18
18
|
string memory _name,
|
|
19
19
|
string memory _symbol,
|
|
20
20
|
uint8 __scydecimals,
|
|
21
21
|
uint8 __assetDecimals,
|
|
22
|
+
bytes32 __assetId,
|
|
22
23
|
address _BTRFLY,
|
|
23
24
|
address _xBTRFLY,
|
|
24
25
|
address _wxBTRFLY
|
|
25
|
-
) SCYBase(_name, _symbol, __scydecimals, __assetDecimals) {
|
|
26
|
+
) SCYBase(_name, _symbol, __scydecimals, __assetDecimals, __assetId) {
|
|
27
|
+
require(_wxBTRFLY != address(0), "zero address");
|
|
26
28
|
BTRFLY = _BTRFLY;
|
|
27
29
|
xBTRFLY = _xBTRFLY;
|
|
28
30
|
wxBTRFLY = _wxBTRFLY;
|
|
@@ -42,9 +44,11 @@ contract PendleBtrflyScy is SCYBase {
|
|
|
42
44
|
if (token == BTRFLY) {
|
|
43
45
|
amountScyOut = IWXBTRFLY(wxBTRFLY).wrapFromBTRFLY(amountBase);
|
|
44
46
|
_afterSendToken(BTRFLY);
|
|
47
|
+
_afterReceiveToken(wxBTRFLY);
|
|
45
48
|
} else if (token == xBTRFLY) {
|
|
46
49
|
amountScyOut = IWXBTRFLY(wxBTRFLY).wrapFromxBTRFLY(amountBase);
|
|
47
50
|
_afterSendToken(xBTRFLY);
|
|
51
|
+
_afterReceiveToken(wxBTRFLY);
|
|
48
52
|
} else {
|
|
49
53
|
// 1 wxBTRFLY = 1 SCY
|
|
50
54
|
amountScyOut = amountBase;
|
|
@@ -73,14 +77,10 @@ contract PendleBtrflyScy is SCYBase {
|
|
|
73
77
|
SCY-INDEX
|
|
74
78
|
//////////////////////////////////////////////////////////////*/
|
|
75
79
|
|
|
76
|
-
function scyIndexCurrent() public virtual override returns (uint256
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function scyIndexStored() public view override returns (uint256 res) {
|
|
83
|
-
res = lastScyIndex;
|
|
80
|
+
function scyIndexCurrent() public virtual override returns (uint256) {
|
|
81
|
+
scyIndexStored = IWXBTRFLY(wxBTRFLY).xBTRFLYValue(Math.ONE);
|
|
82
|
+
emit UpdateScyIndex(scyIndexStored);
|
|
83
|
+
return scyIndexStored;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
/*///////////////////////////////////////////////////////////////
|
|
@@ -94,8 +94,8 @@ contract PendleBtrflyScy is SCYBase {
|
|
|
94
94
|
res[2] = wxBTRFLY;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
function isValidBaseToken(address token) public view virtual override returns (bool
|
|
98
|
-
|
|
97
|
+
function isValidBaseToken(address token) public view virtual override returns (bool) {
|
|
98
|
+
return token == BTRFLY || token == xBTRFLY || token == wxBTRFLY;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
/*///////////////////////////////////////////////////////////////
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
|
+
pragma solidity 0.8.9;
|
|
3
|
+
import "../../SuperComposableYield/implementations/SCYBase.sol";
|
|
4
|
+
import "../../interfaces/IWstETH.sol";
|
|
5
|
+
|
|
6
|
+
contract PendleStEthSCY is SCYBase {
|
|
7
|
+
using SafeERC20 for IERC20;
|
|
8
|
+
|
|
9
|
+
address public immutable stETH;
|
|
10
|
+
address public immutable wstETH;
|
|
11
|
+
|
|
12
|
+
uint256 public override scyIndexStored;
|
|
13
|
+
|
|
14
|
+
constructor(
|
|
15
|
+
string memory _name,
|
|
16
|
+
string memory _symbol,
|
|
17
|
+
uint8 __scydecimals,
|
|
18
|
+
uint8 __assetDecimals,
|
|
19
|
+
address _stETH,
|
|
20
|
+
address _wstETH,
|
|
21
|
+
bytes32 __assetId
|
|
22
|
+
) SCYBase(_name, _symbol, __scydecimals, __assetDecimals, __assetId) {
|
|
23
|
+
require(_wstETH != address(0), "zero address");
|
|
24
|
+
stETH = _stETH;
|
|
25
|
+
wstETH = _wstETH;
|
|
26
|
+
IERC20(stETH).safeIncreaseAllowance(wstETH, type(uint256).max);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/*///////////////////////////////////////////////////////////////
|
|
30
|
+
DEPOSIT/REDEEM USING BASE TOKENS
|
|
31
|
+
//////////////////////////////////////////////////////////////*/
|
|
32
|
+
function _deposit(address token, uint256 amountBase)
|
|
33
|
+
internal
|
|
34
|
+
virtual
|
|
35
|
+
override
|
|
36
|
+
returns (uint256 amountScyOut)
|
|
37
|
+
{
|
|
38
|
+
if (token == stETH) {
|
|
39
|
+
amountScyOut = IWstETH(wstETH).wrap(amountBase);
|
|
40
|
+
_afterSendToken(stETH);
|
|
41
|
+
_afterReceiveToken(wstETH);
|
|
42
|
+
} else {
|
|
43
|
+
// 1 wstETH = 1 SCY
|
|
44
|
+
amountScyOut = amountBase;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function _redeem(address token, uint256 amountScy)
|
|
49
|
+
internal
|
|
50
|
+
virtual
|
|
51
|
+
override
|
|
52
|
+
returns (uint256 amountBaseOut)
|
|
53
|
+
{
|
|
54
|
+
if (token == stETH) {
|
|
55
|
+
amountBaseOut = IWstETH(wstETH).unwrap(amountScy);
|
|
56
|
+
_afterSendToken(wstETH);
|
|
57
|
+
_afterReceiveToken(stETH);
|
|
58
|
+
} else {
|
|
59
|
+
// 1 wstETH = 1 SCY
|
|
60
|
+
amountBaseOut = amountScy;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/*///////////////////////////////////////////////////////////////
|
|
65
|
+
SCY-INDEX
|
|
66
|
+
//////////////////////////////////////////////////////////////*/
|
|
67
|
+
|
|
68
|
+
function scyIndexCurrent() public virtual override returns (uint256) {
|
|
69
|
+
scyIndexStored = IWstETH(wstETH).stEthPerToken();
|
|
70
|
+
emit UpdateScyIndex(scyIndexStored);
|
|
71
|
+
return scyIndexStored;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/*///////////////////////////////////////////////////////////////
|
|
75
|
+
MISC FUNCTIONS FOR METADATA
|
|
76
|
+
//////////////////////////////////////////////////////////////*/
|
|
77
|
+
|
|
78
|
+
function getBaseTokens() public view virtual override returns (address[] memory res) {
|
|
79
|
+
res = new address[](2);
|
|
80
|
+
res[0] = stETH;
|
|
81
|
+
res[1] = wstETH;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function isValidBaseToken(address token) public view virtual override returns (bool) {
|
|
85
|
+
return token == stETH || token == wstETH;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/*///////////////////////////////////////////////////////////////
|
|
89
|
+
REWARDS-RELATED
|
|
90
|
+
//////////////////////////////////////////////////////////////*/
|
|
91
|
+
|
|
92
|
+
//solhint-disable-next-line no-empty-blocks
|
|
93
|
+
function redeemReward(address user) public virtual override returns (uint256[] memory) {}
|
|
94
|
+
|
|
95
|
+
//solhint-disable-next-line no-empty-blocks
|
|
96
|
+
function updateGlobalReward() public virtual override {}
|
|
97
|
+
|
|
98
|
+
//solhint-disable-next-line no-empty-blocks
|
|
99
|
+
function updateUserReward(address user) public virtual override {}
|
|
100
|
+
|
|
101
|
+
function getRewardTokens() public view virtual returns (address[] memory res) {
|
|
102
|
+
res = new address[](0);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
//solhint-disable-next-line no-empty-blocks
|
|
106
|
+
function _redeemExternalReward() internal virtual {}
|
|
107
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
2
2
|
pragma solidity 0.8.9;
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
import "../../SuperComposableYield/implementations/SCYBase.sol";
|
|
5
5
|
import "../../interfaces/IYearnVault.sol";
|
|
6
6
|
|
|
@@ -10,16 +10,18 @@ contract PendleYearnVaultScy is SCYBase {
|
|
|
10
10
|
address public immutable underlying;
|
|
11
11
|
address public immutable yvToken;
|
|
12
12
|
|
|
13
|
-
uint256 public
|
|
13
|
+
uint256 public override scyIndexStored;
|
|
14
14
|
|
|
15
15
|
constructor(
|
|
16
16
|
string memory _name,
|
|
17
17
|
string memory _symbol,
|
|
18
18
|
uint8 __scydecimals,
|
|
19
19
|
uint8 __assetDecimals,
|
|
20
|
+
bytes32 __assetId,
|
|
20
21
|
address _underlying,
|
|
21
22
|
address _yvToken
|
|
22
|
-
) SCYBase(_name, _symbol, __scydecimals, __assetDecimals) {
|
|
23
|
+
) SCYBase(_name, _symbol, __scydecimals, __assetDecimals, __assetId) {
|
|
24
|
+
require(_yvToken != address(0), "zero address");
|
|
23
25
|
yvToken = _yvToken;
|
|
24
26
|
underlying = _underlying;
|
|
25
27
|
IERC20(underlying).safeIncreaseAllowance(yvToken, type(uint256).max);
|
|
@@ -39,7 +41,7 @@ contract PendleYearnVaultScy is SCYBase {
|
|
|
39
41
|
amountScyOut = amountBase;
|
|
40
42
|
} else {
|
|
41
43
|
// must be underlying
|
|
42
|
-
IYearnVault(yvToken).deposit(amountBase);
|
|
44
|
+
IYearnVault(yvToken).deposit(amountBase); // ignore return
|
|
43
45
|
_afterSendToken(underlying);
|
|
44
46
|
amountScyOut = _afterReceiveToken(yvToken);
|
|
45
47
|
}
|
|
@@ -55,7 +57,7 @@ contract PendleYearnVaultScy is SCYBase {
|
|
|
55
57
|
amountBaseOut = amountScy;
|
|
56
58
|
} else {
|
|
57
59
|
// must be underlying
|
|
58
|
-
IYearnVault(yvToken).withdraw(amountScy);
|
|
60
|
+
IYearnVault(yvToken).withdraw(amountScy); // ignore return
|
|
59
61
|
_afterSendToken(yvToken);
|
|
60
62
|
amountBaseOut = _afterReceiveToken(underlying);
|
|
61
63
|
}
|
|
@@ -66,13 +68,9 @@ contract PendleYearnVaultScy is SCYBase {
|
|
|
66
68
|
//////////////////////////////////////////////////////////////*/
|
|
67
69
|
|
|
68
70
|
function scyIndexCurrent() public virtual override returns (uint256 res) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function scyIndexStored() public view override returns (uint256 res) {
|
|
75
|
-
res = lastScyIndex;
|
|
71
|
+
scyIndexStored = IYearnVault(yvToken).pricePerShare();
|
|
72
|
+
emit UpdateScyIndex(scyIndexStored);
|
|
73
|
+
return scyIndexStored;
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
/*///////////////////////////////////////////////////////////////
|
|
@@ -80,12 +78,13 @@ contract PendleYearnVaultScy is SCYBase {
|
|
|
80
78
|
//////////////////////////////////////////////////////////////*/
|
|
81
79
|
|
|
82
80
|
function getBaseTokens() public view virtual override returns (address[] memory res) {
|
|
83
|
-
res = new address[](
|
|
81
|
+
res = new address[](2);
|
|
84
82
|
res[0] = underlying;
|
|
83
|
+
res[1] = yvToken;
|
|
85
84
|
}
|
|
86
85
|
|
|
87
|
-
function isValidBaseToken(address token) public view virtual override returns (bool
|
|
88
|
-
|
|
86
|
+
function isValidBaseToken(address token) public view virtual override returns (bool) {
|
|
87
|
+
return token == underlying || token == yvToken;
|
|
89
88
|
}
|
|
90
89
|
|
|
91
90
|
/*///////////////////////////////////////////////////////////////
|
|
@@ -29,13 +29,13 @@ import "../libraries/helpers/ExpiryUtilsLib.sol";
|
|
|
29
29
|
import "../periphery/PermissionsV2Upg.sol";
|
|
30
30
|
import "../interfaces/IPYieldContractFactory.sol";
|
|
31
31
|
|
|
32
|
-
import "./
|
|
32
|
+
import "./PendlePrincipalToken.sol";
|
|
33
33
|
import "./PendleYieldToken.sol";
|
|
34
34
|
|
|
35
35
|
contract PendleYieldContractFactory is PermissionsV2Upg, IPYieldContractFactory {
|
|
36
36
|
using ExpiryUtils for string;
|
|
37
37
|
|
|
38
|
-
string public constant
|
|
38
|
+
string public constant PT_PREFIX = "PT";
|
|
39
39
|
string public constant YT_PREFIX = "YT";
|
|
40
40
|
|
|
41
41
|
uint256 public expiryDivisor;
|
|
@@ -43,9 +43,9 @@ contract PendleYieldContractFactory is PermissionsV2Upg, IPYieldContractFactory
|
|
|
43
43
|
address public treasury;
|
|
44
44
|
|
|
45
45
|
// SCY => expiry => address
|
|
46
|
-
mapping(address => mapping(uint256 => address)) public
|
|
46
|
+
mapping(address => mapping(uint256 => address)) public getPT;
|
|
47
47
|
mapping(address => mapping(uint256 => address)) public getYT;
|
|
48
|
-
mapping(address => bool) public
|
|
48
|
+
mapping(address => bool) public isPT;
|
|
49
49
|
mapping(address => bool) public isYT;
|
|
50
50
|
|
|
51
51
|
constructor(
|
|
@@ -54,28 +54,36 @@ contract PendleYieldContractFactory is PermissionsV2Upg, IPYieldContractFactory
|
|
|
54
54
|
address _treasury,
|
|
55
55
|
address _governanceManager
|
|
56
56
|
) PermissionsV2Upg(_governanceManager) {
|
|
57
|
+
require(_expiryDivisor != 0, "zero value");
|
|
58
|
+
require(_treasury != address(0), "zero address");
|
|
59
|
+
|
|
57
60
|
expiryDivisor = _expiryDivisor;
|
|
58
61
|
interestFeeRate = _interestFeeRate;
|
|
59
62
|
treasury = _treasury;
|
|
60
63
|
}
|
|
61
64
|
|
|
65
|
+
/**
|
|
66
|
+
* @notice Create a pair of (PT, YT) from any SCY and valid expiry. Anyone can create a yield contract
|
|
67
|
+
*/
|
|
62
68
|
function createYieldContract(address SCY, uint256 expiry)
|
|
63
69
|
external
|
|
64
|
-
returns (address
|
|
70
|
+
returns (address PT, address YT)
|
|
65
71
|
{
|
|
72
|
+
require(expiry > block.timestamp, "invalid expiry");
|
|
73
|
+
|
|
66
74
|
require(expiry % expiryDivisor == 0, "must be multiple of divisor");
|
|
67
75
|
|
|
68
|
-
require(
|
|
76
|
+
require(getPT[SCY][expiry] == address(0), "PT_EXISTED");
|
|
69
77
|
|
|
70
78
|
ISuperComposableYield _SCY = ISuperComposableYield(SCY);
|
|
71
79
|
|
|
72
80
|
uint8 assetDecimals = _SCY.assetDecimals();
|
|
73
81
|
|
|
74
|
-
|
|
75
|
-
new
|
|
82
|
+
PT = address(
|
|
83
|
+
new PendlePrincipalToken(
|
|
76
84
|
SCY,
|
|
77
|
-
|
|
78
|
-
|
|
85
|
+
PT_PREFIX.concat(_SCY.name(), expiry, " "),
|
|
86
|
+
PT_PREFIX.concat(_SCY.symbol(), expiry, "-"),
|
|
79
87
|
assetDecimals,
|
|
80
88
|
expiry
|
|
81
89
|
)
|
|
@@ -84,7 +92,7 @@ contract PendleYieldContractFactory is PermissionsV2Upg, IPYieldContractFactory
|
|
|
84
92
|
YT = address(
|
|
85
93
|
new PendleYieldToken(
|
|
86
94
|
SCY,
|
|
87
|
-
|
|
95
|
+
PT,
|
|
88
96
|
YT_PREFIX.concat(_SCY.name(), expiry, " "),
|
|
89
97
|
YT_PREFIX.concat(_SCY.symbol(), expiry, "-"),
|
|
90
98
|
assetDecimals,
|
|
@@ -92,23 +100,30 @@ contract PendleYieldContractFactory is PermissionsV2Upg, IPYieldContractFactory
|
|
|
92
100
|
)
|
|
93
101
|
);
|
|
94
102
|
|
|
95
|
-
|
|
103
|
+
IPPrincipalToken(PT).initialize(YT);
|
|
96
104
|
|
|
97
|
-
|
|
105
|
+
getPT[SCY][expiry] = PT;
|
|
98
106
|
getYT[SCY][expiry] = YT;
|
|
99
|
-
|
|
107
|
+
isPT[PT] = true;
|
|
100
108
|
isYT[YT] = true;
|
|
109
|
+
|
|
110
|
+
emit CreateYieldContract(SCY, PT, YT, expiry);
|
|
101
111
|
}
|
|
102
112
|
|
|
103
113
|
function setExpiryDivisor(uint256 newExpiryDivisor) external onlyGovernance {
|
|
114
|
+
require(newExpiryDivisor != 0, "zero value");
|
|
104
115
|
expiryDivisor = newExpiryDivisor;
|
|
116
|
+
emit SetExpiryDivisor(newExpiryDivisor);
|
|
105
117
|
}
|
|
106
118
|
|
|
107
119
|
function setInterestFeeRate(uint256 newInterestFeeRate) external onlyGovernance {
|
|
108
120
|
interestFeeRate = newInterestFeeRate;
|
|
121
|
+
emit SetInterestFeeRate(newInterestFeeRate);
|
|
109
122
|
}
|
|
110
123
|
|
|
111
124
|
function setTreasury(address newTreasury) external onlyGovernance {
|
|
125
|
+
require(newTreasury != address(0), "zero address");
|
|
112
126
|
treasury = newTreasury;
|
|
127
|
+
emit SetTreasury(treasury);
|
|
113
128
|
}
|
|
114
129
|
}
|