@gooddollar/goodprotocol 1.0.8 → 1.0.11
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/artifacts/contracts/DAOStackInterfaces.sol/Avatar.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/Controller.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/GlobalConstraintInterface.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/IntVoteInterface.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/ReputationInterface.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/SchemeRegistrar.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/AggregatorV3Interface.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/ERC20.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IAaveIncentivesController.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IAdminWallet.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IDonationStaking.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IERC2917.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IFirstClaimPool.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IGoodDollar.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IGoodStaking.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IHasRouter.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IIdentity.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/ILendingPool.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/INameService.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IUBIScheme.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/ProxyAdmin.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/Reserve.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/Staking.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/Uniswap.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/UniswapFactory.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/UniswapPair.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/cERC20.dbg.json +1 -1
- package/artifacts/contracts/governance/ClaimersDistribution.sol/ClaimersDistribution.dbg.json +1 -1
- package/artifacts/contracts/governance/CompoundVotingMachine.sol/CompoundVotingMachine.dbg.json +1 -1
- package/artifacts/contracts/governance/GReputation.sol/GReputation.dbg.json +1 -1
- package/artifacts/contracts/governance/GovarnanceStaking.sol/GovernanceStaking.dbg.json +1 -1
- package/artifacts/contracts/governance/MultiBaseGovernanceShareField.sol/MultiBaseGovernanceShareField.dbg.json +1 -1
- package/artifacts/contracts/governance/Reputation.sol/Reputation.dbg.json +1 -1
- package/artifacts/contracts/governance/StakersDistribution.sol/StakersDistribution.dbg.json +1 -1
- package/artifacts/contracts/governance/StakersDistribution.sol/StakersDistribution.json +2 -2
- package/artifacts/contracts/mocks/AaveMock.sol/AaveMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DAIMock.sol/DAIMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DecimalsMock.sol/DecimalsMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/GoodCompoundStakingTest.sol/GoodCompoundStakingTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/GoodCompoundStakingTest.sol/GoodCompoundStakingTest.json +6 -6
- package/artifacts/contracts/mocks/GoodFundManagerTest.sol/GoodFundManagerTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/IncentiveControllerMock.sol/IncentiveControllerMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/LendingPoolMock.sol/LendingPoolMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTester.sol/OverMintTester.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTesterRegularStake.sol/OverMintTesterRegularStake.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTesterRegularStake.sol/OverMintTesterRegularStake.json +2 -2
- package/artifacts/contracts/mocks/SixteenDecimalsTokenMock.sol/SixteenDecimalsTokenMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/SwapHelperTest.sol/SwapHelperTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/TwentyDecimalsTokenMock.sol/TwentyDecimalsTokenMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock2.dbg.json +1 -1
- package/artifacts/contracts/mocks/UsdcMock.sol/USDCMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cBATMock.sol/cBATMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDAILowWorthMock.sol/cDAILowWorthMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDAIMock.sol/cDAIMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDAINonMintableMock.sol/cDAINonMintableMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDecimalsMock.sol/cDecimalsMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cSDTMock.sol/cSDTMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cUSDCMock.sol/cUSDCMock.dbg.json +1 -1
- package/artifacts/contracts/reserve/ExchangeHelper.sol/ExchangeHelper.dbg.json +1 -1
- package/artifacts/contracts/reserve/GoodMarketMaker.sol/GoodMarketMaker.dbg.json +1 -1
- package/artifacts/contracts/reserve/GoodReserveCDai.sol/ContributionCalc.dbg.json +1 -1
- package/artifacts/contracts/reserve/GoodReserveCDai.sol/GoodReserveCDai.dbg.json +1 -1
- package/artifacts/contracts/staking/BaseShareField.sol/BaseShareField.dbg.json +1 -1
- package/artifacts/contracts/staking/BaseShareFieldV2.sol/BaseShareFieldV2.dbg.json +4 -0
- package/artifacts/contracts/staking/BaseShareFieldV2.sol/BaseShareFieldV2.json +200 -0
- package/artifacts/contracts/staking/DonationsStaking.sol/DonationsStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/DonationsStaking.sol/DonationsStaking.json +2 -2
- package/artifacts/contracts/staking/GoodFundManager.sol/GoodFundManager.dbg.json +1 -1
- package/artifacts/contracts/staking/SimpleStaking.sol/SimpleStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/SimpleStakingV2.sol/SimpleStakingV2.dbg.json +4 -0
- package/artifacts/contracts/staking/SimpleStakingV2.sol/SimpleStakingV2.json +958 -0
- package/artifacts/contracts/staking/UniswapV2SwapHelper.sol/UniswapV2SwapHelper.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/AaveStakingFactory.sol/AaveStakingFactory.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/AaveStakingFactory.sol/AaveStakingFactory.json +65 -12
- package/artifacts/contracts/staking/aave/GoodAaveStaking.sol/GoodAaveStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/GoodAaveStaking.sol/GoodAaveStaking.json +4 -4
- package/artifacts/contracts/staking/aave/GoodAaveStakingV2.sol/GoodAaveStakingV2.dbg.json +4 -0
- package/artifacts/contracts/staking/aave/GoodAaveStakingV2.sol/GoodAaveStakingV2.json +1149 -0
- package/artifacts/contracts/staking/compound/CompoundStakingFactory.sol/CompoundStakingFactory.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/CompoundStakingFactory.sol/CompoundStakingFactory.json +57 -14
- package/artifacts/contracts/staking/compound/GoodCompoundStaking.sol/GoodCompoundStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/GoodCompoundStaking.sol/GoodCompoundStaking.json +6 -6
- package/artifacts/contracts/staking/compound/GoodCompoundStakingV2.sol/GoodCompoundStakingV2.dbg.json +4 -0
- package/artifacts/contracts/staking/compound/GoodCompoundStakingV2.sol/GoodCompoundStakingV2.json +1092 -0
- package/artifacts/contracts/ubi/UBIScheme.sol/UBIScheme.dbg.json +1 -1
- package/artifacts/contracts/unaudited-foundation/FuseFaucet.sol/FuseFaucet.dbg.json +1 -1
- package/artifacts/contracts/unaudited-foundation/InvitesV1.sol/InvitesV1.dbg.json +1 -1
- package/artifacts/contracts/utils/BancorFormula.sol/BancorFormula.dbg.json +1 -1
- package/artifacts/contracts/utils/DAOContract.sol/DAOContract.dbg.json +1 -1
- package/artifacts/contracts/utils/DAOUpgradeableContract.sol/DAOUpgradeableContract.dbg.json +1 -1
- package/artifacts/contracts/utils/DSMath.sol/DSMath.dbg.json +1 -1
- package/artifacts/contracts/utils/DataTypes.sol/DataTypes.dbg.json +1 -1
- package/artifacts/contracts/utils/NameService.sol/NameService.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgrade.sol/OldMarketMaker.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgrade.sol/ProtocolUpgrade.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgradeFuse.sol/ProtocolUpgradeFuse.dbg.json +1 -1
- package/artifacts/contracts/utils/ReputationTestHelper.sol/ReputationTestHelper.dbg.json +1 -1
- package/contracts/staking/BaseShareFieldV2.sol +343 -0
- package/contracts/staking/SimpleStaking.sol +0 -7
- package/contracts/staking/SimpleStakingV2.sol +488 -0
- package/contracts/staking/aave/AaveStakingFactory.sol +45 -19
- package/contracts/staking/aave/GoodAaveStaking.sol +1 -1
- package/contracts/staking/aave/GoodAaveStakingV2.sol +263 -0
- package/contracts/staking/compound/CompoundStakingFactory.sol +41 -18
- package/contracts/staking/compound/GoodCompoundStaking.sol +1 -1
- package/contracts/staking/compound/GoodCompoundStakingV2.sol +315 -0
- package/package.json +1 -1
- package/releases/deployment.json +55 -47
- package/scripts/deployFullDAO.ts +1 -1
- package/scripts/upgradeToV2/upgradeToV2.ts +7 -3
- package/test/governance/StakersDistribution.test.ts +43 -14
- package/test/helpers.ts +6 -1
- package/test/staking/CompoundStakingFactory.test.ts +24 -21
- package/test/staking/DifferentStakingTokens.test.ts +3 -1
- package/test/staking/DonationsStaking.test.ts +3 -1
- package/test/staking/GoodAaveStakingFactory.test.ts +26 -23
- package/test/staking/SimpleDAIStaking.test.ts +3 -11
- package/test/staking/StakingRewards.test.ts +20 -14
- package/test/staking/SwapHelper.test.ts +4 -1
- package/test/staking/UsdcAaveStaking.test.ts +22 -3
- package/test/ubi/UBIScheme.e2e.test.ts +1 -1
- package/test/utils/ProtocolUpgrade.test.ts +1 -1
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity >=0.8.0;
|
|
4
|
+
import "../SimpleStakingV2.sol";
|
|
5
|
+
import "../../Interfaces.sol";
|
|
6
|
+
import "../../utils/DataTypes.sol";
|
|
7
|
+
import "../UniswapV2SwapHelper.sol";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @title Staking contract that donates earned interest to the DAO
|
|
11
|
+
* allowing stakers to deposit Token
|
|
12
|
+
* or withdraw their stake in Token
|
|
13
|
+
* the contracts buy cToken and can transfer the daily interest to the DAO
|
|
14
|
+
*/
|
|
15
|
+
contract GoodAaveStakingV2 is SimpleStakingV2 {
|
|
16
|
+
using UniswapV2SwapHelper for IHasRouter;
|
|
17
|
+
|
|
18
|
+
// Address of the TOKEN/USD oracle from chainlink
|
|
19
|
+
address public tokenUsdOracle;
|
|
20
|
+
|
|
21
|
+
//LendingPool of aave
|
|
22
|
+
ILendingPool public lendingPool;
|
|
23
|
+
|
|
24
|
+
//Address of the AaveIncentivesController
|
|
25
|
+
IAaveIncentivesController public incentiveController;
|
|
26
|
+
|
|
27
|
+
//address of the AAVE/USD oracle
|
|
28
|
+
address public aaveUSDOracle;
|
|
29
|
+
// Gas cost to collect interest from this staking contract
|
|
30
|
+
uint32 public collectInterestGasCost;
|
|
31
|
+
// Gas cost to claim stkAave rewards
|
|
32
|
+
uint32 public stkAaveClaimGasCost;
|
|
33
|
+
|
|
34
|
+
address[] public tokenToDaiSwapPath;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @param _token Token to swap DEFI token
|
|
38
|
+
* @param _lendingPool LendingPool address
|
|
39
|
+
* @param _ns Address of the NameService
|
|
40
|
+
* @param _tokenName Name of the staking token which will be provided to staker for their staking share
|
|
41
|
+
* @param _tokenSymbol Symbol of the staking token which will be provided to staker for their staking share
|
|
42
|
+
* @param _tokenSymbol Determines blocks to pass for 1x Multiplier
|
|
43
|
+
* @param _tokenUsdOracle address of the TOKEN/USD oracle
|
|
44
|
+
* @param _incentiveController Aave incentive controller which provides AAVE rewards
|
|
45
|
+
* @param _aaveUSDOracle address of the AAVE/USD oracle
|
|
46
|
+
*/
|
|
47
|
+
function init(
|
|
48
|
+
address _token,
|
|
49
|
+
address _lendingPool,
|
|
50
|
+
INameService _ns,
|
|
51
|
+
string memory _tokenName,
|
|
52
|
+
string memory _tokenSymbol,
|
|
53
|
+
uint64 _maxRewardThreshold,
|
|
54
|
+
address _tokenUsdOracle,
|
|
55
|
+
IAaveIncentivesController _incentiveController,
|
|
56
|
+
address _aaveUSDOracle,
|
|
57
|
+
address[] memory _tokenToDaiSwapPath
|
|
58
|
+
) public {
|
|
59
|
+
lendingPool = ILendingPool(_lendingPool);
|
|
60
|
+
DataTypes.ReserveData memory reserve = lendingPool.getReserveData(_token);
|
|
61
|
+
initialize(
|
|
62
|
+
_token,
|
|
63
|
+
reserve.aTokenAddress,
|
|
64
|
+
_ns,
|
|
65
|
+
_tokenName,
|
|
66
|
+
_tokenSymbol,
|
|
67
|
+
_maxRewardThreshold
|
|
68
|
+
);
|
|
69
|
+
require(
|
|
70
|
+
_tokenToDaiSwapPath[0] == _token &&
|
|
71
|
+
_tokenToDaiSwapPath[_tokenToDaiSwapPath.length - 1] ==
|
|
72
|
+
nameService.getAddress("DAI"),
|
|
73
|
+
"invalid _tokenToDaiSwapPath"
|
|
74
|
+
);
|
|
75
|
+
tokenToDaiSwapPath = _tokenToDaiSwapPath;
|
|
76
|
+
|
|
77
|
+
//above initialize going to revert on second call, so this is safe
|
|
78
|
+
tokenUsdOracle = _tokenUsdOracle;
|
|
79
|
+
incentiveController = _incentiveController;
|
|
80
|
+
aaveUSDOracle = _aaveUSDOracle;
|
|
81
|
+
collectInterestGasCost = 250000;
|
|
82
|
+
stkAaveClaimGasCost = 50000;
|
|
83
|
+
_approveTokens();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @dev stake some Token
|
|
88
|
+
* @param _amount of Token to stake
|
|
89
|
+
*/
|
|
90
|
+
function mintInterestToken(uint256 _amount) internal override {
|
|
91
|
+
lendingPool.deposit(address(token), _amount, address(this), 0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* @dev redeem Token from aave
|
|
96
|
+
* @param _amount of token to redeem in Token
|
|
97
|
+
*/
|
|
98
|
+
function redeem(uint256 _amount) internal override {
|
|
99
|
+
uint256 withdrawnAmount = lendingPool.withdraw(
|
|
100
|
+
address(token),
|
|
101
|
+
_amount,
|
|
102
|
+
address(this)
|
|
103
|
+
);
|
|
104
|
+
require(withdrawnAmount > 0, "Withdrawn amount should be bigger than zero");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @dev Function to redeem aToken for DAI, so reserve knows how to handle it. (reserve can handle dai or cdai)
|
|
109
|
+
* also transfers stkaave to reserve
|
|
110
|
+
* @dev _amount of token in iToken
|
|
111
|
+
* @dev _recipient recipient of the DAI
|
|
112
|
+
* @return actualTokenGains amount of token redeemed for dai,
|
|
113
|
+
actualRewardTokenGains amount of reward token earned,
|
|
114
|
+
daiAmount total dai received
|
|
115
|
+
*/
|
|
116
|
+
function redeemUnderlyingToDAI(uint256 _amount, address _recipient)
|
|
117
|
+
internal
|
|
118
|
+
override
|
|
119
|
+
returns (
|
|
120
|
+
uint256 actualTokenGains,
|
|
121
|
+
uint256 actualRewardTokenGains,
|
|
122
|
+
uint256 daiAmount
|
|
123
|
+
)
|
|
124
|
+
{
|
|
125
|
+
//out of requested interests to withdraw how much is it safe to swap
|
|
126
|
+
actualTokenGains = IHasRouter(this).maxSafeTokenAmount(
|
|
127
|
+
address(token),
|
|
128
|
+
tokenToDaiSwapPath[1],
|
|
129
|
+
_amount,
|
|
130
|
+
maxLiquidityPercentageSwap
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
lendingPool.withdraw(address(token), actualTokenGains, address(this));
|
|
134
|
+
actualTokenGains = token.balanceOf(address(this));
|
|
135
|
+
|
|
136
|
+
address[] memory tokenAddress = new address[](1);
|
|
137
|
+
tokenAddress[0] = address(iToken);
|
|
138
|
+
|
|
139
|
+
actualRewardTokenGains = incentiveController.claimRewards(
|
|
140
|
+
tokenAddress,
|
|
141
|
+
type(uint256).max,
|
|
142
|
+
avatar
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
if (actualTokenGains > 0) {
|
|
146
|
+
daiAmount = IHasRouter(this).swap(
|
|
147
|
+
tokenToDaiSwapPath,
|
|
148
|
+
actualTokenGains,
|
|
149
|
+
0,
|
|
150
|
+
_recipient
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @dev returns decimals of token.
|
|
157
|
+
*/
|
|
158
|
+
function tokenDecimal() internal view override returns (uint256) {
|
|
159
|
+
ERC20 token = ERC20(address(token));
|
|
160
|
+
return uint256(token.decimals());
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* @dev returns decimals of interest token.
|
|
165
|
+
*/
|
|
166
|
+
function iTokenDecimal() internal view override returns (uint256) {
|
|
167
|
+
ERC20 aToken = ERC20(address(iToken));
|
|
168
|
+
return uint256(aToken.decimals());
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @dev Function that calculates current interest gains of this staking contract
|
|
173
|
+
* @param _returnTokenBalanceInUSD determine return token balance of staking contract in USD
|
|
174
|
+
* @param _returnTokenGainsInUSD determine return token gains of staking contract in USD
|
|
175
|
+
* @return iTokenGains gains in iToken, tokenGains gains in token, tokenBalance current balance , balanceInUSD, tokenGainsInUSD
|
|
176
|
+
*/
|
|
177
|
+
function currentGains(
|
|
178
|
+
bool _returnTokenBalanceInUSD,
|
|
179
|
+
bool _returnTokenGainsInUSD
|
|
180
|
+
)
|
|
181
|
+
public
|
|
182
|
+
view
|
|
183
|
+
override
|
|
184
|
+
returns (
|
|
185
|
+
uint256 iTokenGains,
|
|
186
|
+
uint256 tokenGains,
|
|
187
|
+
uint256 tokenBalance,
|
|
188
|
+
uint256 balanceInUSD,
|
|
189
|
+
uint256 tokenGainsInUSD
|
|
190
|
+
)
|
|
191
|
+
{
|
|
192
|
+
ERC20 aToken = ERC20(address(iToken));
|
|
193
|
+
tokenBalance = aToken.balanceOf(address(this));
|
|
194
|
+
balanceInUSD = _returnTokenBalanceInUSD
|
|
195
|
+
? getTokenValueInUSD(tokenUsdOracle, tokenBalance, token.decimals())
|
|
196
|
+
: 0;
|
|
197
|
+
address[] memory tokenAddress = new address[](1);
|
|
198
|
+
tokenAddress[0] = address(token);
|
|
199
|
+
if (tokenBalance <= totalProductivity) {
|
|
200
|
+
return (0, 0, tokenBalance, balanceInUSD, 0);
|
|
201
|
+
}
|
|
202
|
+
iTokenGains = tokenGains = tokenBalance - totalProductivity;
|
|
203
|
+
|
|
204
|
+
tokenGainsInUSD = _returnTokenGainsInUSD
|
|
205
|
+
? getTokenValueInUSD(tokenUsdOracle, tokenGains, token.decimals())
|
|
206
|
+
: 0;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @dev Function to get interest transfer cost for this particular staking contract
|
|
211
|
+
*/
|
|
212
|
+
function getGasCostForInterestTransfer()
|
|
213
|
+
external
|
|
214
|
+
view
|
|
215
|
+
override
|
|
216
|
+
returns (uint32)
|
|
217
|
+
{
|
|
218
|
+
address[] memory tokenAddress = new address[](1);
|
|
219
|
+
tokenAddress[0] = address(iToken);
|
|
220
|
+
uint256 stkAaaveBalance = incentiveController.getRewardsBalance(
|
|
221
|
+
tokenAddress,
|
|
222
|
+
address(this)
|
|
223
|
+
);
|
|
224
|
+
if (stkAaaveBalance > 0)
|
|
225
|
+
return collectInterestGasCost + stkAaveClaimGasCost;
|
|
226
|
+
|
|
227
|
+
return collectInterestGasCost;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* @dev Set Gas cost to interest collection for this contract
|
|
232
|
+
* @param _collectInterestGasCost Gas cost to collect interest
|
|
233
|
+
* @param _rewardTokenCollectCost gas cost to collect reward tokens
|
|
234
|
+
*/
|
|
235
|
+
function setcollectInterestGasCostParams(
|
|
236
|
+
uint32 _collectInterestGasCost,
|
|
237
|
+
uint32 _rewardTokenCollectCost
|
|
238
|
+
) external {
|
|
239
|
+
_onlyAvatar();
|
|
240
|
+
collectInterestGasCost = _collectInterestGasCost;
|
|
241
|
+
stkAaveClaimGasCost = _rewardTokenCollectCost;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* @dev Calculates worth of given amount of iToken in Token
|
|
246
|
+
* @param _amount Amount of token to calculate worth in Token
|
|
247
|
+
* @return Worth of given amount of token in Token
|
|
248
|
+
*/
|
|
249
|
+
function iTokenWorthInToken(uint256 _amount)
|
|
250
|
+
internal
|
|
251
|
+
view
|
|
252
|
+
override
|
|
253
|
+
returns (uint256)
|
|
254
|
+
{
|
|
255
|
+
return _amount; // since aToken is peg to Token 1:1 return exact amount
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function _approveTokens() internal {
|
|
259
|
+
address uniswapRouter = nameService.getAddress("UNISWAP_ROUTER");
|
|
260
|
+
token.approve(uniswapRouter, type(uint256).max);
|
|
261
|
+
token.approve(address(lendingPool), type(uint256).max); // approve the transfers to defi protocol as much as possible in order to save gas
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
pragma solidity >=0.8.0;
|
|
4
4
|
import "@openzeppelin/contracts-upgradeable/proxy/ClonesUpgradeable.sol";
|
|
5
|
-
import "./
|
|
5
|
+
import "./GoodCompoundStakingV2.sol";
|
|
6
6
|
import "../../Interfaces.sol";
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -14,23 +14,44 @@ import "../../Interfaces.sol";
|
|
|
14
14
|
contract CompoundStakingFactory {
|
|
15
15
|
using ClonesUpgradeable for address;
|
|
16
16
|
|
|
17
|
-
address impl = address(new
|
|
17
|
+
address public impl = address(new GoodCompoundStakingV2());
|
|
18
18
|
|
|
19
|
-
event Deployed(address proxy, address cToken);
|
|
19
|
+
event Deployed(address proxy, address cToken, address impl);
|
|
20
20
|
|
|
21
|
-
function clone(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
function clone(
|
|
22
|
+
address _impl,
|
|
23
|
+
cERC20 cToken,
|
|
24
|
+
bytes32 paramsHash
|
|
25
|
+
) internal returns (GoodCompoundStakingV2) {
|
|
26
|
+
address deployed = address(_impl).cloneDeterministic(
|
|
26
27
|
keccak256(abi.encodePacked(address(cToken), paramsHash))
|
|
27
28
|
);
|
|
28
|
-
emit Deployed(deployed, address(cToken));
|
|
29
|
-
return
|
|
29
|
+
emit Deployed(deployed, address(cToken), _impl);
|
|
30
|
+
return GoodCompoundStakingV2(deployed);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function cloneAndInit(
|
|
34
|
+
cERC20 _cToken,
|
|
35
|
+
INameService _ns,
|
|
36
|
+
uint64 _maxRewardThreshold,
|
|
37
|
+
address _tokenUsdOracle,
|
|
38
|
+
address _compUsdOracle,
|
|
39
|
+
address[] memory _tokenToDaiSwapPath
|
|
40
|
+
) public {
|
|
41
|
+
cloneAndInit(
|
|
42
|
+
impl,
|
|
43
|
+
_cToken,
|
|
44
|
+
_ns,
|
|
45
|
+
_maxRewardThreshold,
|
|
46
|
+
_tokenUsdOracle,
|
|
47
|
+
_compUsdOracle,
|
|
48
|
+
_tokenToDaiSwapPath
|
|
49
|
+
);
|
|
30
50
|
}
|
|
31
51
|
|
|
32
52
|
/**
|
|
33
53
|
@dev Function to clone Staking contract and initialize new one with new ctoken
|
|
54
|
+
@param _impl address of contract to clone
|
|
34
55
|
@param cToken Staking cToken to use in staking contract
|
|
35
56
|
@param _ns NameService that holds whole necessary addresses
|
|
36
57
|
@param _maxRewardThreshold Block numbers that need to pass in order to user would get their rewards with 1x multiplier instead of 0.5x
|
|
@@ -38,6 +59,7 @@ contract CompoundStakingFactory {
|
|
|
38
59
|
@param _compUsdOracle address of the AAVE/USD oracle
|
|
39
60
|
*/
|
|
40
61
|
function cloneAndInit(
|
|
62
|
+
address _impl,
|
|
41
63
|
cERC20 cToken,
|
|
42
64
|
INameService _ns,
|
|
43
65
|
uint64 _maxRewardThreshold,
|
|
@@ -45,7 +67,8 @@ contract CompoundStakingFactory {
|
|
|
45
67
|
address _compUsdOracle,
|
|
46
68
|
address[] memory _tokenToDaiSwapPath
|
|
47
69
|
) public {
|
|
48
|
-
|
|
70
|
+
GoodCompoundStakingV2 deployed = clone(
|
|
71
|
+
_impl,
|
|
49
72
|
cToken,
|
|
50
73
|
keccak256(
|
|
51
74
|
abi.encodePacked(
|
|
@@ -60,7 +83,7 @@ contract CompoundStakingFactory {
|
|
|
60
83
|
cToken.underlying(),
|
|
61
84
|
address(cToken),
|
|
62
85
|
_ns,
|
|
63
|
-
string(abi.encodePacked("
|
|
86
|
+
string(abi.encodePacked("GoodCompoundStakingV2 ", cToken.name())),
|
|
64
87
|
string(abi.encodePacked("g", cToken.symbol())),
|
|
65
88
|
_maxRewardThreshold,
|
|
66
89
|
_tokenUsdOracle,
|
|
@@ -69,13 +92,13 @@ contract CompoundStakingFactory {
|
|
|
69
92
|
);
|
|
70
93
|
}
|
|
71
94
|
|
|
72
|
-
function predictAddress(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
{
|
|
95
|
+
function predictAddress(
|
|
96
|
+
address _impl,
|
|
97
|
+
cERC20 cToken,
|
|
98
|
+
bytes32 paramsHash
|
|
99
|
+
) public view returns (address) {
|
|
77
100
|
return
|
|
78
|
-
address(
|
|
101
|
+
address(_impl).predictDeterministicAddress(
|
|
79
102
|
keccak256(abi.encodePacked(address(cToken), paramsHash))
|
|
80
103
|
);
|
|
81
104
|
}
|
|
@@ -315,7 +315,7 @@ contract GoodCompoundStaking is SimpleStaking {
|
|
|
315
315
|
compCollectGasCost = _rewardTokenCollectCost;
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
-
function _approveTokens() internal
|
|
318
|
+
function _approveTokens() internal {
|
|
319
319
|
address uniswapRouter = address(uniswapContract);
|
|
320
320
|
comp.approve(uniswapRouter, type(uint256).max);
|
|
321
321
|
token.approve(uniswapRouter, type(uint256).max);
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
pragma solidity >=0.8.0;
|
|
4
|
+
import "../SimpleStakingV2.sol";
|
|
5
|
+
import "../../Interfaces.sol";
|
|
6
|
+
import "../UniswapV2SwapHelper.sol";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @title Staking contract that donates earned interest to the DAO
|
|
10
|
+
* allowing stakers to deposit Token
|
|
11
|
+
* or withdraw their stake in Token
|
|
12
|
+
* the contracts buy cToken and can transfer the daily interest to the DAO
|
|
13
|
+
*/
|
|
14
|
+
contract GoodCompoundStakingV2 is SimpleStakingV2 {
|
|
15
|
+
using UniswapV2SwapHelper for IHasRouter;
|
|
16
|
+
|
|
17
|
+
// Address of the TOKEN/USD oracle from chainlink
|
|
18
|
+
address tokenUsdOracle;
|
|
19
|
+
//Address of the COMP/USD oracle from chianlink
|
|
20
|
+
address compUsdOracle;
|
|
21
|
+
|
|
22
|
+
// Gas cost to collect interest from this staking contract
|
|
23
|
+
uint32 collectInterestGasCost;
|
|
24
|
+
// Gas cost to collect COMP rewards
|
|
25
|
+
uint32 compCollectGasCost;
|
|
26
|
+
|
|
27
|
+
address[] tokenToDaiSwapPath;
|
|
28
|
+
|
|
29
|
+
ERC20 comp;
|
|
30
|
+
|
|
31
|
+
Uniswap uniswapContract;
|
|
32
|
+
|
|
33
|
+
function getSettings()
|
|
34
|
+
external
|
|
35
|
+
view
|
|
36
|
+
returns (uint32 _collectInterestGasCost, uint32 _compCollectGasCost)
|
|
37
|
+
{
|
|
38
|
+
return (collectInterestGasCost, compCollectGasCost);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @param _token Token to swap DEFI token
|
|
43
|
+
* @param _iToken DEFI token address
|
|
44
|
+
* @param _ns Address of the NameService
|
|
45
|
+
* @param _tokenName Name of the staking token which will be provided to staker for their staking share
|
|
46
|
+
* @param _tokenSymbol Symbol of the staking token which will be provided to staker for their staking share
|
|
47
|
+
* @param _maxRewardThreshold Determines blocks to pass for 1x Multiplier
|
|
48
|
+
* @param _tokenUsdOracle address of the TOKEN/USD oracle
|
|
49
|
+
* @param _compUsdOracle address of the COMP/USD oracle
|
|
50
|
+
* @param _tokenToDaiSwapPath the uniswap path to swap token to DAI, should be empty if token is DAI
|
|
51
|
+
*/
|
|
52
|
+
function init(
|
|
53
|
+
address _token,
|
|
54
|
+
address _iToken,
|
|
55
|
+
INameService _ns,
|
|
56
|
+
string memory _tokenName,
|
|
57
|
+
string memory _tokenSymbol,
|
|
58
|
+
uint64 _maxRewardThreshold,
|
|
59
|
+
address _tokenUsdOracle,
|
|
60
|
+
address _compUsdOracle,
|
|
61
|
+
address[] memory _tokenToDaiSwapPath
|
|
62
|
+
) public {
|
|
63
|
+
initialize(
|
|
64
|
+
_token,
|
|
65
|
+
_iToken,
|
|
66
|
+
_ns,
|
|
67
|
+
_tokenName,
|
|
68
|
+
_tokenSymbol,
|
|
69
|
+
_maxRewardThreshold
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
address dai = nameService.getAddress("DAI");
|
|
73
|
+
require(
|
|
74
|
+
_token == dai ||
|
|
75
|
+
(_tokenToDaiSwapPath[0] == _token &&
|
|
76
|
+
_tokenToDaiSwapPath[_tokenToDaiSwapPath.length - 1] == dai),
|
|
77
|
+
"path"
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
//above initialize going to revert on second call, so this is safe
|
|
81
|
+
compUsdOracle = _compUsdOracle;
|
|
82
|
+
tokenUsdOracle = _tokenUsdOracle;
|
|
83
|
+
tokenToDaiSwapPath = _tokenToDaiSwapPath;
|
|
84
|
+
comp = ERC20(nameService.getAddress("COMP"));
|
|
85
|
+
uniswapContract = Uniswap(nameService.getAddress("UNISWAP_ROUTER"));
|
|
86
|
+
collectInterestGasCost = 250000;
|
|
87
|
+
compCollectGasCost = 150000;
|
|
88
|
+
comp.approve(address(uniswapContract), type(uint256).max);
|
|
89
|
+
token.approve(address(uniswapContract), type(uint256).max);
|
|
90
|
+
token.approve(address(iToken), type(uint256).max); // approve the transfers to defi protocol as much as possible in order to save gas
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @dev stake some Token
|
|
95
|
+
* @param _amount of Token to stake
|
|
96
|
+
*/
|
|
97
|
+
function mintInterestToken(uint256 _amount) internal override {
|
|
98
|
+
require(cERC20(address(iToken)).mint(_amount) == 0, "minting");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @dev redeem Token from compound
|
|
103
|
+
* @param _amount of token to redeem in Token
|
|
104
|
+
*/
|
|
105
|
+
function redeem(uint256 _amount) internal override {
|
|
106
|
+
require(cERC20(address(iToken)).redeemUnderlying(_amount) == 0, "redeem");
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* @dev Function to redeem cToken + reward COMP for DAI, so reserve knows how to handle it. (reserve can handle dai or cdai)
|
|
111
|
+
* @dev _amount of token in iToken
|
|
112
|
+
* @dev _recipient recipient of the DAI
|
|
113
|
+
* @return actualTokenGains amount of token redeemed for dai,
|
|
114
|
+
actualRewardTokenGains amount of reward token redeemed for dai,
|
|
115
|
+
daiAmount total dai received
|
|
116
|
+
*/
|
|
117
|
+
function redeemUnderlyingToDAI(uint256 _amount, address _recipient)
|
|
118
|
+
internal
|
|
119
|
+
override
|
|
120
|
+
returns (
|
|
121
|
+
uint256 actualTokenGains,
|
|
122
|
+
uint256 actualRewardTokenGains,
|
|
123
|
+
uint256 daiAmount
|
|
124
|
+
)
|
|
125
|
+
{
|
|
126
|
+
uint256 compBalance = comp.balanceOf(address(this));
|
|
127
|
+
|
|
128
|
+
uint256 redeemedDAI;
|
|
129
|
+
|
|
130
|
+
if (compBalance > 0) {
|
|
131
|
+
address[] memory compToDaiSwapPath = new address[](3);
|
|
132
|
+
compToDaiSwapPath[0] = address(comp);
|
|
133
|
+
compToDaiSwapPath[1] = uniswapContract.WETH();
|
|
134
|
+
compToDaiSwapPath[2] = nameService.getAddress("DAI");
|
|
135
|
+
actualRewardTokenGains = IHasRouter(this).maxSafeTokenAmount(
|
|
136
|
+
address(comp),
|
|
137
|
+
uniswapContract.WETH(),
|
|
138
|
+
compBalance,
|
|
139
|
+
maxLiquidityPercentageSwap
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
redeemedDAI = IHasRouter(this).swap(
|
|
143
|
+
compToDaiSwapPath,
|
|
144
|
+
actualRewardTokenGains,
|
|
145
|
+
0,
|
|
146
|
+
_recipient
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
//in case of cdai there's no need to swap to DAI, we send cdai to reserve directly
|
|
150
|
+
actualTokenGains = iTokenWorthInToken(_amount);
|
|
151
|
+
if (address(iToken) == nameService.getAddress("CDAI")) {
|
|
152
|
+
require(iToken.transfer(_recipient, _amount), "collect");
|
|
153
|
+
return (
|
|
154
|
+
actualTokenGains,
|
|
155
|
+
actualRewardTokenGains,
|
|
156
|
+
actualTokenGains + redeemedDAI
|
|
157
|
+
); // If iToken is cDAI then just return cDAI
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
//out of requested interests to withdraw how much is it safe to swap
|
|
161
|
+
uint256 safeAmount = IHasRouter(this).maxSafeTokenAmount(
|
|
162
|
+
address(token),
|
|
163
|
+
tokenToDaiSwapPath[1],
|
|
164
|
+
actualTokenGains,
|
|
165
|
+
maxLiquidityPercentageSwap
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
if (actualTokenGains > safeAmount) {
|
|
169
|
+
actualTokenGains = safeAmount;
|
|
170
|
+
//recalculate how much iToken to redeem
|
|
171
|
+
_amount = tokenWorthIniToken(actualTokenGains);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
require(cERC20(address(iToken)).redeem(_amount) == 0, "iredeem");
|
|
175
|
+
|
|
176
|
+
actualTokenGains = token.balanceOf(address(this));
|
|
177
|
+
|
|
178
|
+
if (actualTokenGains > 0) {
|
|
179
|
+
redeemedDAI += IHasRouter(this).swap(
|
|
180
|
+
tokenToDaiSwapPath,
|
|
181
|
+
actualTokenGains,
|
|
182
|
+
0,
|
|
183
|
+
_recipient
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return (actualTokenGains, actualRewardTokenGains, redeemedDAI);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* @dev returns decimals of token.
|
|
192
|
+
*/
|
|
193
|
+
function tokenDecimal() internal view override returns (uint256) {
|
|
194
|
+
return uint256(ERC20(address(token)).decimals());
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* @dev returns decimals of interest token.
|
|
199
|
+
*/
|
|
200
|
+
function iTokenDecimal() internal view override returns (uint256) {
|
|
201
|
+
return uint256(ERC20(address(iToken)).decimals());
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @dev Function that calculates current interest gains of this staking contract
|
|
206
|
+
* @param _returnTokenBalanceInUSD determine return token balance of staking contract in USD
|
|
207
|
+
* @param _returnTokenGainsInUSD determine return token gains of staking contract in USD
|
|
208
|
+
* @return iTokenGains gains in itoken, tokenGains gains in token, tokenBalance total locked Tokens, balanceInUsd locked tokens worth in USD, tokenGainsInUSD token Gains in USD
|
|
209
|
+
*/
|
|
210
|
+
function currentGains(
|
|
211
|
+
bool _returnTokenBalanceInUSD,
|
|
212
|
+
bool _returnTokenGainsInUSD
|
|
213
|
+
)
|
|
214
|
+
public
|
|
215
|
+
view
|
|
216
|
+
override
|
|
217
|
+
returns (
|
|
218
|
+
uint256 iTokenGains,
|
|
219
|
+
uint256 tokenGains,
|
|
220
|
+
uint256 tokenBalance,
|
|
221
|
+
uint256 balanceInUSD,
|
|
222
|
+
uint256 tokenGainsInUSD
|
|
223
|
+
)
|
|
224
|
+
{
|
|
225
|
+
tokenBalance = iTokenWorthInToken(iToken.balanceOf(address(this)));
|
|
226
|
+
balanceInUSD = _returnTokenBalanceInUSD
|
|
227
|
+
? getTokenValueInUSD(tokenUsdOracle, tokenBalance, token.decimals())
|
|
228
|
+
: 0;
|
|
229
|
+
uint256 compValueInUSD = _returnTokenGainsInUSD
|
|
230
|
+
? getTokenValueInUSD(
|
|
231
|
+
compUsdOracle,
|
|
232
|
+
comp.balanceOf(address(this)),
|
|
233
|
+
18 // COMP is in 18 decimal
|
|
234
|
+
)
|
|
235
|
+
: 0;
|
|
236
|
+
if (tokenBalance <= totalProductivity) {
|
|
237
|
+
return (0, 0, tokenBalance, balanceInUSD, compValueInUSD);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
tokenGains = tokenBalance - totalProductivity;
|
|
241
|
+
tokenGainsInUSD = _returnTokenGainsInUSD
|
|
242
|
+
? getTokenValueInUSD(tokenUsdOracle, tokenGains, token.decimals()) +
|
|
243
|
+
compValueInUSD
|
|
244
|
+
: 0;
|
|
245
|
+
|
|
246
|
+
iTokenGains = tokenWorthIniToken(tokenGains);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* @dev Function to get interest transfer cost for this particular staking contract
|
|
251
|
+
*/
|
|
252
|
+
function getGasCostForInterestTransfer()
|
|
253
|
+
external
|
|
254
|
+
view
|
|
255
|
+
override
|
|
256
|
+
returns (uint32)
|
|
257
|
+
{
|
|
258
|
+
uint256 compBalance = comp.balanceOf(address(this));
|
|
259
|
+
if (compBalance > 0) return collectInterestGasCost + 200000; // need to make more check for this value
|
|
260
|
+
|
|
261
|
+
return collectInterestGasCost;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @dev Calculates worth of given amount of iToken in Token
|
|
266
|
+
* @param _amount Amount of token to calculate worth in Token
|
|
267
|
+
* @return Worth of given amount of token in Token
|
|
268
|
+
*/
|
|
269
|
+
function iTokenWorthInToken(uint256 _amount)
|
|
270
|
+
internal
|
|
271
|
+
view
|
|
272
|
+
override
|
|
273
|
+
returns (uint256)
|
|
274
|
+
{
|
|
275
|
+
uint256 er = cERC20(address(iToken)).exchangeRateStored();
|
|
276
|
+
(uint256 decimalDifference, bool caseType) = tokenDecimalPrecision();
|
|
277
|
+
uint256 mantissa = 18 + tokenDecimal() - iTokenDecimal();
|
|
278
|
+
uint256 tokenWorth = caseType == true
|
|
279
|
+
? (_amount * (10**decimalDifference) * er) / 10**mantissa
|
|
280
|
+
: ((_amount / (10**decimalDifference)) * er) / 10**mantissa; // calculation based on https://compound.finance/docs#protocol-math
|
|
281
|
+
return tokenWorth;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @dev Calculates worth of given amount of token in iToken
|
|
286
|
+
* @param _amount Amount of iToken to calculate worth in token
|
|
287
|
+
* @return tokenWorth Worth of given amount of token in iToken
|
|
288
|
+
*/
|
|
289
|
+
function tokenWorthIniToken(uint256 _amount)
|
|
290
|
+
public
|
|
291
|
+
view
|
|
292
|
+
returns (uint256 tokenWorth)
|
|
293
|
+
{
|
|
294
|
+
uint256 er = cERC20(address(iToken)).exchangeRateStored();
|
|
295
|
+
(uint256 decimalDifference, bool caseType) = tokenDecimalPrecision();
|
|
296
|
+
uint256 mantissa = 18 + tokenDecimal() - iTokenDecimal();
|
|
297
|
+
tokenWorth = caseType == true
|
|
298
|
+
? ((_amount / (10**decimalDifference)) * 10**mantissa) / er
|
|
299
|
+
: ((_amount * (10**decimalDifference)) * 10**mantissa) / er; // calculation based on https://compound.finance/docs#protocol-math
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* @dev Set Gas cost to interest collection for this contract
|
|
304
|
+
* @param _collectInterestGasCost Gas cost to collect interest
|
|
305
|
+
* @param _rewardTokenCollectCost gas cost to collect reward tokens
|
|
306
|
+
*/
|
|
307
|
+
function setcollectInterestGasCostParams(
|
|
308
|
+
uint32 _collectInterestGasCost,
|
|
309
|
+
uint32 _rewardTokenCollectCost
|
|
310
|
+
) external {
|
|
311
|
+
_onlyAvatar();
|
|
312
|
+
collectInterestGasCost = _collectInterestGasCost;
|
|
313
|
+
compCollectGasCost = _rewardTokenCollectCost;
|
|
314
|
+
}
|
|
315
|
+
}
|