@gooddollar/goodprotocol 2.0.5-beta.7 → 2.0.5-beta.9

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.
Files changed (179) hide show
  1. package/artifacts/abis/IdentityFix.min.json +1 -0
  2. package/artifacts/abis/IdentityV2.min.json +1 -1
  3. package/artifacts/abis/UBISchemeV2.min.json +1 -0
  4. package/artifacts/contracts/DAOStackInterfaces.sol/Avatar.dbg.json +1 -1
  5. package/artifacts/contracts/DAOStackInterfaces.sol/Controller.dbg.json +1 -1
  6. package/artifacts/contracts/DAOStackInterfaces.sol/GlobalConstraintInterface.dbg.json +1 -1
  7. package/artifacts/contracts/DAOStackInterfaces.sol/IntVoteInterface.dbg.json +1 -1
  8. package/artifacts/contracts/DAOStackInterfaces.sol/ReputationInterface.dbg.json +1 -1
  9. package/artifacts/contracts/DAOStackInterfaces.sol/SchemeRegistrar.dbg.json +1 -1
  10. package/artifacts/contracts/Interfaces.sol/AggregatorV3Interface.dbg.json +1 -1
  11. package/artifacts/contracts/Interfaces.sol/ERC20.dbg.json +1 -1
  12. package/artifacts/contracts/Interfaces.sol/IAaveIncentivesController.dbg.json +1 -1
  13. package/artifacts/contracts/Interfaces.sol/IAdminWallet.dbg.json +1 -1
  14. package/artifacts/contracts/Interfaces.sol/IDonationStaking.dbg.json +1 -1
  15. package/artifacts/contracts/Interfaces.sol/IERC2917.dbg.json +1 -1
  16. package/artifacts/contracts/Interfaces.sol/IFirstClaimPool.dbg.json +1 -1
  17. package/artifacts/contracts/Interfaces.sol/IGoodDollar.dbg.json +1 -1
  18. package/artifacts/contracts/Interfaces.sol/IGoodStaking.dbg.json +1 -1
  19. package/artifacts/contracts/Interfaces.sol/IHasRouter.dbg.json +1 -1
  20. package/artifacts/contracts/Interfaces.sol/IIdentity.dbg.json +1 -1
  21. package/artifacts/contracts/Interfaces.sol/IIdentityV2.dbg.json +1 -1
  22. package/artifacts/contracts/Interfaces.sol/ILendingPool.dbg.json +1 -1
  23. package/artifacts/contracts/Interfaces.sol/IMultichainRouter.dbg.json +1 -1
  24. package/artifacts/contracts/Interfaces.sol/INameService.dbg.json +1 -1
  25. package/artifacts/contracts/Interfaces.sol/IUBIScheme.dbg.json +1 -1
  26. package/artifacts/contracts/Interfaces.sol/ProxyAdmin.dbg.json +1 -1
  27. package/artifacts/contracts/Interfaces.sol/Reserve.dbg.json +1 -1
  28. package/artifacts/contracts/Interfaces.sol/Staking.dbg.json +1 -1
  29. package/artifacts/contracts/Interfaces.sol/Uniswap.dbg.json +1 -1
  30. package/artifacts/contracts/Interfaces.sol/UniswapFactory.dbg.json +1 -1
  31. package/artifacts/contracts/Interfaces.sol/UniswapPair.dbg.json +1 -1
  32. package/artifacts/contracts/Interfaces.sol/cERC20.dbg.json +1 -1
  33. package/artifacts/contracts/fuseFaucet/Faucet.sol/Faucet.dbg.json +1 -1
  34. package/artifacts/contracts/fuseFaucet/FuseFaucet.sol/FuseFaucet.dbg.json +1 -1
  35. package/artifacts/contracts/fuseFaucet/FuseFaucetV2.sol/FuseFaucetV2.dbg.json +1 -1
  36. package/artifacts/contracts/governance/ClaimersDistribution.sol/ClaimersDistribution.dbg.json +1 -1
  37. package/artifacts/contracts/governance/CompoundVotingMachine.sol/CompoundVotingMachine.dbg.json +1 -1
  38. package/artifacts/contracts/governance/GReputation.sol/GReputation.dbg.json +1 -1
  39. package/artifacts/contracts/governance/GoodDollarStaking.sol/GoodDollarStaking.dbg.json +1 -1
  40. package/artifacts/contracts/governance/GoodDollarStaking.sol/IGovernanceStaking.dbg.json +1 -1
  41. package/artifacts/contracts/governance/GoodDollarStaking.sol/IStakingUpgrade.dbg.json +1 -1
  42. package/artifacts/contracts/governance/GoodDollarStaking.sol/RewardsMinter.dbg.json +1 -1
  43. package/artifacts/contracts/governance/GovernanceStaking.sol/GovernanceStaking.dbg.json +1 -1
  44. package/artifacts/contracts/governance/MultiBaseGovernanceShareField.sol/MultiBaseGovernanceShareField.dbg.json +1 -1
  45. package/artifacts/contracts/governance/Reputation.sol/Reputation.dbg.json +1 -1
  46. package/artifacts/contracts/governance/StakersDistribution.sol/StakersDistribution.dbg.json +1 -1
  47. package/artifacts/contracts/identity/IdentityV2.sol/IdentityV2.dbg.json +1 -1
  48. package/artifacts/contracts/identity/IdentityV2.sol/IdentityV2.json +20 -2
  49. package/artifacts/contracts/invite/InvitesFuseV2.sol/InvitesFuseV2.dbg.json +1 -1
  50. package/artifacts/contracts/invite/InvitesV1.sol/InvitesV1.dbg.json +1 -1
  51. package/artifacts/contracts/invite/InvitesV2.sol/InvitesV2.dbg.json +1 -1
  52. package/artifacts/contracts/mocks/AaveMock.sol/AaveMock.dbg.json +1 -1
  53. package/artifacts/contracts/mocks/AaveUSDMockOracle.sol/AaveUSDMockOracle.dbg.json +1 -1
  54. package/artifacts/contracts/mocks/BatUSDMockOracle.sol/BatUSDMockOracle.dbg.json +1 -1
  55. package/artifacts/contracts/mocks/CompUsdMockOracle.sol/CompUSDMockOracle.dbg.json +1 -1
  56. package/artifacts/contracts/mocks/DAIMock.sol/DAIMock.dbg.json +1 -1
  57. package/artifacts/contracts/mocks/DaiEthPriceMockOracle.sol/DaiEthPriceMockOracle.dbg.json +1 -1
  58. package/artifacts/contracts/mocks/DecimalsMock.sol/DecimalsMock.dbg.json +1 -1
  59. package/artifacts/contracts/mocks/DistributionBridgeMock.sol/DistributionBridgeMock.dbg.json +1 -1
  60. package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTest.dbg.json +1 -1
  61. package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTestHelper.dbg.json +1 -1
  62. package/artifacts/contracts/mocks/EthUSDMockOracle.sol/EthUSDMockOracle.dbg.json +1 -1
  63. package/artifacts/contracts/mocks/FeesFormularMock.sol/FeesFormulaMock.dbg.json +1 -1
  64. package/artifacts/contracts/mocks/GasPriceMockOracle.sol/GasPriceMockOracle.dbg.json +1 -1
  65. package/artifacts/contracts/mocks/GoodCompoundStakingTest.sol/GoodCompoundStakingTest.dbg.json +1 -1
  66. package/artifacts/contracts/mocks/GoodDollarStakingMock.sol/GoodDollarStakingMock.dbg.json +1 -1
  67. package/artifacts/contracts/mocks/GoodFundManagerTest.sol/GoodFundManagerTest.dbg.json +1 -1
  68. package/artifacts/contracts/mocks/IdentityMock.sol/IdentityMock.dbg.json +1 -1
  69. package/artifacts/contracts/mocks/IncentiveControllerMock.sol/IncentiveControllerMock.dbg.json +1 -1
  70. package/artifacts/contracts/mocks/LendingPoolMock.sol/LendingPoolMock.dbg.json +1 -1
  71. package/artifacts/contracts/mocks/MultichainRouterMock.sol/IWrapper.dbg.json +1 -1
  72. package/artifacts/contracts/mocks/MultichainRouterMock.sol/MultichainRouterMock.dbg.json +1 -1
  73. package/artifacts/contracts/mocks/OverMintTester.sol/IGoodDollarStakingTest.dbg.json +1 -1
  74. package/artifacts/contracts/mocks/OverMintTester.sol/OverMintTester.dbg.json +1 -1
  75. package/artifacts/contracts/mocks/OverMintTesterRegularStake.sol/OverMintTesterRegularStake.dbg.json +1 -1
  76. package/artifacts/contracts/mocks/PayableMock.sol/PayableMock.dbg.json +1 -1
  77. package/artifacts/contracts/mocks/SixteenDecimalsTokenMock.sol/SixteenDecimalsTokenMock.dbg.json +1 -1
  78. package/artifacts/contracts/mocks/StakingMockFixedAPY.sol/StakingMockFixedAPY.dbg.json +1 -1
  79. package/artifacts/contracts/mocks/SwapHelperTest.sol/SwapHelperTest.dbg.json +1 -1
  80. package/artifacts/contracts/mocks/TwentyDecimalsTokenMock.sol/TwentyDecimalsTokenMock.dbg.json +1 -1
  81. package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock.dbg.json +1 -1
  82. package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock2.dbg.json +1 -1
  83. package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock3.dbg.json +1 -1
  84. package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock4.dbg.json +1 -1
  85. package/artifacts/contracts/mocks/UsdcMock.sol/USDCMock.dbg.json +1 -1
  86. package/artifacts/contracts/mocks/cBATMock.sol/cBATMock.dbg.json +1 -1
  87. package/artifacts/contracts/mocks/cDAILowWorthMock.sol/cDAILowWorthMock.dbg.json +1 -1
  88. package/artifacts/contracts/mocks/cDAIMock.sol/cDAIMock.dbg.json +1 -1
  89. package/artifacts/contracts/mocks/cDAINonMintableMock.sol/cDAINonMintableMock.dbg.json +1 -1
  90. package/artifacts/contracts/mocks/cDecimalsMock.sol/cDecimalsMock.dbg.json +1 -1
  91. package/artifacts/contracts/mocks/cSDTMock.sol/cSDTMock.dbg.json +1 -1
  92. package/artifacts/contracts/mocks/cUSDCMock.sol/cUSDCMock.dbg.json +1 -1
  93. package/artifacts/contracts/reserve/DistributionHelper.sol/DistributionHelper.dbg.json +1 -1
  94. package/artifacts/contracts/reserve/ExchangeHelper.sol/ExchangeHelper.dbg.json +1 -1
  95. package/artifacts/contracts/reserve/GoodMarketMaker.sol/GoodMarketMaker.dbg.json +1 -1
  96. package/artifacts/contracts/reserve/GoodReserveCDai.sol/ContributionCalc.dbg.json +1 -1
  97. package/artifacts/contracts/reserve/GoodReserveCDai.sol/GoodReserveCDai.dbg.json +1 -1
  98. package/artifacts/contracts/staking/BaseShareField.sol/BaseShareField.dbg.json +1 -1
  99. package/artifacts/contracts/staking/BaseShareFieldV2.sol/BaseShareFieldV2.dbg.json +1 -1
  100. package/artifacts/contracts/staking/DonationsStaking.sol/DonationsStaking.dbg.json +1 -1
  101. package/artifacts/contracts/staking/FuseStakingV3.sol/FuseStakingV3.dbg.json +1 -1
  102. package/artifacts/contracts/staking/FuseStakingV3.sol/IConsensus.dbg.json +1 -1
  103. package/artifacts/contracts/staking/FuseStakingV3.sol/PegSwap.dbg.json +1 -1
  104. package/artifacts/contracts/staking/GoodFundManager.sol/GoodFundManager.dbg.json +1 -1
  105. package/artifacts/contracts/staking/SimpleStaking.sol/SimpleStaking.dbg.json +1 -1
  106. package/artifacts/contracts/staking/SimpleStakingV2.sol/SimpleStakingV2.dbg.json +1 -1
  107. package/artifacts/contracts/staking/UniswapV2SwapHelper.sol/UniswapV2SwapHelper.dbg.json +1 -1
  108. package/artifacts/contracts/staking/aave/AaveStakingFactory.sol/AaveStakingFactory.dbg.json +1 -1
  109. package/artifacts/contracts/staking/aave/GoodAaveStaking.sol/GoodAaveStaking.dbg.json +1 -1
  110. package/artifacts/contracts/staking/aave/GoodAaveStakingV2.sol/GoodAaveStakingV2.dbg.json +1 -1
  111. package/artifacts/contracts/staking/compound/CompoundStakingFactory.sol/CompoundStakingFactory.dbg.json +1 -1
  112. package/artifacts/contracts/staking/compound/GoodCompoundStaking.sol/GoodCompoundStaking.dbg.json +1 -1
  113. package/artifacts/contracts/staking/compound/GoodCompoundStakingV2.sol/GoodCompoundStakingV2.dbg.json +1 -1
  114. package/artifacts/contracts/staking/utils/Math64X64.sol/Math64x64.dbg.json +1 -1
  115. package/artifacts/contracts/staking/utils/StakingRewardsFixedAPY.sol/StakingRewardsFixedAPY.dbg.json +1 -1
  116. package/artifacts/contracts/token/ERC20PresetMinterPauserUpgradeable.sol/ERC20PresetMinterPauserUpgradeable.dbg.json +1 -1
  117. package/artifacts/contracts/token/ERC677.sol/ERC677.dbg.json +1 -1
  118. package/artifacts/contracts/token/ERC677.sol/ERC677Receiver.dbg.json +1 -1
  119. package/artifacts/contracts/token/FeesFormula.sol/IFeesFormula.dbg.json +1 -1
  120. package/artifacts/contracts/token/GoodDollar.sol/GoodDollar.dbg.json +1 -1
  121. package/artifacts/contracts/token/superfluid/ERC20Permit.sol/ERC20Permit.dbg.json +1 -1
  122. package/artifacts/contracts/token/superfluid/ERC20Permit.sol/SelfApprove.dbg.json +1 -1
  123. package/artifacts/contracts/token/superfluid/ISuperGoodDollar.sol/IGoodDollarCustom.dbg.json +1 -1
  124. package/artifacts/contracts/token/superfluid/ISuperGoodDollar.sol/ISuperGoodDollar.dbg.json +1 -1
  125. package/artifacts/contracts/token/superfluid/SuperGoodDollar.sol/SuperGoodDollar.dbg.json +1 -1
  126. package/artifacts/contracts/token/superfluid/SuperToken.sol/SuperToken.dbg.json +1 -1
  127. package/artifacts/contracts/token/superfluid/SuperfluidToken.sol/SuperfluidToken.dbg.json +1 -1
  128. package/artifacts/contracts/token/superfluid/UUPSProxiable.sol/UUPSProxiable.dbg.json +1 -1
  129. package/artifacts/contracts/token/superfluid/UUPSProxy.sol/Proxy.dbg.json +1 -1
  130. package/artifacts/contracts/token/superfluid/UUPSProxy.sol/UUPSProxy.dbg.json +1 -1
  131. package/artifacts/contracts/token/superfluid/UUPSProxy.sol/UUPSUtils.dbg.json +1 -1
  132. package/artifacts/contracts/ubi/UBIScheme.sol/UBIScheme.dbg.json +1 -1
  133. package/artifacts/contracts/ubi/UBISchemeV2.sol/UBISchemeV2.dbg.json +4 -0
  134. package/artifacts/contracts/ubi/UBISchemeV2.sol/UBISchemeV2.json +789 -0
  135. package/artifacts/contracts/utils/AdminWallet.sol/AdminWallet.dbg.json +1 -1
  136. package/artifacts/contracts/utils/AdminWalletFuse.sol/AdminWalletFuse.dbg.json +1 -1
  137. package/artifacts/contracts/utils/BancorFormula.sol/BancorFormula.dbg.json +1 -1
  138. package/artifacts/contracts/utils/BulkProof.sol/BulkProof.dbg.json +1 -1
  139. package/artifacts/contracts/utils/BuyAndBridgeHelper.sol/BuyAndBridgeHelper.dbg.json +1 -1
  140. package/artifacts/contracts/utils/DAOContract.sol/DAOContract.dbg.json +1 -1
  141. package/artifacts/contracts/utils/DAOUpgradeableContract.sol/DAOUpgradeableContract.dbg.json +1 -1
  142. package/artifacts/contracts/utils/DSMath.sol/DSMath.dbg.json +1 -1
  143. package/artifacts/contracts/utils/DataTypes.sol/DataTypes.dbg.json +1 -1
  144. package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/GoodDollarMintBurnWrapper.dbg.json +1 -1
  145. package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/IRouter.dbg.json +1 -1
  146. package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/PausableControl.dbg.json +1 -1
  147. package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/TokenOperation.dbg.json +1 -1
  148. package/artifacts/contracts/utils/IdentityFix.sol/IdentityFix.dbg.json +4 -0
  149. package/artifacts/contracts/utils/IdentityFix.sol/IdentityFix.json +60 -0
  150. package/artifacts/contracts/utils/MultiCall.sol/Multicall.dbg.json +1 -1
  151. package/artifacts/contracts/utils/MultichainBridgeHelper.sol/MultichainBridgeHelper.dbg.json +1 -1
  152. package/artifacts/contracts/utils/NameService.sol/NameService.dbg.json +1 -1
  153. package/artifacts/contracts/utils/OneTimePayments.sol/OneTimePayments.dbg.json +1 -1
  154. package/artifacts/contracts/utils/OneTimePaymentsV2.sol/OneTimePaymentsV2.dbg.json +1 -1
  155. package/artifacts/contracts/utils/ProtocolUpgrade.sol/OldMarketMaker.dbg.json +1 -1
  156. package/artifacts/contracts/utils/ProtocolUpgrade.sol/ProtocolUpgrade.dbg.json +1 -1
  157. package/artifacts/contracts/utils/ProtocolUpgradeFuse.sol/ProtocolUpgradeFuse.dbg.json +1 -1
  158. package/artifacts/contracts/utils/ProtocolUpgradeFuseRecover.sol/ProtocolUpgradeFuseRecover.dbg.json +1 -1
  159. package/artifacts/contracts/utils/ProtocolUpgradeRecover.sol/ProtocolUpgradeRecover.dbg.json +1 -1
  160. package/artifacts/contracts/utils/ProxyFactory1967.sol/ERC1967Proxy.dbg.json +1 -1
  161. package/artifacts/contracts/utils/ProxyFactory1967.sol/ProxyFactory1967.dbg.json +1 -1
  162. package/artifacts/contracts/utils/ReputationTestHelper.sol/ReputationTestHelper.dbg.json +1 -1
  163. package/contracts/identity/IdentityV2.sol +52 -61
  164. package/contracts/ubi/UBISchemeV2.sol +470 -0
  165. package/contracts/utils/IdentityFix.sol +31 -0
  166. package/package.json +6 -5
  167. package/scripts/analytics/activeUsersCount.ts +56 -18
  168. package/scripts/analytics/whitelistsyncIssue.ts +87 -0
  169. package/scripts/multichain-deploy/helpers.ts +8 -6
  170. package/scripts/proposals/gip-14_1.ts +5 -9
  171. package/types/IdentityFix.ts +141 -0
  172. package/types/IdentityV2.ts +39 -0
  173. package/types/UBISchemeV2.ts +1192 -0
  174. package/types/factories/IdentityFix__factory.ts +110 -0
  175. package/types/factories/IdentityV2__factory.ts +19 -1
  176. package/types/factories/UBISchemeV2__factory.ts +837 -0
  177. package/types/hardhat.d.ts +18 -0
  178. package/types/index.ts +4 -0
  179. package/yarn.lock +22498 -20326
