@gooddollar/goodprotocol 1.0.8 → 1.0.9-beta.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/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/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/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/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 +256 -0
- package/artifacts/contracts/staking/DonationsStaking.sol/DonationsStaking.dbg.json +1 -1
- 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 +1033 -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/AaveStakingFactoryV2.sol/AaveStakingFactoryV2.dbg.json +4 -0
- package/artifacts/contracts/staking/aave/AaveStakingFactoryV2.sol/AaveStakingFactoryV2.json +148 -0
- package/artifacts/contracts/staking/aave/GoodAaveStaking.sol/GoodAaveStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/GoodAaveStakingV2.sol/GoodAaveStakingV2.dbg.json +4 -0
- package/artifacts/contracts/staking/aave/GoodAaveStakingV2.sol/GoodAaveStakingV2.json +1224 -0
- package/artifacts/contracts/staking/compound/CompoundStakingFactory.sol/CompoundStakingFactory.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/GoodCompoundStaking.sol/GoodCompoundStaking.dbg.json +1 -1
- 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 +319 -0
- package/contracts/staking/SimpleStakingV2.sol +522 -0
- package/contracts/staking/aave/AaveStakingFactoryV2.sol +93 -0
- package/contracts/staking/aave/GoodAaveStakingV2.sol +263 -0
- package/package.json +1 -1
- package/test/helpers.ts +5 -1
- package/test/staking/GoodAaveStakingFactoryV2.test.ts +122 -0
- package/test/staking/UsdcAaveStaking.test.ts +5 -1
- package/test/staking/UsdcAaveStakingV2.test.ts +291 -0
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity >=0.8.0;
|
|
3
|
+
import "../Interfaces.sol";
|
|
4
|
+
import "openzeppelin-solidity/contracts/utils/math/Math.sol";
|
|
5
|
+
import "../utils/DSMath.sol";
|
|
6
|
+
|
|
7
|
+
contract BaseShareFieldV2 is DSMath {
|
|
8
|
+
// rewards claimed by users
|
|
9
|
+
uint128 public mintedRewards;
|
|
10
|
+
// number of blocks before reaching the max rewards multiplier (starting at 0.5 reaching 1 after maxMultiplierThreshold)
|
|
11
|
+
uint64 public maxMultiplierThreshold;
|
|
12
|
+
// Staking contracts accepts Tokens with max 18 decimals so this variable holds decimal difference between 18 and Token's decimal in order to make calculations
|
|
13
|
+
uint8 public tokenDecimalDifference;
|
|
14
|
+
// total staked for shares calculation
|
|
15
|
+
uint128 public totalProductivity;
|
|
16
|
+
// total staked that earns rewards (some stakers can donate their rewards)
|
|
17
|
+
uint128 public totalEffectiveStakes;
|
|
18
|
+
// rewards accumulated for distribution
|
|
19
|
+
uint128 public accumulatedRewards;
|
|
20
|
+
// block of last rewards accumulation
|
|
21
|
+
uint128 public lastRewardBlock;
|
|
22
|
+
// accumulated rewards per share in 27 decimals precision
|
|
23
|
+
uint256 public accAmountPerShare;
|
|
24
|
+
|
|
25
|
+
//status of user rewards. everything is in 18 decimals
|
|
26
|
+
struct UserInfo {
|
|
27
|
+
uint128 amount; // How many tokens the user has provided.
|
|
28
|
+
uint128 effectiveStakes; // stakes not including stakes that donate their rewards
|
|
29
|
+
uint128 rewardDebt; // Reward debt.
|
|
30
|
+
uint128 rewardEarn; // Reward earn and not minted
|
|
31
|
+
uint128 rewardMinted; //Rewards minted to user so far
|
|
32
|
+
uint64 lastRewardTime; // Last time that user got rewards
|
|
33
|
+
uint64 multiplierResetTime; // Reset time of multiplier
|
|
34
|
+
}
|
|
35
|
+
mapping(address => UserInfo) public users;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @dev Helper function to check if caller is fund manager
|
|
39
|
+
*/
|
|
40
|
+
function _canMintRewards() internal view virtual {}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @dev Update reward variables of the given pool to be up-to-date.
|
|
44
|
+
* Calculates passed blocks and adding to the reward pool
|
|
45
|
+
* @param rewardsPerBlock how much rewards does this contract earns per block
|
|
46
|
+
* @param blockStart block from which contract starts earning rewards
|
|
47
|
+
* @param blockEnd block from which contract stops earning rewards
|
|
48
|
+
*/
|
|
49
|
+
function _update(
|
|
50
|
+
uint256 rewardsPerBlock,
|
|
51
|
+
uint256 blockStart,
|
|
52
|
+
uint256 blockEnd
|
|
53
|
+
) internal virtual {
|
|
54
|
+
if (totalEffectiveStakes == 0) {
|
|
55
|
+
lastRewardBlock = uint128(block.number);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (block.number >= blockStart && lastRewardBlock < blockStart) {
|
|
59
|
+
lastRewardBlock = uint128(blockStart);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
uint256 _lastRewardBlock = lastRewardBlock < blockStart &&
|
|
63
|
+
block.number >= blockStart
|
|
64
|
+
? blockStart
|
|
65
|
+
: lastRewardBlock;
|
|
66
|
+
uint256 curRewardBlock = block.number > blockEnd ? blockEnd : block.number;
|
|
67
|
+
|
|
68
|
+
if (curRewardBlock < blockStart || _lastRewardBlock >= blockEnd) return;
|
|
69
|
+
|
|
70
|
+
uint256 multiplier = curRewardBlock - _lastRewardBlock; // Blocks passed since last reward block
|
|
71
|
+
uint256 reward = multiplier * (rewardsPerBlock * 1e16); // rewardsPerBlock is in G$ which is only 2 decimals, we turn it into 18 decimals by multiplying 1e16
|
|
72
|
+
|
|
73
|
+
accAmountPerShare =
|
|
74
|
+
accAmountPerShare +
|
|
75
|
+
(reward * 1e27) /
|
|
76
|
+
(totalEffectiveStakes * (10**tokenDecimalDifference));
|
|
77
|
+
// Increase totalEffectiveStakes decimals if it is less than 18 decimals then accAmountPerShare in 27 decimals
|
|
78
|
+
|
|
79
|
+
lastRewardBlock = uint128(curRewardBlock);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @dev Audit user's rewards and calculate their earned rewards
|
|
84
|
+
* For the first month rewards calculated with 0.5x
|
|
85
|
+
* multiplier therefore they just gets half of the rewards which they earned in the first month
|
|
86
|
+
* after first month they get full amount of rewards for the part that they earned after one month
|
|
87
|
+
* @param user the user to audit
|
|
88
|
+
* @param updatedAmount the new stake of the user after deposit/withdraw
|
|
89
|
+
* @param donationPer percentage user is donating from his rewards. (currently just 0 or 100 in SimpleStaking)
|
|
90
|
+
*/
|
|
91
|
+
function _audit(
|
|
92
|
+
address user,
|
|
93
|
+
uint256 updatedAmount,
|
|
94
|
+
uint256 donationPer
|
|
95
|
+
) internal virtual {
|
|
96
|
+
UserInfo storage userInfo = users[user];
|
|
97
|
+
uint256 _amount = userInfo.amount;
|
|
98
|
+
uint256 userEffectiveStake = userInfo.effectiveStakes;
|
|
99
|
+
if (userEffectiveStake > 0) {
|
|
100
|
+
(
|
|
101
|
+
uint256 blocksToPay,
|
|
102
|
+
uint256 firstMonthBlocksToPay,
|
|
103
|
+
uint256 fullBlocksToPay
|
|
104
|
+
) = _auditCalcs(userInfo);
|
|
105
|
+
|
|
106
|
+
if (blocksToPay != 0) {
|
|
107
|
+
uint256 pending = (userEffectiveStake *
|
|
108
|
+
(10**tokenDecimalDifference) *
|
|
109
|
+
accAmountPerShare) /
|
|
110
|
+
1e27 -
|
|
111
|
+
userInfo.rewardDebt;
|
|
112
|
+
// Turn userInfo.amount to 18 decimals by multiplying tokenDecimalDifference if it's not and multiply with accAmountPerShare which is 27 decimals then divide it 1e27 bring it down to 18 decimals
|
|
113
|
+
uint256 rewardPerBlock = (pending * 1e9) / blocksToPay; // bring pending to 1e27
|
|
114
|
+
pending =
|
|
115
|
+
((((firstMonthBlocksToPay * 1e2 * 5) / 10) + fullBlocksToPay * 1e2) * // multiply first month by 0.5x (5/10) since rewards in first month with multiplier 0.5 and multiply it with 1e2 to get it 2decimals so we could get more precision
|
|
116
|
+
rewardPerBlock) / // Multiply fullBlocksToPay with 1e2 to bring it to 2 decimals // rewardPerBlock is in 27decimals
|
|
117
|
+
1e11; // Pending in 18 decimals so we divide 1e11 to bring it down to 18 decimals
|
|
118
|
+
userInfo.rewardEarn = uint128(userInfo.rewardEarn + pending); // Add user's earned rewards to user's account so it can be minted later
|
|
119
|
+
accumulatedRewards = uint128(accumulatedRewards + pending);
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
userInfo.multiplierResetTime = uint64(block.number); // Should set user's multiplierResetTime when they stake for the first time
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
//if withdrawing rewards/stake we reset multiplier, only in case of increasinig productivity we dont reset multiplier
|
|
126
|
+
if (updatedAmount <= _amount) {
|
|
127
|
+
userInfo.multiplierResetTime = uint64(block.number);
|
|
128
|
+
if (_amount > 0) {
|
|
129
|
+
//calculate relative part of user effective stakes
|
|
130
|
+
uint256 withdrawFromEffectiveStake = ((_amount - updatedAmount) *
|
|
131
|
+
userInfo.effectiveStakes) / _amount;
|
|
132
|
+
userInfo.effectiveStakes -= uint128(withdrawFromEffectiveStake);
|
|
133
|
+
totalEffectiveStakes -= uint128(withdrawFromEffectiveStake);
|
|
134
|
+
}
|
|
135
|
+
} else if (donationPer == 0) {
|
|
136
|
+
userInfo.effectiveStakes += uint128(updatedAmount - _amount);
|
|
137
|
+
totalEffectiveStakes += uint128(updatedAmount - _amount);
|
|
138
|
+
}
|
|
139
|
+
userInfo.lastRewardTime = uint64(block.number);
|
|
140
|
+
userInfo.amount = uint128(updatedAmount);
|
|
141
|
+
userInfo.rewardDebt = uint128(
|
|
142
|
+
(userInfo.effectiveStakes *
|
|
143
|
+
(10**tokenDecimalDifference) *
|
|
144
|
+
accAmountPerShare) / 1e27
|
|
145
|
+
); // Divide to 1e27 to keep rewardDebt in 18 decimals since accAmountPerShare is 27 decimals
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @dev Helper function to make calculations in audit and getUserPendingReward methods
|
|
150
|
+
*/
|
|
151
|
+
function _auditCalcs(UserInfo memory _userInfo)
|
|
152
|
+
internal
|
|
153
|
+
view
|
|
154
|
+
returns (
|
|
155
|
+
uint256,
|
|
156
|
+
uint256,
|
|
157
|
+
uint256
|
|
158
|
+
)
|
|
159
|
+
{
|
|
160
|
+
uint256 blocksPaid = _userInfo.lastRewardTime -
|
|
161
|
+
_userInfo.multiplierResetTime; // lastRewardTime is always >= multiplierResetTime
|
|
162
|
+
uint256 blocksPassedFirstMonth = Math.min(
|
|
163
|
+
maxMultiplierThreshold,
|
|
164
|
+
block.number - _userInfo.multiplierResetTime
|
|
165
|
+
);
|
|
166
|
+
// blocks which is after first month
|
|
167
|
+
uint256 blocksToPay = block.number - _userInfo.lastRewardTime; // blocks passed since last payment
|
|
168
|
+
uint256 firstMonthBlocksToPay = blocksPaid >= maxMultiplierThreshold
|
|
169
|
+
? 0
|
|
170
|
+
: blocksPassedFirstMonth - blocksPaid; // block which is in the first month so pays with 0.5x multiplier
|
|
171
|
+
uint256 fullBlocksToPay = blocksToPay - firstMonthBlocksToPay; // blocks to pay in full amount which means with 1x multiplier
|
|
172
|
+
return (blocksToPay, firstMonthBlocksToPay, fullBlocksToPay);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @dev This function increase user's productivity and updates the global productivity.
|
|
177
|
+
* This function increase user's productivity and updates the global productivity.
|
|
178
|
+
* the users' actual share percentage will calculated by:
|
|
179
|
+
* Formula: user_productivity / global_productivity
|
|
180
|
+
* @param user the user to update
|
|
181
|
+
* @param value the increase in user stake
|
|
182
|
+
* @param rewardsPerBlock how much rewards does this contract earns per block
|
|
183
|
+
* @param blockStart block from which contract starts earning rewards
|
|
184
|
+
* @param blockEnd block from which contract stops earning rewards
|
|
185
|
+
* @param donationPer percentage user is donating from his rewards. (currently just 0 or 100 in SimpleStaking)
|
|
186
|
+
*/
|
|
187
|
+
function _increaseProductivity(
|
|
188
|
+
address user,
|
|
189
|
+
uint256 value,
|
|
190
|
+
uint256 rewardsPerBlock,
|
|
191
|
+
uint256 blockStart,
|
|
192
|
+
uint256 blockEnd,
|
|
193
|
+
uint256 donationPer
|
|
194
|
+
) internal virtual returns (bool) {
|
|
195
|
+
_update(rewardsPerBlock, blockStart, blockEnd);
|
|
196
|
+
_audit(user, users[user].amount + value, donationPer);
|
|
197
|
+
|
|
198
|
+
totalProductivity = uint128(totalProductivity + value);
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* @dev This function will decreases user's productivity by value, and updates the global productivity
|
|
204
|
+
* it will record which block this is happenning and accumulates the area of (productivity * time)
|
|
205
|
+
* @param user the user to update
|
|
206
|
+
* @param value the increase in user stake
|
|
207
|
+
* @param rewardsPerBlock how much rewards does this contract earns per block
|
|
208
|
+
* @param blockStart block from which contract starts earning rewards
|
|
209
|
+
* @param blockEnd block from which contract stops earning rewards
|
|
210
|
+
*/
|
|
211
|
+
|
|
212
|
+
function _decreaseProductivity(
|
|
213
|
+
address user,
|
|
214
|
+
uint256 value,
|
|
215
|
+
uint256 rewardsPerBlock,
|
|
216
|
+
uint256 blockStart,
|
|
217
|
+
uint256 blockEnd
|
|
218
|
+
) internal virtual returns (bool) {
|
|
219
|
+
_update(rewardsPerBlock, blockStart, blockEnd);
|
|
220
|
+
_audit(user, users[user].amount - value, 1); // donationPer variable should be something different than zero so called with 1
|
|
221
|
+
totalProductivity = uint128(totalProductivity - value);
|
|
222
|
+
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* @dev Query user's pending reward with updated variables
|
|
228
|
+
* @param user the user to update
|
|
229
|
+
* @param rewardsPerBlock how much rewards does this contract earns per block
|
|
230
|
+
* @param blockStart block from which contract starts earning rewards
|
|
231
|
+
* @param blockEnd block from which contract stops earning rewards
|
|
232
|
+
* @return returns amount of user's earned but not minted rewards
|
|
233
|
+
*/
|
|
234
|
+
function getUserPendingReward(
|
|
235
|
+
address user,
|
|
236
|
+
uint256 rewardsPerBlock,
|
|
237
|
+
uint256 blockStart,
|
|
238
|
+
uint256 blockEnd
|
|
239
|
+
) public view returns (uint256) {
|
|
240
|
+
UserInfo memory userInfo = users[user];
|
|
241
|
+
uint256 _accAmountPerShare = accAmountPerShare;
|
|
242
|
+
|
|
243
|
+
uint256 pending = 0;
|
|
244
|
+
if (
|
|
245
|
+
totalEffectiveStakes != 0 &&
|
|
246
|
+
block.number >= blockStart &&
|
|
247
|
+
blockEnd >= block.number
|
|
248
|
+
) {
|
|
249
|
+
uint256 multiplier = block.number - lastRewardBlock;
|
|
250
|
+
uint256 reward = multiplier * (rewardsPerBlock * 1e16); // turn it to 18 decimals since rewardsPerBlock in 2 decimals
|
|
251
|
+
(
|
|
252
|
+
uint256 blocksToPay,
|
|
253
|
+
uint256 firstMonthBlocksToPay,
|
|
254
|
+
uint256 fullBlocksToPay
|
|
255
|
+
) = _auditCalcs(userInfo);
|
|
256
|
+
|
|
257
|
+
_accAmountPerShare =
|
|
258
|
+
_accAmountPerShare +
|
|
259
|
+
(reward * 1e27) /
|
|
260
|
+
(totalEffectiveStakes * 10**tokenDecimalDifference); // Increase totalEffectiveStakes decimals if it is less than 18 decimals then accAmountPerShare in 27 decimals
|
|
261
|
+
UserInfo memory tempUserInfo = userInfo; // to prevent stack too deep error any other recommendation?
|
|
262
|
+
if (blocksToPay != 0) {
|
|
263
|
+
pending =
|
|
264
|
+
(tempUserInfo.effectiveStakes *
|
|
265
|
+
(10**tokenDecimalDifference) *
|
|
266
|
+
_accAmountPerShare) /
|
|
267
|
+
1e27 -
|
|
268
|
+
tempUserInfo.rewardDebt; // Turn userInfo.amount to 18 decimals by multiplying tokenDecimalDifference if it's not and multiply with accAmountPerShare which is 27 decimals then divide it 1e27 bring it down to 18 decimals
|
|
269
|
+
uint256 rewardPerBlock = (pending * 1e27) / (blocksToPay * 1e18); // bring both variable to 18 decimals and multiply pending by 1e27 so when we divide them to each other result would be in 1e27
|
|
270
|
+
pending =
|
|
271
|
+
((((firstMonthBlocksToPay * 1e2 * 5) / 10) + fullBlocksToPay * 1e2) * // multiply first month by 0.5x (5/10) since rewards in first month with multiplier 0.5 and multiply it with 1e2 to get it 2decimals so we could get more precision
|
|
272
|
+
rewardPerBlock) / // Multiply fullBlocksToPay with 1e2 to bring it to 2decimals // rewardPerBlock is in 27decimals
|
|
273
|
+
1e11; // Pending in 18 decimals so we divide 1e11 to bring it down to 18 decimals
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return userInfo.rewardEarn + pending; // rewardEarn is in 18 decimals
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* @dev When the fundmanager calls this function it will updates the user records
|
|
281
|
+
* get the user rewards which they earned but not minted and mark it as minted
|
|
282
|
+
* @param user the user to update
|
|
283
|
+
* @param rewardsPerBlock how much rewards does this contract earns per block
|
|
284
|
+
* @param blockStart block from which contract starts earning rewards
|
|
285
|
+
* @param blockEnd block from which contract stops earning rewards
|
|
286
|
+
* @return returns amount to mint as reward to the user
|
|
287
|
+
*/
|
|
288
|
+
|
|
289
|
+
function rewardsMinted(
|
|
290
|
+
address user,
|
|
291
|
+
uint256 rewardsPerBlock,
|
|
292
|
+
uint256 blockStart,
|
|
293
|
+
uint256 blockEnd
|
|
294
|
+
) public returns (uint256) {
|
|
295
|
+
UserInfo storage userInfo = users[user];
|
|
296
|
+
_canMintRewards();
|
|
297
|
+
_update(rewardsPerBlock, blockStart, blockEnd);
|
|
298
|
+
_audit(user, userInfo.amount, 1); // donationPer variable should be something different than zero so called with 1
|
|
299
|
+
uint128 amount = userInfo.rewardEarn;
|
|
300
|
+
userInfo.rewardEarn = 0;
|
|
301
|
+
userInfo.rewardMinted += amount;
|
|
302
|
+
mintedRewards = mintedRewards + amount;
|
|
303
|
+
amount = amount / 1e16; // change decimal of mint amount to GD decimals
|
|
304
|
+
return amount;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* @return Returns how many productivity a user has and global has.
|
|
309
|
+
*/
|
|
310
|
+
|
|
311
|
+
function getProductivity(address user)
|
|
312
|
+
public
|
|
313
|
+
view
|
|
314
|
+
virtual
|
|
315
|
+
returns (uint256, uint256)
|
|
316
|
+
{
|
|
317
|
+
return (users[user].amount, totalProductivity);
|
|
318
|
+
}
|
|
319
|
+
}
|