@@ -0,0 +1,470 @@
1
+ // SPDX-License-Identifier: MIXED
2
+
3
+ // License-Identifier: MIT
4
+ pragma solidity >=0.8.0;
5
+
6
+ import "../utils/DAOUpgradeableContract.sol";
7
+ import "../utils/NameService.sol";
8
+ import "../Interfaces.sol";
9
+ import "../governance/ClaimersDistribution.sol";
10
+
11
+ // import "hardhat/console.sol";
12
+
13
+ /* @title Dynamic amount-per-day UBI scheme allowing claim once a day
14
+ * V2 does not keep active user count but adds a "reserve factor" of new claimers based on previous day claimers
15
+ */
16
+ contract UBISchemeV2 is DAOUpgradeableContract {
17
+ struct Day {
18
+ mapping(address => bool) hasClaimed;
19
+ uint256 amountOfClaimers;
20
+ uint256 claimAmount;
21
+ }
22
+
23
+ //daily statistics
24
+ mapping(uint256 => Day) public claimDay;
25
+
26
+ //last ubi claim of user
27
+ mapping(address => uint256) public lastClaimed;
28
+
29
+ //current day since start of contract
30
+ uint256 public currentDay;
31
+
32
+ //starting date of contract, used to determine the hour where daily ubi cycle starts
33
+ uint256 public periodStart;
34
+
35
+ // Result of distribution formula
36
+ // calculated each day
37
+ uint256 public dailyUbi;
38
+
39
+ // Limits the gas for each iteration at `fishMulti`
40
+ uint256 private iterationGasLimit_unused;
41
+
42
+ // Tracks the active users number. It changes when
43
+ // a new user claim for the first time or when a user
44
+ // has been fished
45
+ uint256 private activeUsersCount_unused;
46
+
47
+ // Tracks the last withdrawal day of funds from avatar.
48
+ // Withdraw occures on the first daily claim or the
49
+ // first daily fish only
50
+ uint256 public lastWithdrawDay;
51
+
52
+ // How long can a user be inactive.
53
+ // After those days the user can be fished
54
+ // (see `fish` notes)
55
+ uint256 private maxInactiveDays_unused;
56
+
57
+ // Whether to withdraw GD from avatar
58
+ // before daily ubi calculation
59
+ bool public shouldWithdrawFromDAO;
60
+
61
+ //number of days of each UBI pool cycle
62
+ //dailyPool = Pool/cycleLength
63
+ uint256 public cycleLength;
64
+
65
+ //the amount of G$ UBI pool for each day in the cycle to be divided by active users
66
+ uint256 public dailyCyclePool;
67
+
68
+ //timestamp of current cycle start
69
+ uint256 public startOfCycle;
70
+
71
+ //should be 0 for starters so distributionFormula detects new cycle on first day claim
72
+ uint256 public currentCycleLength;
73
+
74
+ //dont use first claim, and give ubi as usual
75
+ bool private useFirstClaimPool_unused;
76
+
77
+ //minimum amount of users to divide the pool for, renamed from defaultDailyUbi
78
+ uint256 public minActiveUsers;
79
+
80
+ // A pool of GD to give to activated users,
81
+ // since they will enter the UBI pool
82
+ // calculations only in the next day,
83
+ // meaning they can only claim in the next
84
+ // day
85
+ IFirstClaimPool private firstClaimPool_unused;
86
+
87
+ struct Funds {
88
+ // marks if the funds for a specific day has
89
+ // withdrawn from avatar
90
+ bool hasWithdrawn;
91
+ // total GD held after withdrawing
92
+ uint256 openAmount;
93
+ }
94
+
95
+ // Tracks the daily withdraws and the actual amount
96
+ // at the begining of a trading day
97
+ mapping(uint256 => Funds) public dailyUBIHistory;
98
+
99
+ // Marks users that have been fished to avoid
100
+ // double fishing
101
+ mapping(address => bool) private fishedUsersAddresses_unused;
102
+
103
+ // Total claims per user stat
104
+ mapping(address => uint256) public totalClaimsPerUser;
105
+
106
+ bool public paused;
107
+
108
+ uint32 public reserveFactor;
109
+
110
+ // Emits when a withdraw has been succeded
111
+ event WithdrawFromDao(uint256 prevBalance, uint256 newBalance);
112
+
113
+ // Emits when daily ubi is calculated
114
+ event UBICalculated(uint256 day, uint256 dailyUbi, uint256 blockNumber);
115
+
116
+ //Emits whenever a new multi day cycle starts
117
+ event UBICycleCalculated(
118
+ uint256 day,
119
+ uint256 pool,
120
+ uint256 cycleLength,
121
+ uint256 dailyUBIPool
122
+ );
123
+
124
+ event UBIClaimed(address indexed claimer, uint256 amount);
125
+ event CycleLengthSet(uint256 newCycleLength);
126
+ event DaySet(uint256 newDay);
127
+ event ShouldWithdrawFromDAOSet(bool ShouldWithdrawFromDAO);
128
+
129
+ /**
130
+ * @dev Constructor
131
+ * @param _ns the DAO
132
+ * @param _maxInactiveDays Days of grace without claiming request
133
+ */
134
+ function initialize(
135
+ INameService _ns,
136
+ uint256 _maxInactiveDays
137
+ ) public initializer {
138
+ require(_maxInactiveDays > 0, "Max inactive days cannot be zero");
139
+ setDAO(_ns);
140
+ shouldWithdrawFromDAO = false;
141
+ cycleLength = 30; //30 days
142
+ periodStart = (block.timestamp / (1 days)) * 1 days + 12 hours; //set start time to GMT noon
143
+ startOfCycle = periodStart;
144
+ minActiveUsers = 1000;
145
+ reserveFactor = 500;
146
+ }
147
+
148
+ /**
149
+ * @dev function that gets the amount of people who claimed on the given day
150
+ * @param day the day to get claimer count from, with 0 being the starting day
151
+ * @return an integer indicating the amount of people who claimed that day
152
+ */
153
+ function getClaimerCount(uint256 day) public view returns (uint256) {
154
+ return claimDay[day].amountOfClaimers;
155
+ }
156
+
157
+ /**
158
+ * @dev function that gets the amount that was claimed on the given day
159
+ * @param day the day to get claimer count from, with 0 being the starting day
160
+ * @return an integer indicating the amount that has been claimed on the given day
161
+ */
162
+ function getClaimAmount(uint256 day) public view returns (uint256) {
163
+ return claimDay[day].claimAmount;
164
+ }
165
+
166
+ /**
167
+ * @dev function that gets count of claimers and amount claimed for the current day
168
+ * @return the count of claimers and the amount claimed.
169
+ */
170
+ function getDailyStats() public view returns (uint256, uint256) {
171
+ uint256 today = (block.timestamp - periodStart) / 1 days;
172
+ return (getClaimerCount(today), getClaimAmount(today));
173
+ }
174
+
175
+ modifier requireStarted() {
176
+ require(
177
+ paused == false && periodStart > 0 && block.timestamp >= periodStart,
178
+ "not in periodStarted or paused"
179
+ );
180
+ _;
181
+ }
182
+
183
+ /**
184
+ * @dev On a daily basis UBIScheme withdraws tokens from GoodDao.
185
+ * Emits event with caller address and last day balance and the
186
+ * updated balance.
187
+ */
188
+ function _withdrawFromDao() internal {
189
+ IGoodDollar token = nativeToken();
190
+ uint256 prevBalance = token.balanceOf(address(this));
191
+ uint256 toWithdraw = token.balanceOf(address(avatar));
192
+ dao.genericCall(
193
+ address(token),
194
+ abi.encodeWithSignature(
195
+ "transfer(address,uint256)",
196
+ address(this),
197
+ toWithdraw
198
+ ),
199
+ address(avatar),
200
+ 0
201
+ );
202
+ uint256 newBalance = prevBalance + toWithdraw;
203
+ require(
204
+ newBalance == token.balanceOf(address(this)),
205
+ "DAO transfer has failed"
206
+ );
207
+ emit WithdrawFromDao(prevBalance, newBalance);
208
+ }
209
+
210
+ /**
211
+ * @dev sets the ubi calculation cycle length
212
+ * @param _newLength the new length in days
213
+ */
214
+ function setCycleLength(uint256 _newLength) public {
215
+ _onlyAvatar();
216
+ require(_newLength > 0, "cycle must be at least 1 day long");
217
+ cycleLength = _newLength;
218
+ currentCycleLength = 0; //this will trigger a distributionFormula on next claim day
219
+ emit CycleLengthSet(_newLength);
220
+ }
221
+
222
+ /**
223
+ * @dev returns the day count since start of current cycle
224
+ */
225
+ function currentDayInCycle() public view returns (uint256) {
226
+ return (block.timestamp - startOfCycle) / (1 days);
227
+ }
228
+
229
+ /**
230
+ * @dev The claim calculation formula. Divide the daily pool with
231
+ * the sum of the active users.
232
+ * the daily balance is determined by dividing current pool by the cycle length
233
+ * @return The amount of GoodDollar the user can claim
234
+ */
235
+ function distributionFormula() internal returns (uint256) {
236
+ setDay();
237
+ // on first day or once in 24 hrs calculate distribution
238
+ if (currentDay != lastWithdrawDay || dailyUbi == 0) {
239
+ IGoodDollar token = nativeToken();
240
+ uint256 currentBalance = token.balanceOf(address(this));
241
+ //start early cycle if daily pool size is +-%5 previous pool
242
+ uint256 nextDailyPool = currentBalance / cycleLength;
243
+ bool shouldStartEarlyCycle = nextDailyPool >
244
+ (dailyCyclePool * 105) / 100 ||
245
+ nextDailyPool < (dailyCyclePool * 95) / 100;
246
+
247
+ if (
248
+ currentDayInCycle() >= currentCycleLength || shouldStartEarlyCycle
249
+ ) //start of cycle or first time
250
+ {
251
+ if (shouldWithdrawFromDAO) {
252
+ _withdrawFromDao();
253
+ currentBalance = token.balanceOf(address(this));
254
+ }
255
+ dailyCyclePool = nextDailyPool;
256
+ currentCycleLength = cycleLength;
257
+ startOfCycle = (block.timestamp / (1 hours)) * 1 hours; //start at a round hour
258
+ emit UBICycleCalculated(
259
+ currentDay,
260
+ currentBalance,
261
+ cycleLength,
262
+ dailyCyclePool
263
+ );
264
+ }
265
+
266
+ uint256 prevDayClaimers = claimDay[lastWithdrawDay].amountOfClaimers;
267
+ lastWithdrawDay = currentDay;
268
+ Funds storage funds = dailyUBIHistory[currentDay];
269
+ funds.hasWithdrawn = shouldWithdrawFromDAO;
270
+ funds.openAmount = currentBalance;
271
+ dailyUbi =
272
+ dailyCyclePool /
273
+ max((prevDayClaimers * reserveFactor) / 10000, minActiveUsers);
274
+ //update minActiveUsers as claimers grow
275
+ minActiveUsers = max(prevDayClaimers / 2, minActiveUsers);
276
+
277
+ emit UBICalculated(currentDay, dailyUbi, block.number);
278
+ }
279
+
280
+ return dailyUbi;
281
+ }
282
+
283
+ function max(uint256 a, uint256 b) private pure returns (uint256) {
284
+ return a >= b ? a : b;
285
+ }
286
+
287
+ /**
288
+ *@dev Sets the currentDay variable to amount of days
289
+ * since start of contract.
290
+ */
291
+ function setDay() public {
292
+ uint256 day = (block.timestamp - periodStart) / (1 days);
293
+ if (day > currentDay) {
294
+ currentDay = day;
295
+ emit DaySet(day);
296
+ }
297
+ }
298
+
299
+ /**
300
+ * @dev Checks if the given account has claimed today
301
+ * @param account to check
302
+ * @return True if the given user has already claimed today
303
+ */
304
+ function hasClaimed(address account) public view returns (bool) {
305
+ return claimDay[currentDay].hasClaimed[account];
306
+ }
307
+
308
+ /**
309
+ * @dev Checks if the given account has been owned by a registered user.
310
+ * @param _account to check
311
+ * @return True for an existing user. False for a new user
312
+ */
313
+ function isNotNewUser(address _account) public view returns (bool) {
314
+ if (lastClaimed[_account] > 0) {
315
+ // the sender is not registered
316
+ return true;
317
+ }
318
+ return false;
319
+ }
320
+
321
+ /**
322
+ * @dev Transfers `amount` DAO tokens to `account`. Updates stats
323
+ * and emits an event in case of claimed.
324
+ * In case that `isFirstTime` is true, it awards the user.
325
+ * @param _account the account which recieves the funds
326
+ * @param _target the recipient of funds
327
+ * @param _amount the amount to transfer
328
+ */
329
+ function _transferTokens(
330
+ address _account,
331
+ address _target,
332
+ uint256 _amount
333
+ ) internal {
334
+ // updates the stats
335
+ claimDay[currentDay].amountOfClaimers += 1;
336
+ claimDay[currentDay].hasClaimed[_account] = true;
337
+ lastClaimed[_account] = block.timestamp;
338
+ totalClaimsPerUser[_account] += 1;
339
+ claimDay[currentDay].claimAmount += _amount;
340
+
341
+ emit UBIClaimed(_account, _amount);
342
+ IGoodDollar token = nativeToken();
343
+ require(token.transfer(_target, _amount), "claim transfer failed");
344
+ }
345
+
346
+ function estimateNextDailyUBI() public view returns (uint256) {
347
+ uint256 currentBalance = nativeToken().balanceOf(address(this));
348
+ //start early cycle if we can increase the daily UBI pool
349
+ uint256 nextDailyPool = currentBalance / cycleLength;
350
+ bool shouldStartEarlyCycle = nextDailyPool > (dailyCyclePool * 105) / 100 ||
351
+ nextDailyPool < (dailyCyclePool * 95) / 100;
352
+
353
+ uint256 _dailyCyclePool = dailyCyclePool;
354
+ uint256 _dailyUbi;
355
+ if (
356
+ (currentDayInCycle() + 1) >= currentCycleLength || shouldStartEarlyCycle
357
+ ) //start of cycle or first time
358
+ {
359
+ _dailyCyclePool = currentBalance / cycleLength;
360
+ }
361
+
362
+ _dailyUbi =
363
+ _dailyCyclePool /
364
+ max(
365
+ (claimDay[currentDay].amountOfClaimers * reserveFactor) / 10000,
366
+ minActiveUsers
367
+ );
368
+
369
+ return _dailyUbi;
370
+ }
371
+
372
+ function checkEntitlement() public view returns (uint256) {
373
+ return checkEntitlement(msg.sender);
374
+ }
375
+
376
+ /**
377
+ * @dev Checks the amount which the sender address is eligible to claim for,
378
+ * regardless if they have been whitelisted or not. In case the user is
379
+ * active, then the current day must be equal to the actual day, i.e. claim
380
+ * or fish has already been executed today.
381
+ * @return The amount of GD tokens the address can claim.
382
+ */
383
+ function checkEntitlement(address _member) public view returns (uint256) {
384
+ if (block.timestamp < periodStart) return 0; //not started
385
+
386
+ // current day has already been updated which means
387
+ // that the dailyUbi has been updated
388
+ if (
389
+ currentDay == (block.timestamp - periodStart) / (1 days) && dailyUbi > 0
390
+ ) {
391
+ return hasClaimed(_member) ? 0 : dailyUbi;
392
+ }
393
+ return estimateNextDailyUBI();
394
+ }
395
+
396
+ /**
397
+ * @dev Function for claiming UBI. Requires contract to be active. Calls distributionFormula,
398
+ * calculats the amount the account can claims, and transfers the amount to the account.
399
+ * Emits the address of account and amount claimed.
400
+ * @param _account The claimer account
401
+ * @param _target recipient of funds
402
+ * @return A bool indicating if UBI was claimed
403
+ */
404
+ function _claim(address _account, address _target) internal returns (bool) {
405
+ // calculats the formula up today ie on day 0 there are no active users, on day 1 any user
406
+ // (new or active) will trigger the calculation with the active users count of the day before
407
+ // and so on. the new or inactive users that will become active today, will not take into account
408
+ // within the calculation.
409
+ uint256 newDistribution = distributionFormula();
410
+
411
+ // active user which has not claimed today yet, ie user last claimed < today
412
+ if (!hasClaimed(_account)) {
413
+ _transferTokens(_account, _target, newDistribution);
414
+ return true;
415
+ }
416
+ return false;
417
+ }
418
+
419
+ /**
420
+ * @dev Function for claiming UBI. Requires contract to be active and claimer to be whitelisted.
421
+ * Calls distributionFormula, calculats the amount the caller can claim, and transfers the amount
422
+ * to the caller. Emits the address of caller and amount claimed.
423
+ * @return A bool indicating if UBI was claimed
424
+ */
425
+ function claim() public requireStarted returns (bool) {
426
+ address whitelistedRoot = IIdentityV2(nameService.getAddress("IDENTITY"))
427
+ .getWhitelistedRoot(msg.sender);
428
+ require(whitelistedRoot != address(0), "UBIScheme: not whitelisted");
429
+ bool didClaim = _claim(whitelistedRoot, msg.sender);
430
+ address claimerDistribution = nameService.getAddress("GDAO_CLAIMERS");
431
+ if (didClaim && claimerDistribution != address(0)) {
432
+ ClaimersDistribution(claimerDistribution).updateClaim(whitelistedRoot);
433
+ }
434
+ return didClaim;
435
+ }
436
+
437
+ /**
438
+ * @dev Sets whether to also withdraw GD from avatar for UBI
439
+ * @param _shouldWithdraw boolean if to withdraw
440
+ */
441
+ function setShouldWithdrawFromDAO(bool _shouldWithdraw) public {
442
+ _onlyAvatar();
443
+ shouldWithdrawFromDAO = _shouldWithdraw;
444
+ emit ShouldWithdrawFromDAOSet(shouldWithdrawFromDAO);
445
+ }
446
+
447
+ function pause(bool _pause) public {
448
+ _onlyAvatar();
449
+ paused = _pause;
450
+ }
451
+
452
+ // function upgrade() public {
453
+ // _onlyAvatar();
454
+ // paused = true;
455
+ // activeUsersCount = 50000; //estimated
456
+ // dailyUbi = 0; //required so distributionformula will trigger
457
+ // cycleLength = 30;
458
+ // currentCycleLength = 0; //this will trigger a new cycle calculation in distribution formula
459
+ // startOfCycle = block.timestamp - 91 days; //this will trigger a new calculation in distributionFormula
460
+ // periodStart = 1646136000;
461
+ // maxDailyUBI = 50000;
462
+ // distributionFormula();
463
+ // emit CycleLengthSet(cycleLength);
464
+ // }
465
+
466
+ function setNewClaimersReserveFactor(uint32 _reserveFactor) public {
467
+ _onlyAvatar();
468
+ reserveFactor = _reserveFactor;
469
+ }
470
+ }
@@ -0,0 +1,31 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity >=0.8.0;
3
+
4
+ import "../identity/IdentityV2.sol";
5
+
6
+ contract IdentityFix {
7
+ IdentityV2 public identity;
8
+
9
+ constructor(IdentityV2 _identity) {
10
+ identity = _identity;
11
+ }
12
+
13
+ function fix(address[] memory addrs, uint256[] memory timestamps) public {
14
+ require(
15
+ identity.hasRole(identity.IDENTITY_ADMIN_ROLE(), msg.sender),
16
+ "not admin"
17
+ );
18
+ for (uint256 i = 0; i < addrs.length; i++) {
19
+ identity.authenticateWithTimestamp(addrs[i], timestamps[i]);
20
+ }
21
+ }
22
+
23
+ function end() public {
24
+ require(
25
+ identity.hasRole(identity.IDENTITY_ADMIN_ROLE(), msg.sender),
26
+ "not admin"
27
+ );
28
+ identity.renounceRole(identity.IDENTITY_ADMIN_ROLE(), address(this));
29
+ selfdestruct(payable(msg.sender));
30
+ }
31
+ }
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@gooddollar/goodprotocol",
3
- "version": "2.0.5-beta.7",
3
+ "version": "2.0.5-beta.9",
4
4
  "description": "GoodDollar Protocol",
5
5
  "scripts": {
6
6
  "prepack": "npm run minimize",
7
7
  "build": "scripts/build.sh deploy",
8
- "coverage:report": "export COVERALLS_REPO_TOKEN='qiXNelh1HXMAsoPah9yRD2yG2WlqrDfLh' && cat ../coverage/lcov.info coverage/lcov.info | coveralls",
9
- "coverage": "export CODE_COVERAGE=true; hardhat --max-memory 6096 coverage",
8
+ "coverage:report": "COVERALLS_REPO_TOKEN='qiXNelh1HXMAsoPah9yRD2yG2WlqrDfLh' cat ../coverage/lcov.info coverage/lcov.info | coveralls",
9
+ "coverage": "CODE_COVERAGE=true hardhat --max-memory 6096 coverage",
10
10
  "minimize": "./scripts/minimize.sh 'artifacts/contracts'",
11
11
  "test": "hardhat test",
12
12
  "test:parallel": "mocha --require hardhat/register --extension ts --recursive --parallel --exit",
@@ -117,11 +117,12 @@
117
117
  "regenerator-runtime": "^0.13.9",
118
118
  "solhint": "*",
119
119
  "solidity-coverage": "^0.8.2",
120
- "truffle": "^5.3.12",
120
+ "truffle": "^5.9.3",
121
121
  "truffle-hdwallet-provider": "*",
122
122
  "ts-generator": "^0.1.1",
123
123
  "ts-node": "^10.8.0",
124
124
  "typechain": "^6.0.2",
125
125
  "typescript": "*"
126
- }
126
+ },
127
+ "packageManager": "yarn@3.6.0"
127
128
  }
@@ -3,14 +3,14 @@ import { ethers as Ethers } from "hardhat";
3
3
  import fetch from "node-fetch";
4
4
 
5
5
  const ONE_DAY = 24 * 60 * 60;
6
+ const ONE_HOUR = 60 * 60;
6
7
 
7
8
  const main = async () => {
8
9
  const signer = (await Ethers.getSigners())[0];
9
10
  console.log("signer:", signer.address);
10
- const ubiScheme = new Ethers.Contract(
11
- "0xD7aC544F8A570C4d8764c3AAbCF6870CBD960D0D",
12
- ["function fishMulti(address[] tofish)"]
13
- ).connect(signer);
11
+ const ubiScheme = new Ethers.Contract("0xD7aC544F8A570C4d8764c3AAbCF6870CBD960D0D", [
12
+ "function fishMulti(address[] tofish)"
13
+ ]).connect(signer);
14
14
  const twoWeeksAgo = parseInt((Date.now() / 1000).toFixed(0)); //
15
15
  //parseInt((Date.now() / 1000).toFixed(0)) - 24 * 60 * 60 * 14;
16
16
 
@@ -28,21 +28,14 @@ const main = async () => {
28
28
  }
29
29
  `;
30
30
 
31
- console.log(
32
- "fetching inactive users since:",
33
- { curDay, day },
34
- JSON.stringify({ query })
35
- );
31
+ console.log("fetching inactive users since:", { curDay, day }, JSON.stringify({ query }));
36
32
  const {
37
33
  data: { walletStats }
38
- } = await fetch(
39
- "https://api.thegraph.com/subgraphs/name/gooddollar/gooddollarfuse",
40
- {
41
- method: "post",
42
- body: JSON.stringify({ query }),
43
- headers: { "Content-Type": "application/json" }
44
- }
45
- ).then(_ => _.json());
34
+ } = await fetch("https://api.thegraph.com/subgraphs/name/gooddollar/gooddollarfuse", {
35
+ method: "post",
36
+ body: JSON.stringify({ query }),
37
+ headers: { "Content-Type": "application/json" }
38
+ }).then(_ => _.json());
46
39
 
47
40
  console.log("got inactive wallets:", walletStats.length);
48
41
  if (walletStats) {
@@ -62,4 +55,49 @@ const main = async () => {
62
55
  console.log("active claimers:", unique.length);
63
56
  };
64
57
 
65
- main();
58
+ const countActive = async () => {
59
+ const twoWeeksAgo = parseInt((Date.now() / 1000).toFixed(0)); //
60
+
61
+ const hoursAgo: number[] = range(0, 24 * 14, 1);
62
+ let curDay = twoWeeksAgo;
63
+ const allActive = [];
64
+ for (let hour of hoursAgo) {
65
+ const query = `
66
+ {
67
+ walletStats(first:1000, where: { lastClaimed_lte: ${curDay},lastClaimed_gt: ${
68
+ curDay - ONE_HOUR
69
+ } isActiveUser: true }) {
70
+ id
71
+ }
72
+ }
73
+ `;
74
+
75
+ console.log("fetching active users since:", { curDay, hour }, JSON.stringify({ query }));
76
+ const {
77
+ data: { walletStats }
78
+ } = await fetch("https://api.thegraph.com/subgraphs/name/gooddollar/gooddollarfuse", {
79
+ method: "post",
80
+ body: JSON.stringify({ query }),
81
+ headers: { "Content-Type": "application/json" }
82
+ }).then(_ => _.json());
83
+
84
+ console.log("got active wallets:", walletStats.length);
85
+ if (walletStats) {
86
+ const accounts = walletStats.map(_ => _.id);
87
+ allActive.push(...accounts);
88
+ }
89
+ // for (let tofish of chunk(accounts, 50)) {
90
+ // const tx = await ubiScheme.fishMulti(tofish, { gasLimit: 2000000 });
91
+ // console.log("fishing tx:", tx, tofish);
92
+ // const res = await tx.wait();
93
+ // console.log("fishing tx result:", res);
94
+ // }
95
+
96
+ curDay = curDay - ONE_HOUR;
97
+ }
98
+ const unique = uniq(allActive);
99
+ console.log("active claimers:", unique.length);
100
+ };
101
+
102
+ //main();
103
+ countActive();