@gooddollar/goodprotocol 2.0.21 → 2.0.22-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.
Files changed (222) hide show
  1. package/artifacts/abis/ISuperToken.min.json +1 -1
  2. package/artifacts/abis/SuperGoodDollar.min.json +1 -1
  3. package/artifacts/abis/SuperToken.min.json +1 -1
  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/invite/InvitesFuseV2.sol/InvitesFuseV2.dbg.json +1 -1
  49. package/artifacts/contracts/invite/InvitesV1.sol/InvitesV1.dbg.json +1 -1
  50. package/artifacts/contracts/invite/InvitesV2.sol/InvitesV2.dbg.json +1 -1
  51. package/artifacts/contracts/mocks/AaveMock.sol/AaveMock.dbg.json +1 -1
  52. package/artifacts/contracts/mocks/AaveUSDMockOracle.sol/AaveUSDMockOracle.dbg.json +1 -1
  53. package/artifacts/contracts/mocks/BatUSDMockOracle.sol/BatUSDMockOracle.dbg.json +1 -1
  54. package/artifacts/contracts/mocks/CompUsdMockOracle.sol/CompUSDMockOracle.dbg.json +1 -1
  55. package/artifacts/contracts/mocks/DAIMock.sol/DAIMock.dbg.json +1 -1
  56. package/artifacts/contracts/mocks/DaiEthPriceMockOracle.sol/DaiEthPriceMockOracle.dbg.json +1 -1
  57. package/artifacts/contracts/mocks/DecimalsMock.sol/DecimalsMock.dbg.json +1 -1
  58. package/artifacts/contracts/mocks/DistributionBridgeMock.sol/DistributionBridgeMock.dbg.json +1 -1
  59. package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTest.dbg.json +1 -1
  60. package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTestHelper.dbg.json +1 -1
  61. package/artifacts/contracts/mocks/EthUSDMockOracle.sol/EthUSDMockOracle.dbg.json +1 -1
  62. package/artifacts/contracts/mocks/FeesFormularMock.sol/FeesFormulaMock.dbg.json +1 -1
  63. package/artifacts/contracts/mocks/GasPriceMockOracle.sol/GasPriceMockOracle.dbg.json +1 -1
  64. package/artifacts/contracts/mocks/GoodCompoundStakingTest.sol/GoodCompoundStakingTest.dbg.json +1 -1
  65. package/artifacts/contracts/mocks/GoodDollarStakingMock.sol/GoodDollarStakingMock.dbg.json +1 -1
  66. package/artifacts/contracts/mocks/GoodFundManagerTest.sol/GoodFundManagerTest.dbg.json +1 -1
  67. package/artifacts/contracts/mocks/IdentityMock.sol/IdentityMock.dbg.json +1 -1
  68. package/artifacts/contracts/mocks/IncentiveControllerMock.sol/IncentiveControllerMock.dbg.json +1 -1
  69. package/artifacts/contracts/mocks/LendingPoolMock.sol/LendingPoolMock.dbg.json +1 -1
  70. package/artifacts/contracts/mocks/MultichainRouterMock.sol/IWrapper.dbg.json +1 -1
  71. package/artifacts/contracts/mocks/MultichainRouterMock.sol/MultichainRouterMock.dbg.json +1 -1
  72. package/artifacts/contracts/mocks/OverMintTester.sol/IGoodDollarStakingTest.dbg.json +1 -1
  73. package/artifacts/contracts/mocks/OverMintTester.sol/OverMintTester.dbg.json +1 -1
  74. package/artifacts/contracts/mocks/OverMintTesterRegularStake.sol/OverMintTesterRegularStake.dbg.json +1 -1
  75. package/artifacts/contracts/mocks/PayableMock.sol/PayableMock.dbg.json +1 -1
  76. package/artifacts/contracts/mocks/SixteenDecimalsTokenMock.sol/SixteenDecimalsTokenMock.dbg.json +1 -1
  77. package/artifacts/contracts/mocks/StakingMockFixedAPY.sol/StakingMockFixedAPY.dbg.json +1 -1
  78. package/artifacts/contracts/mocks/SwapHelperTest.sol/SwapHelperTest.dbg.json +1 -1
  79. package/artifacts/contracts/mocks/TwentyDecimalsTokenMock.sol/TwentyDecimalsTokenMock.dbg.json +1 -1
  80. package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock.dbg.json +1 -1
  81. package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock2.dbg.json +1 -1
  82. package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock3.dbg.json +1 -1
  83. package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock4.dbg.json +1 -1
  84. package/artifacts/contracts/mocks/UsdcMock.sol/USDCMock.dbg.json +1 -1
  85. package/artifacts/contracts/mocks/cBATMock.sol/cBATMock.dbg.json +1 -1
  86. package/artifacts/contracts/mocks/cDAILowWorthMock.sol/cDAILowWorthMock.dbg.json +1 -1
  87. package/artifacts/contracts/mocks/cDAIMock.sol/cDAIMock.dbg.json +1 -1
  88. package/artifacts/contracts/mocks/cDAINonMintableMock.sol/cDAINonMintableMock.dbg.json +1 -1
  89. package/artifacts/contracts/mocks/cDecimalsMock.sol/cDecimalsMock.dbg.json +1 -1
  90. package/artifacts/contracts/mocks/cSDTMock.sol/cSDTMock.dbg.json +1 -1
  91. package/artifacts/contracts/mocks/cUSDCMock.sol/cUSDCMock.dbg.json +1 -1
  92. package/artifacts/contracts/reserve/DistributionHelper.sol/DistributionHelper.dbg.json +1 -1
  93. package/artifacts/contracts/reserve/ExchangeHelper.sol/ExchangeHelper.dbg.json +1 -1
  94. package/artifacts/contracts/reserve/GoodMarketMaker.sol/GoodMarketMaker.dbg.json +1 -1
  95. package/artifacts/contracts/reserve/GoodReserveCDai.sol/ContributionCalc.dbg.json +1 -1
  96. package/artifacts/contracts/reserve/GoodReserveCDai.sol/GoodReserveCDai.dbg.json +1 -1
  97. package/artifacts/contracts/staking/BaseShareField.sol/BaseShareField.dbg.json +1 -1
  98. package/artifacts/contracts/staking/BaseShareFieldV2.sol/BaseShareFieldV2.dbg.json +1 -1
  99. package/artifacts/contracts/staking/DonationsStaking.sol/DonationsStaking.dbg.json +1 -1
  100. package/artifacts/contracts/staking/FuseStakingV3.sol/FuseStakingV3.dbg.json +1 -1
  101. package/artifacts/contracts/staking/FuseStakingV3.sol/IConsensus.dbg.json +1 -1
  102. package/artifacts/contracts/staking/FuseStakingV3.sol/PegSwap.dbg.json +1 -1
  103. package/artifacts/contracts/staking/GoodFundManager.sol/GoodFundManager.dbg.json +1 -1
  104. package/artifacts/contracts/staking/SimpleStaking.sol/SimpleStaking.dbg.json +1 -1
  105. package/artifacts/contracts/staking/SimpleStakingV2.sol/SimpleStakingV2.dbg.json +1 -1
  106. package/artifacts/contracts/staking/UniswapV2SwapHelper.sol/UniswapV2SwapHelper.dbg.json +1 -1
  107. package/artifacts/contracts/staking/aave/AaveStakingFactory.sol/AaveStakingFactory.dbg.json +1 -1
  108. package/artifacts/contracts/staking/aave/GoodAaveStaking.sol/GoodAaveStaking.dbg.json +1 -1
  109. package/artifacts/contracts/staking/aave/GoodAaveStakingV2.sol/GoodAaveStakingV2.dbg.json +1 -1
  110. package/artifacts/contracts/staking/compound/CompoundStakingFactory.sol/CompoundStakingFactory.dbg.json +1 -1
  111. package/artifacts/contracts/staking/compound/GoodCompoundStaking.sol/GoodCompoundStaking.dbg.json +1 -1
  112. package/artifacts/contracts/staking/compound/GoodCompoundStakingV2.sol/GoodCompoundStakingV2.dbg.json +1 -1
  113. package/artifacts/contracts/staking/utils/Math64X64.sol/Math64x64.dbg.json +1 -1
  114. package/artifacts/contracts/staking/utils/StakingRewardsFixedAPY.sol/StakingRewardsFixedAPY.dbg.json +1 -1
  115. package/artifacts/contracts/token/ERC20PresetMinterPauserUpgradeable.sol/ERC20PresetMinterPauserUpgradeable.dbg.json +1 -1
  116. package/artifacts/contracts/token/ERC677.sol/ERC677.dbg.json +1 -1
  117. package/artifacts/contracts/token/ERC677.sol/ERC677Receiver.dbg.json +1 -1
  118. package/artifacts/contracts/token/GoodDollar.sol/GoodDollar.dbg.json +1 -1
  119. package/artifacts/contracts/token/IFeesFormula.sol/IFeesFormula.dbg.json +1 -1
  120. package/artifacts/contracts/token/MultichainFeeFormula.sol/MultichainFeeFormula.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/ISuperToken.sol/ISuperToken.dbg.json +1 -1
  126. package/artifacts/contracts/token/superfluid/ISuperToken.sol/ISuperToken.json +5 -0
  127. package/artifacts/contracts/token/superfluid/SuperGoodDollar.sol/SuperGoodDollar.dbg.json +1 -1
  128. package/artifacts/contracts/token/superfluid/SuperGoodDollar.sol/SuperGoodDollar.json +25 -2
  129. package/artifacts/contracts/token/superfluid/SuperToken.sol/SuperToken.dbg.json +1 -1
  130. package/artifacts/contracts/token/superfluid/SuperToken.sol/SuperToken.json +7 -2
  131. package/artifacts/contracts/token/superfluid/SuperfluidToken.sol/SuperfluidToken.dbg.json +1 -1
  132. package/artifacts/contracts/token/superfluid/UUPSProxiable.sol/UUPSProxiable.dbg.json +1 -1
  133. package/artifacts/contracts/token/superfluid/UUPSProxy.sol/Proxy.dbg.json +1 -1
  134. package/artifacts/contracts/token/superfluid/UUPSProxy.sol/UUPSProxy.dbg.json +1 -1
  135. package/artifacts/contracts/token/superfluid/UUPSProxy.sol/UUPSUtils.dbg.json +1 -1
  136. package/artifacts/contracts/ubi/UBIScheme.sol/UBIScheme.dbg.json +1 -1
  137. package/artifacts/contracts/ubi/UBISchemeV2.sol/UBISchemeV2.dbg.json +1 -1
  138. package/artifacts/contracts/utils/AdminWallet.sol/AdminWallet.dbg.json +1 -1
  139. package/artifacts/contracts/utils/AdminWalletFuse.sol/AdminWalletFuse.dbg.json +1 -1
  140. package/artifacts/contracts/utils/BancorFormula.sol/BancorFormula.dbg.json +1 -1
  141. package/artifacts/contracts/utils/BulkProof.sol/BulkProof.dbg.json +1 -1
  142. package/artifacts/contracts/utils/BuyAndBridgeHelper.sol/BuyAndBridgeHelper.dbg.json +1 -1
  143. package/artifacts/contracts/utils/BuyGDClone.sol/BuyGDClone.dbg.json +1 -1
  144. package/artifacts/contracts/utils/BuyGDClone.sol/BuyGDCloneFactory.dbg.json +1 -1
  145. package/artifacts/contracts/utils/BuyGDClone.sol/DonateGDClone.dbg.json +1 -1
  146. package/artifacts/contracts/utils/BuyGDClone.sol/IQuoterV2.dbg.json +1 -1
  147. package/artifacts/contracts/utils/BuyGDClone.sol/ISwapRouter.dbg.json +1 -1
  148. package/artifacts/contracts/utils/DAOContract.sol/DAOContract.dbg.json +1 -1
  149. package/artifacts/contracts/utils/DAOUpgradeableContract.sol/DAOUpgradeableContract.dbg.json +1 -1
  150. package/artifacts/contracts/utils/DSMath.sol/DSMath.dbg.json +1 -1
  151. package/artifacts/contracts/utils/DataTypes.sol/DataTypes.dbg.json +1 -1
  152. package/artifacts/contracts/utils/GDFaucet.sol/GDFaucet.dbg.json +1 -1
  153. package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/GoodDollarMintBurnWrapper.dbg.json +1 -1
  154. package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/IRouter.dbg.json +1 -1
  155. package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/PausableControl.dbg.json +1 -1
  156. package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/TokenOperation.dbg.json +1 -1
  157. package/artifacts/contracts/utils/IdentityFix.sol/IdentityFix.dbg.json +1 -1
  158. package/artifacts/contracts/utils/MultiCall.sol/Multicall.dbg.json +1 -1
  159. package/artifacts/contracts/utils/MultichainBridgeHelper.sol/MultichainBridgeHelper.dbg.json +1 -1
  160. package/artifacts/contracts/utils/NameService.sol/NameService.dbg.json +1 -1
  161. package/artifacts/contracts/utils/OneTimePayments.sol/OneTimePayments.dbg.json +1 -1
  162. package/artifacts/contracts/utils/OneTimePaymentsV2.sol/OneTimePaymentsV2.dbg.json +1 -1
  163. package/artifacts/contracts/utils/ProtocolUpgrade.sol/OldMarketMaker.dbg.json +1 -1
  164. package/artifacts/contracts/utils/ProtocolUpgrade.sol/ProtocolUpgrade.dbg.json +1 -1
  165. package/artifacts/contracts/utils/ProtocolUpgradeFuse.sol/ProtocolUpgradeFuse.dbg.json +1 -1
  166. package/artifacts/contracts/utils/ProtocolUpgradeFuseRecover.sol/ProtocolUpgradeFuseRecover.dbg.json +1 -1
  167. package/artifacts/contracts/utils/ProtocolUpgradeRecover.sol/ProtocolUpgradeRecover.dbg.json +1 -1
  168. package/artifacts/contracts/utils/ProxyFactory1967.sol/ERC1967Proxy.dbg.json +1 -1
  169. package/artifacts/contracts/utils/ProxyFactory1967.sol/ProxyFactory1967.dbg.json +1 -1
  170. package/artifacts/contracts/utils/ReputationTestHelper.sol/ReputationTestHelper.dbg.json +1 -1
  171. package/contracts/token/superfluid/ISuperToken.sol +1 -0
  172. package/contracts/token/superfluid/SuperGoodDollar.sol +11 -2
  173. package/contracts/token/superfluid/SuperToken.sol +8 -0
  174. package/dist/artifacts/contracts/token/superfluid/SuperGoodDollar.sol/SuperGoodDollar.json +25 -2
  175. package/hardhat.config.ts +1 -1
  176. package/package.json +4 -3
  177. package/scripts/blockchainTestSetup.sh +1 -1
  178. package/test/faucet/Faucet.test.ts +63 -19
  179. package/test/faucet/FuseFaucet.test.ts +43 -14
  180. package/test/governance/ClaimersDistribution.test.ts +3 -3
  181. package/test/governance/CompoundVotingMachine.castvote.test.ts +3 -6
  182. package/test/governance/CompoundVotingMachine.crossblockchain.ts +2 -2
  183. package/test/governance/CompoundVotingMachine.daoscheme.ts +1 -1
  184. package/test/governance/CompoundVotingMachine.guardian.test.ts +4 -4
  185. package/test/governance/CompoundVotingMachine.propose.test.ts +8 -8
  186. package/test/governance/CompoundVotingMachine.state.test.ts +4 -4
  187. package/test/governance/GReputation.test.ts +6 -6
  188. package/test/governance/GoodDollarStaking.gd.test.ts +44 -71
  189. package/test/governance/GoodDollarStaking.good.test.ts +52 -73
  190. package/test/governance/GovernanceStaking.test.ts +1 -1
  191. package/test/governance/Reputation.test.ts +2 -2
  192. package/test/helpers.ts +1 -1
  193. package/test/identity/IdentityV2.test.ts +12 -12
  194. package/test/invite/InvitesV1.test.ts +6 -6
  195. package/test/invite/InvitesV2.test.ts +272 -81
  196. package/test/reserve/DistributionHelper.test.ts +232 -139
  197. package/test/reserve/GoodMarketMaker.test.ts +17 -17
  198. package/test/reserve/GoodReserveCDai.cap.test.ts +4 -4
  199. package/test/reserve/GoodReserveCDai.distribution.test.ts +64 -42
  200. package/test/reserve/GoodReserveCDai.gdx.test.ts +1 -1
  201. package/test/reserve/GoodReserveCDai.pause.test.ts +8 -8
  202. package/test/reserve/GoodReserveCDai.test.ts +307 -101
  203. package/test/reserve/GoodReserveCDai.uniswap.test.ts +1 -1
  204. package/test/staking/DonationsStaking.test.ts +2 -2
  205. package/test/staking/FuseStaking.test.ts +3 -3
  206. package/test/staking/GoodAaveStakingFactory.test.ts +2 -2
  207. package/test/staking/StakingRewards.test.ts +913 -320
  208. package/test/staking/StakingRewardsFixedAPY.test.ts +62 -66
  209. package/test/token/CeloGasToken.test.ts +2 -2
  210. package/test/token/GoodDollar.test.ts +5 -5
  211. package/test/token/SuperGoodDollar.test.ts +17 -13
  212. package/test/ubi/UBIScheme.test.ts +1 -1
  213. package/test/utils/AdminWallet.test.ts +10 -10
  214. package/test/utils/BuyAndBridgeHelper.test.ts +33 -9
  215. package/test/utils/GoodDollarMintBurnWrapper.test.ts +265 -113
  216. package/test/utils/NameService.test.ts +1 -1
  217. package/test/utils/ProxyFactory.test.ts +2 -2
  218. package/types/contracts/token/superfluid/SuperGoodDollar.ts +26 -0
  219. package/types/factories/contracts/token/superfluid/ISuperToken__factory.ts +5 -0
  220. package/types/factories/contracts/token/superfluid/SuperGoodDollar__factory.ts +24 -1
  221. package/types/factories/contracts/token/superfluid/SuperToken__factory.ts +6 -1
  222. package/yarn.lock +635 -253
@@ -3,7 +3,13 @@ import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
3
3
  import { BigNumber, Contract } from "ethers";
4
4
  import { expect } from "chai";
5
5
  import { GoodMarketMaker } from "../../types";
6
- import { createDAO, increaseTime, advanceBlocks, deployUniswap, getStakingFactory } from "../helpers";
6
+ import {
7
+ createDAO,
8
+ increaseTime,
9
+ advanceBlocks,
10
+ deployUniswap,
11
+ getStakingFactory
12
+ } from "../helpers";
7
13
  import ContributionCalculation from "@gooddollar/goodcontracts/stakingModel/build/contracts/ContributionCalculation.json";
8
14
  import IUniswapV2Pair from "@uniswap/v2-core/build/IUniswapV2Pair.json";
9
15
  const BN = ethers.BigNumber;
@@ -66,9 +72,15 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
66
72
 
67
73
  const cdaiFactory = await ethers.getContractFactory("cDAIMock");
68
74
  const cBatFactory = await ethers.getContractFactory("cBATMock");
69
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
70
- goodCompoundStakingFactory = await getStakingFactory("GoodCompoundStakingV2");
71
- goodCompoundStakingTestFactory = await getStakingFactory("GoodCompoundStakingTest");
75
+ const goodFundManagerFactory = await ethers.getContractFactory(
76
+ "GoodFundManager"
77
+ );
78
+ goodCompoundStakingFactory = await getStakingFactory(
79
+ "GoodCompoundStakingV2"
80
+ );
81
+ goodCompoundStakingTestFactory = await getStakingFactory(
82
+ "GoodCompoundStakingTest"
83
+ );
72
84
 
73
85
  const daiFactory = await ethers.getContractFactory("DAIMock");
74
86
 
@@ -93,9 +105,13 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
93
105
  controller,
94
106
  avatar
95
107
  });
96
- goodFundManager = await upgrades.deployProxy(goodFundManagerFactory, [nameService.address], {
97
- kind: "uups"
98
- });
108
+ goodFundManager = await upgrades.deployProxy(
109
+ goodFundManagerFactory,
110
+ [nameService.address],
111
+ {
112
+ kind: "uups"
113
+ }
114
+ );
99
115
  await setDAOAddress("FUND_MANAGER", goodFundManager.address);
100
116
  console.log("Deployed goodfund manager", {
101
117
  manager: goodFundManager.address
@@ -113,11 +129,15 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
113
129
  });
114
130
 
115
131
  console.log("setting permissions...");
116
- const tokenUsdOracleFactory = await ethers.getContractFactory("BatUSDMockOracle");
132
+ const tokenUsdOracleFactory = await ethers.getContractFactory(
133
+ "BatUSDMockOracle"
134
+ );
117
135
  await setDAOAddress("UNISWAP_ROUTER", uniswapRouter.address);
118
136
 
119
137
  daiUsdOracle = await tokenUsdOracleFactory.deploy();
120
- const compUsdOracleFactory = await ethers.getContractFactory("CompUSDMockOracle");
138
+ const compUsdOracleFactory = await ethers.getContractFactory(
139
+ "CompUSDMockOracle"
140
+ );
121
141
  compUsdOracle = await compUsdOracleFactory.deploy();
122
142
 
123
143
  deployStaking = (token, itoken, blocksThreashold = "50") =>
@@ -141,9 +161,13 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
141
161
  console.log("initializing marketmaker...");
142
162
 
143
163
  cDAI1 = await cdaiFactory.deploy(dai.address);
144
- const cdaiLowWorthFactory = await ethers.getContractFactory("cDAILowWorthMock");
164
+ const cdaiLowWorthFactory = await ethers.getContractFactory(
165
+ "cDAILowWorthMock"
166
+ );
145
167
  cDAI2 = await cdaiLowWorthFactory.deploy(dai.address);
146
- const cdaiNonMintableFactory = await ethers.getContractFactory("cDAINonMintableMock");
168
+ const cdaiNonMintableFactory = await ethers.getContractFactory(
169
+ "cDAINonMintableMock"
170
+ );
147
171
  cDAI3 = await cdaiNonMintableFactory.deploy(dai.address);
148
172
  bat = await daiFactory.deploy(); // Another erc20 token for uniswap router test
149
173
  cBat = await cBatFactory.deploy(bat.address);
@@ -168,45 +192,82 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
168
192
 
169
193
  await factory.createPair(bat.address, dai.address); // Create tokenA and dai pair
170
194
  const pairAddress = factory.getPair(bat.address, dai.address);
171
- pair = new Contract(pairAddress, JSON.stringify(IUniswapV2Pair.abi), staker).connect(founder);
195
+ pair = new Contract(
196
+ pairAddress,
197
+ JSON.stringify(IUniswapV2Pair.abi),
198
+ staker
199
+ ).connect(founder);
172
200
  await setDAOAddress("CDAI", cDAI.address);
173
201
  await setDAOAddress("DAI", dai.address);
174
202
 
175
203
  batUsdOracle = await tokenUsdOracleFactory.deploy();
176
204
 
177
- await dai["mint(address,uint256)"](founder.address, ethers.utils.parseEther("2000000"));
178
- await bat["mint(address,uint256)"](founder.address, ethers.utils.parseEther("2000000"));
205
+ await dai["mint(address,uint256)"](
206
+ founder.address,
207
+ ethers.utils.parseEther("2000000")
208
+ );
209
+ await bat["mint(address,uint256)"](
210
+ founder.address,
211
+ ethers.utils.parseEther("2000000")
212
+ );
179
213
 
180
- await addLiquidity(ethers.utils.parseEther("2000000"), ethers.utils.parseEther("2000000"));
214
+ await addLiquidity(
215
+ ethers.utils.parseEther("2000000"),
216
+ ethers.utils.parseEther("2000000")
217
+ );
181
218
 
182
- gasFeeOracle = await ethers.getContractAt("GasPriceMockOracle", await nameService.getAddress("GAS_PRICE_ORACLE"));
183
- daiEthOracle = await ethers.getContractAt("DaiEthPriceMockOracle", await nameService.getAddress("DAI_ETH_ORACLE"));
219
+ gasFeeOracle = await ethers.getContractAt(
220
+ "GasPriceMockOracle",
221
+ await nameService.getAddress("GAS_PRICE_ORACLE")
222
+ );
223
+ daiEthOracle = await ethers.getContractAt(
224
+ "DaiEthPriceMockOracle",
225
+ await nameService.getAddress("DAI_ETH_ORACLE")
226
+ );
184
227
  await setDAOAddress("MARKET_MAKER", marketMaker.address);
185
228
  });
186
229
 
187
230
  it("should be set rewards per block for particular stacking contract", async () => {
188
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
231
+ const goodFundManagerFactory = await ethers.getContractFactory(
232
+ "GoodFundManager"
233
+ );
189
234
  const currentBlockNumber = await ethers.provider.getBlockNumber();
190
235
  const encodedData = goodFundManagerFactory.interface.encodeFunctionData(
191
236
  "setStakingReward",
192
- ["1000", goodCompoundStaking.address, currentBlockNumber - 5, currentBlockNumber + 10, false] // set 10 gd per block
237
+ [
238
+ "1000",
239
+ goodCompoundStaking.address,
240
+ currentBlockNumber - 5,
241
+ currentBlockNumber + 10,
242
+ false
243
+ ] // set 10 gd per block
193
244
  );
194
245
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
195
- let rewardPerBlock = await goodFundManager.rewardsForStakingContract(goodCompoundStaking.address);
246
+ let rewardPerBlock = await goodFundManager.rewardsForStakingContract(
247
+ goodCompoundStaking.address
248
+ );
196
249
  expect(rewardPerBlock[0].toString()).to.be.equal("1000");
197
- expect(rewardPerBlock[1].toString()).to.be.equal((currentBlockNumber - 5).toString());
198
- expect(rewardPerBlock[2].toString()).to.be.equal((currentBlockNumber + 10).toString());
250
+ expect(rewardPerBlock[1].toString()).to.be.equal(
251
+ (currentBlockNumber - 5).toString()
252
+ );
253
+ expect(rewardPerBlock[2].toString()).to.be.equal(
254
+ (currentBlockNumber + 10).toString()
255
+ );
199
256
  expect(rewardPerBlock[3]).to.be.equal(false);
200
257
  });
201
258
 
202
259
  it("should be able to earn rewards after some block passed", async () => {
203
260
  let stakingAmount = ethers.utils.parseEther("100");
204
261
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
205
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
262
+ await dai
263
+ .connect(staker)
264
+ .approve(goodCompoundStaking.address, stakingAmount);
206
265
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 0, false);
207
266
  let gdBalanceBeforeWithdraw = await goodDollar.balanceOf(staker.address);
208
267
  await advanceBlocks(4);
209
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
268
+ await goodCompoundStaking
269
+ .connect(staker)
270
+ .withdrawStake(stakingAmount, false);
210
271
  let gdBalancerAfterWithdraw = await goodDollar.balanceOf(staker.address);
211
272
  expect(gdBalancerAfterWithdraw.toString()).to.be.equal("2500");
212
273
  });
@@ -215,78 +276,142 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
215
276
  const stakingAmount = ethers.utils.parseEther("100");
216
277
 
217
278
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
218
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount.mul(BN.from("2")));
279
+ await dai
280
+ .connect(staker)
281
+ .approve(goodCompoundStaking.address, stakingAmount.mul(BN.from("2")));
219
282
 
220
283
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 0, false);
221
284
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 100, false);
222
- const userStakeInfoBeforeWithdraw = await goodCompoundStaking.users(staker.address);
223
- expect(userStakeInfoBeforeWithdraw.effectiveStakes).to.be.equal(stakingAmount);
224
- expect(userStakeInfoBeforeWithdraw.amount).to.be.equal(stakingAmount.mul(BN.from("2")));
225
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
226
- const userStakeInfoAfterWithdraw = await goodCompoundStaking.users(staker.address);
227
- expect(userStakeInfoAfterWithdraw.effectiveStakes).to.be.equal(stakingAmount.div(BN.from("2"))); // should be half of the stakes that staked initially
285
+ const userStakeInfoBeforeWithdraw = await goodCompoundStaking.users(
286
+ staker.address
287
+ );
288
+ expect(userStakeInfoBeforeWithdraw.effectiveStakes).to.be.equal(
289
+ stakingAmount
290
+ );
291
+ expect(userStakeInfoBeforeWithdraw.amount).to.be.equal(
292
+ stakingAmount.mul(BN.from("2"))
293
+ );
294
+ await goodCompoundStaking
295
+ .connect(staker)
296
+ .withdrawStake(stakingAmount, false);
297
+ const userStakeInfoAfterWithdraw = await goodCompoundStaking.users(
298
+ staker.address
299
+ );
300
+ expect(userStakeInfoAfterWithdraw.effectiveStakes).to.be.equal(
301
+ stakingAmount.div(BN.from("2"))
302
+ ); // should be half of the stakes that staked initially
228
303
  expect(userStakeInfoAfterWithdraw.amount).to.be.equal(stakingAmount);
229
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
304
+ await goodCompoundStaking
305
+ .connect(staker)
306
+ .withdrawStake(stakingAmount, false);
230
307
  });
231
308
  it("it should not increase totalEffectiveStakes when staked amount's rewards are donated", async () => {
232
309
  const stakingAmount = ethers.utils.parseEther("100");
233
310
 
234
311
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
235
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
236
- const totalEffectiveStakesBeforeStake = await goodCompoundStaking.getStats().then(_ => _[3]);
312
+ await dai
313
+ .connect(staker)
314
+ .approve(goodCompoundStaking.address, stakingAmount);
315
+ const totalEffectiveStakesBeforeStake = await goodCompoundStaking
316
+ .getStats()
317
+ .then(_ => _[3]);
237
318
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 100, false);
238
- const totalEffectiveStakesAfterStake = await goodCompoundStaking.getStats().then(_ => _[3]);
239
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
240
- expect(totalEffectiveStakesAfterStake).to.be.equal(totalEffectiveStakesBeforeStake);
319
+ const totalEffectiveStakesAfterStake = await goodCompoundStaking
320
+ .getStats()
321
+ .then(_ => _[3]);
322
+ await goodCompoundStaking
323
+ .connect(staker)
324
+ .withdrawStake(stakingAmount, false);
325
+ expect(totalEffectiveStakesAfterStake).to.be.equal(
326
+ totalEffectiveStakesBeforeStake
327
+ );
241
328
  });
242
329
  it("it should increase totalEffectiveStakes when staked without donation", async () => {
243
330
  const stakingAmount = ethers.utils.parseEther("100");
244
331
 
245
332
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
246
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
247
- const totalEffectiveStakesBeforeStake = await goodCompoundStaking.getStats().then(_ => _[3]);
333
+ await dai
334
+ .connect(staker)
335
+ .approve(goodCompoundStaking.address, stakingAmount);
336
+ const totalEffectiveStakesBeforeStake = await goodCompoundStaking
337
+ .getStats()
338
+ .then(_ => _[3]);
248
339
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 0, false);
249
- const totalEffectiveStakesAfterStake = await goodCompoundStaking.getStats().then(_ => _[3]);
250
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
251
- expect(totalEffectiveStakesAfterStake).to.be.gt(totalEffectiveStakesBeforeStake);
340
+ const totalEffectiveStakesAfterStake = await goodCompoundStaking
341
+ .getStats()
342
+ .then(_ => _[3]);
343
+ await goodCompoundStaking
344
+ .connect(staker)
345
+ .withdrawStake(stakingAmount, false);
346
+ expect(totalEffectiveStakesAfterStake).to.be.gt(
347
+ totalEffectiveStakesBeforeStake
348
+ );
252
349
  });
253
350
  it("it should withdraw effective and stakes according to ratio", async () => {
254
351
  const stakingAmount = ethers.utils.parseEther("100");
255
352
 
256
353
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
257
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
354
+ await dai
355
+ .connect(staker)
356
+ .approve(goodCompoundStaking.address, stakingAmount);
258
357
 
259
- await goodCompoundStaking.connect(staker).stake(stakingAmount.mul(80).div(100), 0, false);
260
- await goodCompoundStaking.connect(staker).stake(stakingAmount.mul(20).div(100), 100, false);
261
- const userStakeInfoBeforeWithdraw = await goodCompoundStaking.users(staker.address);
358
+ await goodCompoundStaking
359
+ .connect(staker)
360
+ .stake(stakingAmount.mul(80).div(100), 0, false);
361
+ await goodCompoundStaking
362
+ .connect(staker)
363
+ .stake(stakingAmount.mul(20).div(100), 100, false);
364
+ const userStakeInfoBeforeWithdraw = await goodCompoundStaking.users(
365
+ staker.address
366
+ );
262
367
  const withdrawAmount = stakingAmount.mul(20).div(100);
263
368
  const withdrawFromEffectiveStake = withdrawAmount
264
369
  .mul(userStakeInfoBeforeWithdraw.effectiveStakes)
265
370
  .div(userStakeInfoBeforeWithdraw.amount);
266
371
  const withdrawFromDonation = withdrawAmount.sub(withdrawFromEffectiveStake);
267
- await goodCompoundStaking.connect(staker).withdrawStake(withdrawAmount, false);
268
- const userStakeInfoAfterWithdraw = await goodCompoundStaking.users(staker.address);
372
+ await goodCompoundStaking
373
+ .connect(staker)
374
+ .withdrawStake(withdrawAmount, false);
375
+ const userStakeInfoAfterWithdraw = await goodCompoundStaking.users(
376
+ staker.address
377
+ );
269
378
  expect(userStakeInfoBeforeWithdraw.effectiveStakes).to.be.gt(0);
270
379
  expect(userStakeInfoAfterWithdraw.effectiveStakes).to.be.equal(
271
- userStakeInfoBeforeWithdraw.effectiveStakes.sub(withdrawFromEffectiveStake)
380
+ userStakeInfoBeforeWithdraw.effectiveStakes.sub(
381
+ withdrawFromEffectiveStake
382
+ )
272
383
  );
273
- expect(userStakeInfoAfterWithdraw.amount.sub(userStakeInfoAfterWithdraw.effectiveStakes)).to.be.equal(
274
- userStakeInfoBeforeWithdraw.amount.sub(userStakeInfoBeforeWithdraw.effectiveStakes).sub(withdrawFromDonation)
384
+ expect(
385
+ userStakeInfoAfterWithdraw.amount.sub(
386
+ userStakeInfoAfterWithdraw.effectiveStakes
387
+ )
388
+ ).to.be.equal(
389
+ userStakeInfoBeforeWithdraw.amount
390
+ .sub(userStakeInfoBeforeWithdraw.effectiveStakes)
391
+ .sub(withdrawFromDonation)
275
392
  );
276
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount.sub(withdrawAmount), false); // withdraw left amount
393
+ await goodCompoundStaking
394
+ .connect(staker)
395
+ .withdrawStake(stakingAmount.sub(withdrawAmount), false); // withdraw left amount
277
396
  });
278
397
  it("shouldn't be able to earn rewards after rewards blockend passed", async () => {
279
398
  let stakingAmount = ethers.utils.parseEther("100");
280
399
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
281
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
400
+ await dai
401
+ .connect(staker)
402
+ .approve(goodCompoundStaking.address, stakingAmount);
282
403
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 0, false);
283
404
 
284
405
  let gdBalanceBeforeWithdraw = await goodDollar.balanceOf(staker.address);
285
406
  advanceBlocks(5);
286
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
407
+ await goodCompoundStaking
408
+ .connect(staker)
409
+ .withdrawStake(stakingAmount, false);
287
410
  let gdBalancerAfterWithdraw = await goodDollar.balanceOf(staker.address);
288
411
 
289
- expect(gdBalancerAfterWithdraw.toString()).to.be.equal(gdBalanceBeforeWithdraw.toString());
412
+ expect(gdBalancerAfterWithdraw.toString()).to.be.equal(
413
+ gdBalanceBeforeWithdraw.toString()
414
+ );
290
415
  });
291
416
 
292
417
  it("shouldn't be able to mint reward when staking contract is blacklisted", async () => {
@@ -300,7 +425,9 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
300
425
 
301
426
  let stakingAmount = ethers.utils.parseEther("100");
302
427
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
303
- await dai.connect(staker).approve(goodCompoundStaking2.address, stakingAmount);
428
+ await dai
429
+ .connect(staker)
430
+ .approve(goodCompoundStaking2.address, stakingAmount);
304
431
  await goodCompoundStaking2.connect(staker).stake(stakingAmount, 0, false);
305
432
 
306
433
  let gdBalanceBeforeWithdraw = await goodDollar.balanceOf(staker.address);
@@ -312,7 +439,9 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
312
439
  );
313
440
  await genericCall(goodFundManager.address, encodedDataTwo);
314
441
 
315
- await goodCompoundStaking2.connect(staker).withdrawStake(stakingAmount, false);
442
+ await goodCompoundStaking2
443
+ .connect(staker)
444
+ .withdrawStake(stakingAmount, false);
316
445
  let gdBalancerAfterWithdraw = await goodDollar.balanceOf(staker.address);
317
446
 
318
447
  expect(gdBalancerAfterWithdraw).to.be.equal(gdBalanceBeforeWithdraw);
@@ -359,20 +488,34 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
359
488
  it("it should send staker's productivity to some other user", async () => {
360
489
  let stakingAmount = ethers.utils.parseEther("100");
361
490
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
362
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
491
+ await dai
492
+ .connect(staker)
493
+ .approve(goodCompoundStaking.address, stakingAmount);
363
494
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 100, false);
364
- let stakersProductivityBefore = await goodCompoundStaking.getProductivity(staker.address);
365
- await goodCompoundStaking.connect(staker).transfer(founder.address, stakingAmount);
366
- let stakersProductivityAfter = await goodCompoundStaking.connect(staker).getProductivity(staker.address);
367
- let foundersProductivity = await goodCompoundStaking.getProductivity(founder.address);
495
+ let stakersProductivityBefore = await goodCompoundStaking.getProductivity(
496
+ staker.address
497
+ );
498
+ await goodCompoundStaking
499
+ .connect(staker)
500
+ .transfer(founder.address, stakingAmount);
501
+ let stakersProductivityAfter = await goodCompoundStaking
502
+ .connect(staker)
503
+ .getProductivity(staker.address);
504
+ let foundersProductivity = await goodCompoundStaking.getProductivity(
505
+ founder.address
506
+ );
368
507
 
369
508
  expect(stakersProductivityAfter[0].toString()).to.be.equal("0");
370
- expect(foundersProductivity[0].toString()).to.be.equals(stakingAmount.toString());
509
+ expect(foundersProductivity[0].toString()).to.be.equals(
510
+ stakingAmount.toString()
511
+ );
371
512
  });
372
513
 
373
514
  it("it shouldn't be able to withdraw stake when staker sent it to another user", async () => {
374
515
  const stakingAmount = ethers.utils.parseEther("100");
375
- await expect(goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false)).to.be.reverted;
516
+ await expect(
517
+ goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false)
518
+ ).to.be.reverted;
376
519
  });
377
520
 
378
521
  it("it should be able to withdraw their stake when got staking tokens from somebody else", async () => {
@@ -380,7 +523,9 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
380
523
 
381
524
  await goodCompoundStaking.withdrawStake(stakingAmount, false);
382
525
 
383
- const foundersProductivity = await goodCompoundStaking.getProductivity(founder.address);
526
+ const foundersProductivity = await goodCompoundStaking.getProductivity(
527
+ founder.address
528
+ );
384
529
  expect(foundersProductivity[0].toString()).to.be.equal("0");
385
530
  expect(foundersProductivity[1].toString()).to.be.equal("0"); // Total productivity also should equal 0
386
531
  });
@@ -389,43 +534,73 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
389
534
  const stakingAmount = ethers.utils.parseEther("100");
390
535
 
391
536
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
392
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
537
+ await dai
538
+ .connect(staker)
539
+ .approve(goodCompoundStaking.address, stakingAmount);
393
540
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 100, false);
394
541
 
395
- await dai["mint(address,uint256)"](staker.address, ethers.utils.parseEther("1000000"));
396
- await dai.connect(staker).transfer(cDAI.address, ethers.utils.parseEther("1000000")); // We should put extra DAI to mock cDAI contract in order to provide interest
542
+ await dai["mint(address,uint256)"](
543
+ staker.address,
544
+ ethers.utils.parseEther("1000000")
545
+ );
546
+ await dai
547
+ .connect(staker)
548
+ .transfer(cDAI.address, ethers.utils.parseEther("1000000")); // We should put extra DAI to mock cDAI contract in order to provide interest
397
549
  await cDAI.increasePriceWithMultiplier("1500"); // increase interest by calling exchangeRateCurrent
398
550
 
399
- const currentUBIInterestBeforeWithdraw = await goodCompoundStaking.currentGains(false, true);
400
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
401
- const gdBalanceBeforeCollectInterest = await goodDollar.balanceOf(staker.address);
402
- const contractAddressesToBeCollected = await goodFundManager.calcSortedContracts();
551
+ const currentUBIInterestBeforeWithdraw =
552
+ await goodCompoundStaking.currentGains(false, true);
553
+ await goodCompoundStaking
554
+ .connect(staker)
555
+ .withdrawStake(stakingAmount, false);
556
+ const gdBalanceBeforeCollectInterest = await goodDollar.balanceOf(
557
+ staker.address
558
+ );
559
+ const contractAddressesToBeCollected =
560
+ await goodFundManager.calcSortedContracts();
403
561
  const addressesToCollect = contractAddressesToBeCollected.map(x => x[0]);
404
- await goodFundManager.connect(staker).collectInterest(addressesToCollect, false);
405
- const gdBalanceAfterCollectInterest = await goodDollar.balanceOf(staker.address);
406
- const currentUBIInterestAfterWithdraw = await goodCompoundStaking.currentGains(false, true);
562
+ await goodFundManager
563
+ .connect(staker)
564
+ .collectInterest(addressesToCollect, false);
565
+ const gdBalanceAfterCollectInterest = await goodDollar.balanceOf(
566
+ staker.address
567
+ );
568
+ const currentUBIInterestAfterWithdraw =
569
+ await goodCompoundStaking.currentGains(false, true);
407
570
  expect(currentUBIInterestBeforeWithdraw[0].toString()).to.not.be.equal("0");
408
571
  expect(currentUBIInterestAfterWithdraw[0].toString()).to.be.equal("0");
409
572
  expect(gdBalanceAfterCollectInterest.gt(gdBalanceBeforeCollectInterest));
410
573
  });
411
574
 
412
575
  it("it should get rewards with updated values", async () => {
413
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
576
+ const goodFundManagerFactory = await ethers.getContractFactory(
577
+ "GoodFundManager"
578
+ );
414
579
  const currentBlockNumber = await ethers.provider.getBlockNumber();
415
580
  const encodedDataTwo = goodFundManagerFactory.interface.encodeFunctionData(
416
581
  "setStakingReward",
417
- ["1000", goodCompoundStaking.address, currentBlockNumber, currentBlockNumber + 5000, false] // set 10 gd per block
582
+ [
583
+ "1000",
584
+ goodCompoundStaking.address,
585
+ currentBlockNumber,
586
+ currentBlockNumber + 5000,
587
+ false
588
+ ] // set 10 gd per block
418
589
  );
419
590
  await genericCall(goodFundManager.address, encodedDataTwo, avatar, 0);
420
591
 
421
592
  const stakingAmount = ethers.utils.parseEther("100");
422
593
 
423
594
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
424
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
595
+ await dai
596
+ .connect(staker)
597
+ .approve(goodCompoundStaking.address, stakingAmount);
425
598
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 0, false);
426
599
 
427
600
  await advanceBlocks(4);
428
- const stakingContractVals = await goodFundManager.rewardsForStakingContract(goodCompoundStaking.address);
601
+ const stakingContractVals = await goodFundManager.rewardsForStakingContract(
602
+ goodCompoundStaking.address
603
+ );
429
604
  let rewardsEarned = await goodCompoundStaking.getUserPendingReward(
430
605
  staker.address,
431
606
  stakingContractVals[0],
@@ -433,46 +608,71 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
433
608
  stakingContractVals[2]
434
609
  );
435
610
  //baseshare rewards is in 18 decimals
436
- expect(rewardsEarned.toString()).to.be.equal(ethers.utils.parseUnits("20", 18)); // Each block reward is 10gd so total reward 40gd but since multiplier is 0.5 for first month should get 20gd
611
+ expect(rewardsEarned.toString()).to.be.equal(
612
+ ethers.utils.parseUnits("20", 18)
613
+ ); // Each block reward is 10gd so total reward 40gd but since multiplier is 0.5 for first month should get 20gd
437
614
 
438
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
615
+ await goodCompoundStaking
616
+ .connect(staker)
617
+ .withdrawStake(stakingAmount, false);
439
618
  });
440
619
 
441
620
  it("should get user minted and pending rewards", async () => {
442
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
621
+ const goodFundManagerFactory = await ethers.getContractFactory(
622
+ "GoodFundManager"
623
+ );
443
624
  const currentBlockNumber = await ethers.provider.getBlockNumber();
444
625
  const encodedData = goodFundManagerFactory.interface.encodeFunctionData(
445
626
  "setStakingReward",
446
- ["1000", goodCompoundStaking.address, currentBlockNumber, currentBlockNumber + 5000, false] // set 10 gd per block
627
+ [
628
+ "1000",
629
+ goodCompoundStaking.address,
630
+ currentBlockNumber,
631
+ currentBlockNumber + 5000,
632
+ false
633
+ ] // set 10 gd per block
447
634
  );
448
635
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
449
636
 
450
637
  const stakingAmount = ethers.utils.parseEther("100");
451
638
 
452
639
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
453
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
640
+ await dai
641
+ .connect(staker)
642
+ .approve(goodCompoundStaking.address, stakingAmount);
454
643
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 0, false);
455
644
 
456
645
  await advanceBlocks(4);
457
646
 
458
- const userMintedAndPending = await goodCompoundStaking.getUserMintedAndPending(staker.address);
647
+ const userMintedAndPending =
648
+ await goodCompoundStaking.getUserMintedAndPending(staker.address);
459
649
  const userMintedReward = userMintedAndPending[0].toString();
460
650
  const userPendingReward = userMintedAndPending[1].toString();
461
651
  expect(userMintedReward).to.equal("5000");
462
652
  expect(userPendingReward).to.equal("2000");
463
653
 
464
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
654
+ await goodCompoundStaking
655
+ .connect(staker)
656
+ .withdrawStake(stakingAmount, false);
465
657
  });
466
658
 
467
659
  it("it should get rewards with 1x multiplier for after threshold pass", async () => {
468
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
660
+ const goodFundManagerFactory = await ethers.getContractFactory(
661
+ "GoodFundManager"
662
+ );
469
663
 
470
664
  const simpleStaking = await await deployStaking();
471
665
 
472
666
  const currentBlockNumber = await ethers.provider.getBlockNumber();
473
667
  let encodedDataTwo = goodFundManagerFactory.interface.encodeFunctionData(
474
668
  "setStakingReward",
475
- ["1000", simpleStaking.address, currentBlockNumber, currentBlockNumber + 100, false] // set 10 gd per block
669
+ [
670
+ "1000",
671
+ simpleStaking.address,
672
+ currentBlockNumber,
673
+ currentBlockNumber + 100,
674
+ false
675
+ ] // set 10 gd per block
476
676
  );
477
677
  await genericCall(goodFundManager.address, encodedDataTwo, avatar, 0);
478
678
 
@@ -480,17 +680,29 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
480
680
 
481
681
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
482
682
  await dai.connect(staker).approve(simpleStaking.address, stakingAmount);
483
- let gdBalanceStakerBeforeWithdraw = await goodDollar.balanceOf(staker.address);
683
+ let gdBalanceStakerBeforeWithdraw = await goodDollar.balanceOf(
684
+ staker.address
685
+ );
484
686
  await simpleStaking.connect(staker).stake(stakingAmount, 0, false);
485
687
 
486
688
  await advanceBlocks(54);
487
689
  await simpleStaking.connect(staker).withdrawStake(stakingAmount, false);
488
- let gdBalanceStakerAfterWithdraw = await goodDollar.balanceOf(staker.address);
690
+ let gdBalanceStakerAfterWithdraw = await goodDollar.balanceOf(
691
+ staker.address
692
+ );
489
693
 
490
- expect(gdBalanceStakerAfterWithdraw.sub(gdBalanceStakerBeforeWithdraw).toString()).to.be.equal("30000"); // 50 blocks reward worth 500gd but since it's with the 0.5x multiplier so 250gd then there is 5 blocks which gets full reward so total reward is 300gd
694
+ expect(
695
+ gdBalanceStakerAfterWithdraw.sub(gdBalanceStakerBeforeWithdraw).toString()
696
+ ).to.be.equal("30000"); // 50 blocks reward worth 500gd but since it's with the 0.5x multiplier so 250gd then there is 5 blocks which gets full reward so total reward is 300gd
491
697
  encodedDataTwo = goodFundManagerFactory.interface.encodeFunctionData(
492
698
  "setStakingReward",
493
- ["1000", simpleStaking.address, currentBlockNumber, currentBlockNumber + 100, true] // set 10 gd per block
699
+ [
700
+ "1000",
701
+ simpleStaking.address,
702
+ currentBlockNumber,
703
+ currentBlockNumber + 100,
704
+ true
705
+ ] // set 10 gd per block
494
706
  );
495
707
  await genericCall(goodFundManager.address, encodedDataTwo, avatar, 0);
496
708
  });
@@ -499,15 +711,27 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
499
711
  const stakingAmount = ethers.utils.parseEther("100");
500
712
 
501
713
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
502
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
714
+ await dai
715
+ .connect(staker)
716
+ .approve(goodCompoundStaking.address, stakingAmount);
503
717
 
504
718
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 100, false);
505
- await goodCompoundStaking.connect(staker).approve(founder.address, stakingAmount);
506
- const stakingTokenBalanceBeforeTransfer = await goodCompoundStaking.balanceOf(founder.address);
507
- await goodCompoundStaking.transferFrom(staker.address, founder.address, stakingAmount);
508
- const stakingTokenBalanceAfterTransfer = await goodCompoundStaking.balanceOf(founder.address);
719
+ await goodCompoundStaking
720
+ .connect(staker)
721
+ .approve(founder.address, stakingAmount);
722
+ const stakingTokenBalanceBeforeTransfer =
723
+ await goodCompoundStaking.balanceOf(founder.address);
724
+ await goodCompoundStaking.transferFrom(
725
+ staker.address,
726
+ founder.address,
727
+ stakingAmount
728
+ );
729
+ const stakingTokenBalanceAfterTransfer =
730
+ await goodCompoundStaking.balanceOf(founder.address);
509
731
 
510
- expect(stakingTokenBalanceAfterTransfer.gt(stakingTokenBalanceBeforeTransfer)).to.be.true;
732
+ expect(
733
+ stakingTokenBalanceAfterTransfer.gt(stakingTokenBalanceBeforeTransfer)
734
+ ).to.be.true;
511
735
  await goodCompoundStaking.withdrawStake(stakingAmount, false);
512
736
  });
513
737
 
@@ -515,28 +739,37 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
515
739
  const stakingAmount = ethers.utils.parseEther("100");
516
740
 
517
741
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
518
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
742
+ await dai
743
+ .connect(staker)
744
+ .approve(goodCompoundStaking.address, stakingAmount);
519
745
 
520
746
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 0, false);
521
747
  await advanceBlocks(5);
522
- const stakingContractVals = await goodFundManager.rewardsForStakingContract(goodCompoundStaking.address);
523
- const earnedRewardBeforeWithdrawReward = await goodCompoundStaking.getUserPendingReward(
524
- staker.address,
525
- stakingContractVals[0],
526
- stakingContractVals[1],
527
- stakingContractVals[2]
748
+ const stakingContractVals = await goodFundManager.rewardsForStakingContract(
749
+ goodCompoundStaking.address
528
750
  );
751
+ const earnedRewardBeforeWithdrawReward =
752
+ await goodCompoundStaking.getUserPendingReward(
753
+ staker.address,
754
+ stakingContractVals[0],
755
+ stakingContractVals[1],
756
+ stakingContractVals[2]
757
+ );
529
758
  await goodCompoundStaking.connect(staker).withdrawRewards();
530
- const earnedRewardAfterWithdrawReward = await goodCompoundStaking.getUserPendingReward(
531
- staker.address,
532
- stakingContractVals[0],
533
- stakingContractVals[1],
534
- stakingContractVals[2]
535
- );
759
+ const earnedRewardAfterWithdrawReward =
760
+ await goodCompoundStaking.getUserPendingReward(
761
+ staker.address,
762
+ stakingContractVals[0],
763
+ stakingContractVals[1],
764
+ stakingContractVals[2]
765
+ );
536
766
 
537
- expect(earnedRewardAfterWithdrawReward.lt(earnedRewardBeforeWithdrawReward)).to.be.true;
767
+ expect(earnedRewardAfterWithdrawReward.lt(earnedRewardBeforeWithdrawReward))
768
+ .to.be.true;
538
769
  expect(earnedRewardAfterWithdrawReward.toString()).to.be.equal("0");
539
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
770
+ await goodCompoundStaking
771
+ .connect(staker)
772
+ .withdrawStake(stakingAmount, false);
540
773
  });
541
774
  it("it should not mint reward when staking contract is not registered", async () => {
542
775
  const simpleStaking = await deployStaking();
@@ -545,27 +778,45 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
545
778
  expect(tx.message).to.not.be.empty;
546
779
  });
547
780
  it("it should be able to distribute rewards when blockEnd passed but last Reward block was before blockend", async () => {
548
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
781
+ const goodFundManagerFactory = await ethers.getContractFactory(
782
+ "GoodFundManager"
783
+ );
549
784
  const currentBlockNumber = await ethers.provider.getBlockNumber();
550
785
  let encodedData = goodFundManagerFactory.interface.encodeFunctionData(
551
786
  "setStakingReward",
552
- ["1000", goodCompoundStaking.address, currentBlockNumber - 10, currentBlockNumber + 50, false] // set 10 gd per block
787
+ [
788
+ "1000",
789
+ goodCompoundStaking.address,
790
+ currentBlockNumber - 10,
791
+ currentBlockNumber + 50,
792
+ false
793
+ ] // set 10 gd per block
553
794
  );
554
795
  await genericCall(goodFundManager.address, encodedData);
555
796
  const stakingAmount = ethers.utils.parseEther("100");
556
797
  const initialGdBalance = await goodDollar.balanceOf(staker.address);
557
798
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
558
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
799
+ await dai
800
+ .connect(staker)
801
+ .approve(goodCompoundStaking.address, stakingAmount);
559
802
  const stakeBlockNumber = (await ethers.provider.getBlockNumber()) + 1;
560
803
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 0, false);
561
804
  await advanceBlocks(5);
562
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount.div(2), false);
563
- const gdBalanceAfterFirstWithdraw = await goodDollar.balanceOf(staker.address);
805
+ await goodCompoundStaking
806
+ .connect(staker)
807
+ .withdrawStake(stakingAmount.div(2), false);
808
+ const gdBalanceAfterFirstWithdraw = await goodDollar.balanceOf(
809
+ staker.address
810
+ );
564
811
  const firstWithdrawBlockNumber = await ethers.provider.getBlockNumber();
565
812
  await advanceBlocks(60);
566
813
 
567
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount.div(2), false);
568
- const gdBalanceAfterSecondWithdraw = await goodDollar.balanceOf(staker.address);
814
+ await goodCompoundStaking
815
+ .connect(staker)
816
+ .withdrawStake(stakingAmount.div(2), false);
817
+ const gdBalanceAfterSecondWithdraw = await goodDollar.balanceOf(
818
+ staker.address
819
+ );
569
820
  expect(gdBalanceAfterFirstWithdraw).to.be.gt(initialGdBalance);
570
821
  expect(gdBalanceAfterFirstWithdraw.sub(initialGdBalance)).to.be.equal(
571
822
  BN.from("1000")
@@ -573,7 +824,9 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
573
824
  .div(2)
574
825
  );
575
826
  expect(gdBalanceAfterSecondWithdraw).to.be.gt(gdBalanceAfterFirstWithdraw);
576
- expect(gdBalanceAfterSecondWithdraw.sub(gdBalanceAfterFirstWithdraw)).to.be.equal(
827
+ expect(
828
+ gdBalanceAfterSecondWithdraw.sub(gdBalanceAfterFirstWithdraw)
829
+ ).to.be.equal(
577
830
  BN.from("1000")
578
831
  .mul(currentBlockNumber + 50 - firstWithdrawBlockNumber)
579
832
  .div(2)
@@ -581,20 +834,32 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
581
834
  ); // sub 1 due to precision loss
582
835
  });
583
836
  it("it should not earn rewards when currentBlock < blockStart", async () => {
584
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
837
+ const goodFundManagerFactory = await ethers.getContractFactory(
838
+ "GoodFundManager"
839
+ );
585
840
  const currentBlockNumber = await ethers.provider.getBlockNumber();
586
841
  let encodedData = goodFundManagerFactory.interface.encodeFunctionData(
587
842
  "setStakingReward",
588
- ["1000", goodCompoundStaking.address, currentBlockNumber + 100, currentBlockNumber + 500, false] // set 10 gd per block
843
+ [
844
+ "1000",
845
+ goodCompoundStaking.address,
846
+ currentBlockNumber + 100,
847
+ currentBlockNumber + 500,
848
+ false
849
+ ] // set 10 gd per block
589
850
  );
590
851
  await genericCall(goodFundManager.address, encodedData);
591
852
  const stakingAmount = ethers.utils.parseEther("100");
592
853
  const initialGdBalance = await goodDollar.balanceOf(staker.address);
593
854
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
594
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
855
+ await dai
856
+ .connect(staker)
857
+ .approve(goodCompoundStaking.address, stakingAmount);
595
858
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 0, false);
596
859
  await advanceBlocks(50);
597
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
860
+ await goodCompoundStaking
861
+ .connect(staker)
862
+ .withdrawStake(stakingAmount, false);
598
863
  const gdBalanceAfterWithdraw = await goodDollar.balanceOf(staker.address);
599
864
 
600
865
  expect(initialGdBalance).to.be.gt(0);
@@ -602,20 +867,32 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
602
867
  });
603
868
 
604
869
  it("it should earn rewards when they stake before blockStart but keep their stake until after blockStart", async () => {
605
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
870
+ const goodFundManagerFactory = await ethers.getContractFactory(
871
+ "GoodFundManager"
872
+ );
606
873
  const currentBlockNumber = await ethers.provider.getBlockNumber();
607
874
  let encodedData = goodFundManagerFactory.interface.encodeFunctionData(
608
875
  "setStakingReward",
609
- ["1000", goodCompoundStaking.address, currentBlockNumber + 30, currentBlockNumber + 500, false] // set 10 gd per block
876
+ [
877
+ "1000",
878
+ goodCompoundStaking.address,
879
+ currentBlockNumber + 30,
880
+ currentBlockNumber + 500,
881
+ false
882
+ ] // set 10 gd per block
610
883
  );
611
884
  await genericCall(goodFundManager.address, encodedData);
612
885
  const stakingAmount = ethers.utils.parseEther("100");
613
886
  const initialGdBalance = await goodDollar.balanceOf(staker.address);
614
887
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
615
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
888
+ await dai
889
+ .connect(staker)
890
+ .approve(goodCompoundStaking.address, stakingAmount);
616
891
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 0, false);
617
892
  await advanceBlocks(50);
618
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
893
+ await goodCompoundStaking
894
+ .connect(staker)
895
+ .withdrawStake(stakingAmount, false);
619
896
  const withdrawBlockNumber = await ethers.provider.getBlockNumber();
620
897
  const gdBalanceAfterWithdraw = await goodDollar.balanceOf(staker.address);
621
898
  expect(initialGdBalance).to.be.gt(0);
@@ -628,42 +905,78 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
628
905
  );
629
906
  });
630
907
  it("should be able earn to 50% of rewards when owns 50% of total productivity", async () => {
631
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
632
- const ictrl = await ethers.getContractAt("Controller", controller, schemeMock);
908
+ const goodFundManagerFactory = await ethers.getContractFactory(
909
+ "GoodFundManager"
910
+ );
911
+ const ictrl = await ethers.getContractAt(
912
+ "Controller",
913
+ controller,
914
+ schemeMock
915
+ );
633
916
  const currentBlockNumber = await ethers.provider.getBlockNumber();
634
917
  let encodedDataTwo = goodFundManagerFactory.interface.encodeFunctionData(
635
918
  "setStakingReward",
636
- ["1000", goodCompoundStaking.address, currentBlockNumber - 10, currentBlockNumber + 100, false] // set 10 gd per block
919
+ [
920
+ "1000",
921
+ goodCompoundStaking.address,
922
+ currentBlockNumber - 10,
923
+ currentBlockNumber + 100,
924
+ false
925
+ ] // set 10 gd per block
637
926
  );
638
927
 
639
928
  const stakingAmount = ethers.utils.parseEther("100");
640
929
 
641
930
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
642
931
  await dai["mint(address,uint256)"](signers[0].address, stakingAmount); // We use some different signer than founder since founder also UBI INTEREST collector
643
- await dai.connect(signers[0]).approve(goodCompoundStaking.address, stakingAmount);
644
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
645
- let stakerTwoGDAmountBeforeStake = await goodDollar.balanceOf(signers[0].address);
932
+ await dai
933
+ .connect(signers[0])
934
+ .approve(goodCompoundStaking.address, stakingAmount);
935
+ await dai
936
+ .connect(staker)
937
+ .approve(goodCompoundStaking.address, stakingAmount);
938
+ let stakerTwoGDAmountBeforeStake = await goodDollar.balanceOf(
939
+ signers[0].address
940
+ );
646
941
  let stakerGDAmountBeforeStake = await goodDollar.balanceOf(staker.address);
647
942
 
648
943
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 100, false);
649
- await goodCompoundStaking.connect(signers[0]).stake(stakingAmount, 100, false);
944
+ await goodCompoundStaking
945
+ .connect(signers[0])
946
+ .stake(stakingAmount, 100, false);
650
947
  await advanceBlocks(5);
651
948
 
652
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
653
- await goodCompoundStaking.connect(signers[0]).withdrawStake(stakingAmount, false);
654
- let stakerTwoGDAmountAfterStake = await goodDollar.balanceOf(signers[0].address);
949
+ await goodCompoundStaking
950
+ .connect(staker)
951
+ .withdrawStake(stakingAmount, false);
952
+ await goodCompoundStaking
953
+ .connect(signers[0])
954
+ .withdrawStake(stakingAmount, false);
955
+ let stakerTwoGDAmountAfterStake = await goodDollar.balanceOf(
956
+ signers[0].address
957
+ );
655
958
  let stakerGDAmountAfterStake = await goodDollar.balanceOf(staker.address);
656
- expect(stakerTwoGDAmountAfterStake.sub(stakerTwoGDAmountBeforeStake).toString()).to.be.equal(
959
+ expect(
960
+ stakerTwoGDAmountAfterStake.sub(stakerTwoGDAmountBeforeStake).toString()
961
+ ).to.be.equal(
657
962
  stakerGDAmountAfterStake.sub(stakerGDAmountBeforeStake).toString()
658
963
  );
659
964
  });
660
965
  it("Accumulated per share has enough precision when reward << totalproductivity", async () => {
661
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
966
+ const goodFundManagerFactory = await ethers.getContractFactory(
967
+ "GoodFundManager"
968
+ );
662
969
 
663
970
  const currentBlockNumber = await ethers.provider.getBlockNumber();
664
971
  let encodedDataTwo = goodFundManagerFactory.interface.encodeFunctionData(
665
972
  "setStakingReward",
666
- ["1000", goodCompoundStaking.address, currentBlockNumber - 10, currentBlockNumber + 100, false] // set 10 gd per block
973
+ [
974
+ "1000",
975
+ goodCompoundStaking.address,
976
+ currentBlockNumber - 10,
977
+ currentBlockNumber + 100,
978
+ false
979
+ ] // set 10 gd per block
667
980
  );
668
981
  await genericCall(goodFundManager.address, encodedDataTwo, avatar, 0);
669
982
  const stakingAmount = ethers.utils.parseEther("1000000000");
@@ -674,24 +987,32 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
674
987
  const gdBalanceBeforeWithdraw = await goodDollar.balanceOf(founder.address);
675
988
  await goodCompoundStaking.withdrawStake(stakingAmount, false);
676
989
  const gdBalanceAfterWithdraw = await goodDollar.balanceOf(founder.address);
677
- expect(gdBalanceAfterWithdraw.sub(gdBalanceBeforeWithdraw).toString()).to.be.equal("2500");
990
+ expect(
991
+ gdBalanceAfterWithdraw.sub(gdBalanceBeforeWithdraw).toString()
992
+ ).to.be.equal("2500");
678
993
  });
679
994
 
680
995
  it("it should not get any reward when donationPer set to 100", async () => {
681
996
  const stakingAmount = ethers.utils.parseEther("100");
682
997
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
683
998
  let stakerGDAmountBeforeStake = await goodDollar.balanceOf(staker.address);
684
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
999
+ await dai
1000
+ .connect(staker)
1001
+ .approve(goodCompoundStaking.address, stakingAmount);
685
1002
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 100, false);
686
1003
  await advanceBlocks(4);
687
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
1004
+ await goodCompoundStaking
1005
+ .connect(staker)
1006
+ .withdrawStake(stakingAmount, false);
688
1007
  let stakerGDAmountAfterStake = await goodDollar.balanceOf(staker.address);
689
1008
  expect(stakerGDAmountAfterStake).to.be.equal(stakerGDAmountBeforeStake);
690
1009
  });
691
1010
  it("it should be reverted when donation per set to different than 0 or 100", async () => {
692
1011
  const stakingAmount = ethers.utils.parseEther("100");
693
1012
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
694
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
1013
+ await dai
1014
+ .connect(staker)
1015
+ .approve(goodCompoundStaking.address, stakingAmount);
695
1016
  const tx = await goodCompoundStaking
696
1017
  .connect(staker)
697
1018
  .stake(stakingAmount, 55, false)
@@ -703,7 +1024,9 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
703
1024
  const stakingAmount = ethers.utils.parseEther("100");
704
1025
 
705
1026
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
706
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
1027
+ await dai
1028
+ .connect(staker)
1029
+ .approve(goodCompoundStaking.address, stakingAmount);
707
1030
 
708
1031
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 100, false);
709
1032
 
@@ -713,14 +1036,13 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
713
1036
 
714
1037
  const simpleStaking1 = await deployStaking();
715
1038
 
716
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
717
- let encodedData = goodFundManagerFactory.interface.encodeFunctionData("setStakingReward", [
718
- "100",
719
- simpleStaking.address,
720
- 0,
721
- 10,
722
- false
723
- ]);
1039
+ const goodFundManagerFactory = await ethers.getContractFactory(
1040
+ "GoodFundManager"
1041
+ );
1042
+ let encodedData = goodFundManagerFactory.interface.encodeFunctionData(
1043
+ "setStakingReward",
1044
+ ["100", simpleStaking.address, 0, 10, false]
1045
+ );
724
1046
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
725
1047
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
726
1048
  await dai.connect(staker).approve(simpleStaking.address, stakingAmount);
@@ -735,14 +1057,13 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
735
1057
  expect(addressesToCollect[0]).to.be.equal(simpleStaking.address);
736
1058
  expect(addressesToCollect[1]).to.be.equal(goodCompoundStaking.address);
737
1059
 
738
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
739
- encodedData = goodFundManagerFactory.interface.encodeFunctionData("setStakingReward", [
740
- "100",
741
- simpleStaking.address,
742
- 0,
743
- 10,
744
- true
745
- ]);
1060
+ await goodCompoundStaking
1061
+ .connect(staker)
1062
+ .withdrawStake(stakingAmount, false);
1063
+ encodedData = goodFundManagerFactory.interface.encodeFunctionData(
1064
+ "setStakingReward",
1065
+ ["100", simpleStaking.address, 0, 10, true]
1066
+ );
746
1067
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
747
1068
  });
748
1069
 
@@ -752,42 +1073,64 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
752
1073
  goodFundManager.collectInterest([], false, {
753
1074
  gasLimit: 770000
754
1075
  })
755
- ).revertedWith("X*gas costs");
1076
+ ).revertedWith(/X*gas costs/);
756
1077
  await gasFeeOracle.setPrice(25e8); //undo gas price
757
1078
  });
758
1079
 
759
1080
  it("It should always collect interest without rewards when forced", async () => {
760
- await goodFundManager.collectInterest([goodCompoundStaking.address], false).catch(e => e); // make sure there is no interest left
1081
+ await goodFundManager
1082
+ .collectInterest([goodCompoundStaking.address], false)
1083
+ .catch(e => e); // make sure there is no interest left
761
1084
 
762
1085
  const stakingAmount = ethers.utils.parseEther("100");
763
1086
 
764
1087
  await dai["mint(address,uint256)"](staker.address, stakingAmount);
765
- await dai.connect(staker).approve(goodCompoundStaking.address, stakingAmount);
1088
+ await dai
1089
+ .connect(staker)
1090
+ .approve(goodCompoundStaking.address, stakingAmount);
766
1091
 
767
1092
  await goodCompoundStaking.connect(staker).stake(stakingAmount, 100, false);
768
- const transaction = goodFundManager.collectInterest([goodCompoundStaking.address], true, {
769
- gasLimit: 770000
770
- });
1093
+ const transaction = goodFundManager.collectInterest(
1094
+ [goodCompoundStaking.address],
1095
+ true,
1096
+ {
1097
+ gasLimit: 770000
1098
+ }
1099
+ );
771
1100
 
772
1101
  await expect(transaction).to.emit(goodFundManager, "FundsTransferred");
773
1102
  const tx = await (await transaction).wait();
774
1103
  const event = tx.events.find(e => e.event === "FundsTransferred");
775
1104
  expect(event.args.gdReward).to.equal(0);
776
1105
 
777
- await goodCompoundStaking.connect(staker).withdrawStake(stakingAmount, false);
1106
+ await goodCompoundStaking
1107
+ .connect(staker)
1108
+ .withdrawStake(stakingAmount, false);
778
1109
  });
779
1110
 
780
1111
  it("It should sort array from lowest to highest ", async () => {
781
- const goodFundManagerTestFactory = await ethers.getContractFactory("GoodFundManagerTest");
782
- const goodFundManagerTest = await goodFundManagerTestFactory.deploy(nameService.address);
783
- const addresses = [founder.address, staker.address, cDAI.address, cDAI1.address];
1112
+ const goodFundManagerTestFactory = await ethers.getContractFactory(
1113
+ "GoodFundManagerTest"
1114
+ );
1115
+ const goodFundManagerTest = await goodFundManagerTestFactory.deploy(
1116
+ nameService.address
1117
+ );
1118
+ const addresses = [
1119
+ founder.address,
1120
+ staker.address,
1121
+ cDAI.address,
1122
+ cDAI1.address
1123
+ ];
784
1124
  const balances = [
785
1125
  ethers.utils.parseEther("100"),
786
1126
  ethers.utils.parseEther("85"),
787
1127
  ethers.utils.parseEther("90"),
788
1128
  ethers.utils.parseEther("30")
789
1129
  ];
790
- const sortedArrays = await goodFundManagerTest.testSorting(balances, addresses);
1130
+ const sortedArrays = await goodFundManagerTest.testSorting(
1131
+ balances,
1132
+ addresses
1133
+ );
791
1134
  expect(sortedArrays[0][0]).to.be.equal(ethers.utils.parseEther("30"));
792
1135
  expect(sortedArrays[0][3]).to.be.equal(ethers.utils.parseEther("100"));
793
1136
  expect(sortedArrays[1][3]).to.be.equal(founder.address);
@@ -795,24 +1138,21 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
795
1138
  });
796
1139
 
797
1140
  it("It should not be able to calc and sort array when there is no active staking contract", async () => {
798
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
799
- let encodedData = goodFundManagerFactory.interface.encodeFunctionData("setStakingReward", [
800
- "100",
801
- goodCompoundStaking.address,
802
- 0,
803
- 10,
804
- true
805
- ]);
1141
+ const goodFundManagerFactory = await ethers.getContractFactory(
1142
+ "GoodFundManager"
1143
+ );
1144
+ let encodedData = goodFundManagerFactory.interface.encodeFunctionData(
1145
+ "setStakingReward",
1146
+ ["100", goodCompoundStaking.address, 0, 10, true]
1147
+ );
806
1148
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
807
- const contractsToInterestCollected = await goodFundManager.calcSortedContracts();
1149
+ const contractsToInterestCollected =
1150
+ await goodFundManager.calcSortedContracts();
808
1151
  expect(contractsToInterestCollected.length).to.be.equal(0);
809
- encodedData = goodFundManagerFactory.interface.encodeFunctionData("setStakingReward", [
810
- "100",
811
- goodCompoundStaking.address,
812
- 100,
813
- 1000,
814
- false
815
- ]);
1152
+ encodedData = goodFundManagerFactory.interface.encodeFunctionData(
1153
+ "setStakingReward",
1154
+ ["100", goodCompoundStaking.address, 100, 1000, false]
1155
+ );
816
1156
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
817
1157
  });
818
1158
 
@@ -820,72 +1160,104 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
820
1160
  const currentBlockNumber = await ethers.provider.getBlockNumber();
821
1161
  const currentBlock = await ethers.provider.getBlock(currentBlockNumber);
822
1162
 
823
- await ethers.provider.send("evm_setNextBlockTimestamp", [currentBlock.timestamp + 5185020]);
1163
+ await ethers.provider.send("evm_setNextBlockTimestamp", [
1164
+ currentBlock.timestamp + 5185020
1165
+ ]);
824
1166
  await ethers.provider.send("evm_mine", []);
825
- const collectableContracts = await goodFundManager.calcSortedContracts().catch(e => e);
826
- await expect(goodFundManager.collectInterest([goodCompoundStaking.address], false)).revertedWith("< gas costs");
1167
+ const collectableContracts = await goodFundManager
1168
+ .calcSortedContracts()
1169
+ .catch(e => e);
1170
+ await expect(
1171
+ goodFundManager.collectInterest([goodCompoundStaking.address], false)
1172
+ ).revertedWith(/< gas costs/);
827
1173
  });
828
1174
 
829
1175
  it("Avatar should be able to set gd minting gas amount", async () => {
830
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
831
- let encodedData = goodFundManagerFactory.interface.encodeFunctionData("setGasCost", ["140000"]);
1176
+ const goodFundManagerFactory = await ethers.getContractFactory(
1177
+ "GoodFundManager"
1178
+ );
1179
+ let encodedData = goodFundManagerFactory.interface.encodeFunctionData(
1180
+ "setGasCost",
1181
+ ["140000"]
1182
+ );
832
1183
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
833
1184
  });
834
1185
  it("Avatar should be able to set collectInterestTimeThreshold", async () => {
835
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
836
- let encodedData = goodFundManagerFactory.interface.encodeFunctionData("setCollectInterestTimeThreshold", [
837
- "5184000"
838
- ]);
1186
+ const goodFundManagerFactory = await ethers.getContractFactory(
1187
+ "GoodFundManager"
1188
+ );
1189
+ let encodedData = goodFundManagerFactory.interface.encodeFunctionData(
1190
+ "setCollectInterestTimeThreshold",
1191
+ ["5184000"]
1192
+ );
839
1193
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
840
1194
  });
841
1195
  it("Avatar should be able set interestMultiplier", async () => {
842
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
843
- let encodedData = goodFundManagerFactory.interface.encodeFunctionData("setInterestMultiplier", ["4"]);
1196
+ const goodFundManagerFactory = await ethers.getContractFactory(
1197
+ "GoodFundManager"
1198
+ );
1199
+ let encodedData = goodFundManagerFactory.interface.encodeFunctionData(
1200
+ "setInterestMultiplier",
1201
+ ["4"]
1202
+ );
844
1203
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
845
1204
  });
846
1205
  it("Avatar should be able set gasCostExceptInterestCollect", async () => {
847
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
848
- let encodedData = goodFundManagerFactory.interface.encodeFunctionData("setGasCostExceptInterestCollect", [
849
- "650000"
850
- ]);
1206
+ const goodFundManagerFactory = await ethers.getContractFactory(
1207
+ "GoodFundManager"
1208
+ );
1209
+ let encodedData = goodFundManagerFactory.interface.encodeFunctionData(
1210
+ "setGasCostExceptInterestCollect",
1211
+ ["650000"]
1212
+ );
851
1213
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
852
1214
  });
853
1215
 
854
1216
  it("It should be able to collect Interest from non DAI or cDAI staking contract [ @skip-on-coverage ]", async () => {
855
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
856
-
857
- const simpleStaking = await goodCompoundStakingFactory.deploy().then(async contract => {
858
- await contract.init(
859
- bat.address,
860
- cBat.address,
861
- nameService.address,
862
- "Good BaT",
863
- "gBAT",
864
- "50",
865
- batUsdOracle.address,
866
- compUsdOracle.address,
867
- [bat.address, dai.address]
868
- );
869
- return contract;
870
- });
1217
+ const goodFundManagerFactory = await ethers.getContractFactory(
1218
+ "GoodFundManager"
1219
+ );
871
1220
 
872
- let encodedData = goodFundManagerFactory.interface.encodeFunctionData("setStakingReward", [
873
- "100",
874
- simpleStaking.address,
875
- 10,
876
- 10000,
877
- false
878
- ]);
1221
+ const simpleStaking = await goodCompoundStakingFactory
1222
+ .deploy()
1223
+ .then(async contract => {
1224
+ await contract.init(
1225
+ bat.address,
1226
+ cBat.address,
1227
+ nameService.address,
1228
+ "Good BaT",
1229
+ "gBAT",
1230
+ "50",
1231
+ batUsdOracle.address,
1232
+ compUsdOracle.address,
1233
+ [bat.address, dai.address]
1234
+ );
1235
+ return contract;
1236
+ });
1237
+
1238
+ let encodedData = goodFundManagerFactory.interface.encodeFunctionData(
1239
+ "setStakingReward",
1240
+ ["100", simpleStaking.address, 10, 10000, false]
1241
+ );
879
1242
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
880
- encodedData = goodCompoundStakingFactory.interface.encodeFunctionData("setcollectInterestGasCostParams", [
881
- "250000",
882
- "150000"
883
- ]);
1243
+ encodedData = goodCompoundStakingFactory.interface.encodeFunctionData(
1244
+ "setcollectInterestGasCostParams",
1245
+ ["250000", "150000"]
1246
+ );
884
1247
  await genericCall(simpleStaking.address, encodedData, avatar, 0);
885
- await bat["mint(address,uint256)"](founder.address, ethers.utils.parseEther("1001000"));
1248
+ await bat["mint(address,uint256)"](
1249
+ founder.address,
1250
+ ethers.utils.parseEther("1001000")
1251
+ );
886
1252
  await bat.transfer(cBat.address, ethers.utils.parseEther("1000000")); // We should put extra BAT to mock cBAT contract in order to provide interest
887
- await dai["mint(address,uint256)"](founder.address, ethers.utils.parseEther("1000000"));
888
- await dai.approve(goodCompoundStaking.address, ethers.utils.parseEther("100"));
1253
+ await dai["mint(address,uint256)"](
1254
+ founder.address,
1255
+ ethers.utils.parseEther("1000000")
1256
+ );
1257
+ await dai.approve(
1258
+ goodCompoundStaking.address,
1259
+ ethers.utils.parseEther("100")
1260
+ );
889
1261
  await goodCompoundStaking.stake(ethers.utils.parseEther("100"), 100, false);
890
1262
  await bat.approve(simpleStaking.address, ethers.utils.parseEther("100"));
891
1263
  await simpleStaking.stake(ethers.utils.parseEther("100"), 100, false);
@@ -900,10 +1272,15 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
900
1272
  gasLimit: 1500000
901
1273
  });
902
1274
  await simpleStaking.withdrawStake(ethers.utils.parseEther("100"), false);
903
- await goodCompoundStaking.withdrawStake(ethers.utils.parseEther("100"), false);
1275
+ await goodCompoundStaking.withdrawStake(
1276
+ ethers.utils.parseEther("100"),
1277
+ false
1278
+ );
904
1279
  });
905
1280
  it("It should redeem underlying token to DAI", async () => {
906
- const goodFundManagerFactory = await ethers.getContractFactory("GoodFundManager");
1281
+ const goodFundManagerFactory = await ethers.getContractFactory(
1282
+ "GoodFundManager"
1283
+ );
907
1284
 
908
1285
  const simpleStaking = await goodCompoundStakingTestFactory.deploy(
909
1286
  bat.address,
@@ -917,10 +1294,18 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
917
1294
  [bat.address, dai.address]
918
1295
  );
919
1296
  await setDAOAddress("RESERVE", simpleStaking.address);
920
- await bat["mint(address,uint256)"](cBat.address, ethers.utils.parseEther("1000"));
921
- await cBat["mint(address,uint256)"](simpleStaking.address, ethers.utils.parseUnits("1000", 8));
1297
+ await bat["mint(address,uint256)"](
1298
+ cBat.address,
1299
+ ethers.utils.parseEther("1000")
1300
+ );
1301
+ await cBat["mint(address,uint256)"](
1302
+ simpleStaking.address,
1303
+ ethers.utils.parseUnits("1000", 8)
1304
+ );
922
1305
  const balanceBeforeRedeem = await dai.balanceOf(simpleStaking.address);
923
- await simpleStaking.redeemUnderlyingToDAITest(ethers.utils.parseUnits("10", 8));
1306
+ await simpleStaking.redeemUnderlyingToDAITest(
1307
+ ethers.utils.parseUnits("10", 8)
1308
+ );
924
1309
  await setDAOAddress("RESERVE", goodReserve.address);
925
1310
  const balanceAfterRedeem = await dai.balanceOf(simpleStaking.address);
926
1311
  const accAmountPerShare = await simpleStaking.accAmountPerShare();
@@ -928,7 +1313,9 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
928
1313
  expect(balanceAfterRedeem.gt(balanceBeforeRedeem)).to.be.true;
929
1314
  });
930
1315
  it("it should reverted when someone trying to call rewardsMinted function beside fundmanager", async () => {
931
- const tx = await goodCompoundStaking.rewardsMinted(founder.address, "1000", 50, 100).catch(e => e);
1316
+ const tx = await goodCompoundStaking
1317
+ .rewardsMinted(founder.address, "1000", 50, 100)
1318
+ .catch(e => e);
932
1319
  expect(tx.message).to.not.empty;
933
1320
  });
934
1321
 
@@ -944,7 +1331,12 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
944
1331
  compUsdOracle.address,
945
1332
  [bat.address, dai.address]
946
1333
  );
947
- await expect(simpleStaking.decreaseProductivityTest(founder.address, ethers.utils.parseEther("100"))).reverted;
1334
+ await expect(
1335
+ simpleStaking.decreaseProductivityTest(
1336
+ founder.address,
1337
+ ethers.utils.parseEther("100")
1338
+ )
1339
+ ).reverted;
948
1340
  });
949
1341
 
950
1342
  it("User pending reward should be zero when there is no stake of user", async () => {
@@ -959,12 +1351,15 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
959
1351
  compUsdOracle.address,
960
1352
  [bat.address, dai.address]
961
1353
  );
962
- let encodedData = goodCompoundStakingTestFactory.interface.encodeFunctionData("setcollectInterestGasCostParams", [
963
- "250000",
964
- "150000"
965
- ]);
1354
+ let encodedData =
1355
+ goodCompoundStakingTestFactory.interface.encodeFunctionData(
1356
+ "setcollectInterestGasCostParams",
1357
+ ["250000", "150000"]
1358
+ );
966
1359
  await genericCall(simpleStaking.address, encodedData, avatar, 0);
967
- const stakingContractVals = await goodFundManager.rewardsForStakingContract(goodCompoundStaking.address);
1360
+ const stakingContractVals = await goodFundManager.rewardsForStakingContract(
1361
+ goodCompoundStaking.address
1362
+ );
968
1363
  const pendingReward = await simpleStaking.getUserPendingReward(
969
1364
  founder.address,
970
1365
  stakingContractVals[0],
@@ -985,11 +1380,16 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
985
1380
  compUsdOracle.address,
986
1381
  [bat.address, dai.address]
987
1382
  );
988
- const tx = await simpleStaking.transfer(staker.address, "10000").catch(e => e);
1383
+ const tx = await simpleStaking
1384
+ .transfer(staker.address, "10000")
1385
+ .catch(e => e);
989
1386
  expect(tx.message).to.have.string("ERC20: transfer amount exceeds balance");
990
1387
  });
991
1388
 
992
- async function addLiquidity(token0Amount: BigNumber, token1Amount: BigNumber) {
1389
+ async function addLiquidity(
1390
+ token0Amount: BigNumber,
1391
+ token1Amount: BigNumber
1392
+ ) {
993
1393
  await bat.transfer(pair.address, token0Amount);
994
1394
  await dai.transfer(pair.address, token1Amount);
995
1395
  await pair.mint(founder.address);
@@ -1001,7 +1401,9 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1001
1401
  ["1000", signers[0].address, 10, 1000, true] // set 10 gd per block
1002
1402
  );
1003
1403
  await genericCall(goodFundManager.address, encodedData);
1004
- let data = await goodFundManager.rewardsForStakingContract(signers[0].address);
1404
+ let data = await goodFundManager.rewardsForStakingContract(
1405
+ signers[0].address
1406
+ );
1005
1407
  expect(data.isBlackListed).to.equal(true);
1006
1408
 
1007
1409
  encodedData = goodFundManager.interface.encodeFunctionData(
@@ -1030,7 +1432,8 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1030
1432
  ["1000", simpleStaking1.address, 10, 1000, false] // set 10 gd per block
1031
1433
  );
1032
1434
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
1033
- const activeContractsCount = await goodFundManager.getActiveContractsCount();
1435
+ const activeContractsCount =
1436
+ await goodFundManager.getActiveContractsCount();
1034
1437
 
1035
1438
  const simpleStaking = await goodCompoundStakingTestFactory.deploy(
1036
1439
  bat.address,
@@ -1048,7 +1451,8 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1048
1451
  ["1000", simpleStaking.address, 10, 1000, false] // set 10 gd per block
1049
1452
  );
1050
1453
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
1051
- const activeContractsCountAfterAdded = await goodFundManager.getActiveContractsCount();
1454
+ const activeContractsCountAfterAdded =
1455
+ await goodFundManager.getActiveContractsCount();
1052
1456
 
1053
1457
  expect(activeContractsCountAfterAdded).equal(activeContractsCount.add(1));
1054
1458
 
@@ -1058,13 +1462,16 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1058
1462
  );
1059
1463
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
1060
1464
 
1061
- const activeContractsCountAfterRemoved = await goodFundManager.getActiveContractsCount();
1465
+ const activeContractsCountAfterRemoved =
1466
+ await goodFundManager.getActiveContractsCount();
1062
1467
  const lastActiveContractAfterRemove = await goodFundManager.activeContracts(
1063
1468
  activeContractsCountAfterRemoved.sub(1)
1064
1469
  );
1065
1470
 
1066
1471
  expect(lastActiveContractAfterRemove).to.be.equal(simpleStaking.address);
1067
- expect(activeContractsCountAfterAdded).to.be.eq(activeContractsCountAfterRemoved);
1472
+ expect(activeContractsCountAfterAdded).to.be.eq(
1473
+ activeContractsCountAfterRemoved
1474
+ );
1068
1475
 
1069
1476
  expect(activeContractsCount).to.be.lt(activeContractsCountAfterRemoved);
1070
1477
  });
@@ -1085,7 +1492,13 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1085
1492
  const rewardsPerBlock = BN.from("1000");
1086
1493
  let encodedData = goodFundManager.interface.encodeFunctionData(
1087
1494
  "setStakingReward",
1088
- [rewardsPerBlock, simpleStaking1.address, currentBlock - 10, currentBlock + 1000, false] // set 10 gd per block
1495
+ [
1496
+ rewardsPerBlock,
1497
+ simpleStaking1.address,
1498
+ currentBlock - 10,
1499
+ currentBlock + 1000,
1500
+ false
1501
+ ] // set 10 gd per block
1089
1502
  );
1090
1503
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
1091
1504
  const stakingAmount = ethers.utils.parseEther("100");
@@ -1093,34 +1506,79 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1093
1506
  await bat["mint(address,uint256)"](staker.address, stakingAmount);
1094
1507
  await bat["mint(address,uint256)"](signers[0].address, stakingAmount);
1095
1508
  await bat["mint(address,uint256)"](signers[1].address, stakingAmount);
1096
- await bat["approve(address,uint256)"](simpleStaking1.address, stakingAmount);
1097
- await bat.connect(staker)["approve(address,uint256)"](simpleStaking1.address, stakingAmount);
1098
- await bat.connect(signers[0])["approve(address,uint256)"](simpleStaking1.address, stakingAmount);
1099
- await bat.connect(signers[1])["approve(address,uint256)"](simpleStaking1.address, stakingAmount);
1100
- const stakerOneStakeBlockNumber = (await ethers.provider.getBlockNumber()) + 1;
1101
- await simpleStaking1["stake(uint256,uint256,bool)"](stakingAmount, "0", false);
1102
- const stakerOneGdBalanceAfterStake = await goodDollar.balanceOf(founder.address);
1103
- const stakerTwoStakeBlockNumber = (await ethers.provider.getBlockNumber()) + 1;
1104
- await simpleStaking1.connect(staker)["stake(uint256,uint256,bool)"](stakingAmount.div(5), "0", false);
1105
- const stakerTwoGdBalanceAfterStake = await goodDollar.balanceOf(staker.address);
1106
- const stakerThreeStakeBlockNumber = (await ethers.provider.getBlockNumber()) + 1;
1107
- await simpleStaking1.connect(signers[0])["stake(uint256,uint256,bool)"](stakingAmount.div(4), "0", false);
1108
- const stakerThreeGdBalanceAfterStake = await goodDollar.balanceOf(signers[0].address);
1109
- const stakerFourStakeBlockNumber = (await ethers.provider.getBlockNumber()) + 1;
1110
- await simpleStaking1.connect(signers[1])["stake(uint256,uint256,bool)"](stakingAmount.div(10), "0", false);
1111
- const stakerFourGdBalanceAfterStake = await goodDollar.balanceOf(signers[1].address);
1509
+ await bat["approve(address,uint256)"](
1510
+ simpleStaking1.address,
1511
+ stakingAmount
1512
+ );
1513
+ await bat
1514
+ .connect(staker)
1515
+ ["approve(address,uint256)"](simpleStaking1.address, stakingAmount);
1516
+ await bat
1517
+ .connect(signers[0])
1518
+ ["approve(address,uint256)"](simpleStaking1.address, stakingAmount);
1519
+ await bat
1520
+ .connect(signers[1])
1521
+ ["approve(address,uint256)"](simpleStaking1.address, stakingAmount);
1522
+ const stakerOneStakeBlockNumber =
1523
+ (await ethers.provider.getBlockNumber()) + 1;
1524
+ await simpleStaking1["stake(uint256,uint256,bool)"](
1525
+ stakingAmount,
1526
+ "0",
1527
+ false
1528
+ );
1529
+ const stakerOneGdBalanceAfterStake = await goodDollar.balanceOf(
1530
+ founder.address
1531
+ );
1532
+ const stakerTwoStakeBlockNumber =
1533
+ (await ethers.provider.getBlockNumber()) + 1;
1534
+ await simpleStaking1
1535
+ .connect(staker)
1536
+ ["stake(uint256,uint256,bool)"](stakingAmount.div(5), "0", false);
1537
+ const stakerTwoGdBalanceAfterStake = await goodDollar.balanceOf(
1538
+ staker.address
1539
+ );
1540
+ const stakerThreeStakeBlockNumber =
1541
+ (await ethers.provider.getBlockNumber()) + 1;
1542
+ await simpleStaking1
1543
+ .connect(signers[0])
1544
+ ["stake(uint256,uint256,bool)"](stakingAmount.div(4), "0", false);
1545
+ const stakerThreeGdBalanceAfterStake = await goodDollar.balanceOf(
1546
+ signers[0].address
1547
+ );
1548
+ const stakerFourStakeBlockNumber =
1549
+ (await ethers.provider.getBlockNumber()) + 1;
1550
+ await simpleStaking1
1551
+ .connect(signers[1])
1552
+ ["stake(uint256,uint256,bool)"](stakingAmount.div(10), "0", false);
1553
+ const stakerFourGdBalanceAfterStake = await goodDollar.balanceOf(
1554
+ signers[1].address
1555
+ );
1112
1556
  await advanceBlocks(10);
1113
1557
  await simpleStaking1["withdrawStake(uint256,bool)"](stakingAmount, false);
1114
1558
  const stakerOneWithdrawBlockNumber = await ethers.provider.getBlockNumber();
1115
- const stakerOneGdBalanceAfterWithdraw = await goodDollar.balanceOf(founder.address);
1116
- await simpleStaking1.connect(staker)["withdrawStake(uint256,bool)"](stakingAmount.div(5), false);
1559
+ const stakerOneGdBalanceAfterWithdraw = await goodDollar.balanceOf(
1560
+ founder.address
1561
+ );
1562
+ await simpleStaking1
1563
+ .connect(staker)
1564
+ ["withdrawStake(uint256,bool)"](stakingAmount.div(5), false);
1117
1565
  const stakerTwoWithdrawBlockNumber = await ethers.provider.getBlockNumber();
1118
- const stakerTwoGdBalanceAfterWithdraw = await goodDollar.balanceOf(staker.address);
1119
- await simpleStaking1.connect(signers[0])["withdrawStake(uint256,bool)"](stakingAmount.div(4), false);
1566
+ const stakerTwoGdBalanceAfterWithdraw = await goodDollar.balanceOf(
1567
+ staker.address
1568
+ );
1569
+ await simpleStaking1
1570
+ .connect(signers[0])
1571
+ ["withdrawStake(uint256,bool)"](stakingAmount.div(4), false);
1120
1572
 
1121
- const stakerThreeGdBalanceAfterWithdraw = await goodDollar.balanceOf(signers[0].address);
1122
- await simpleStaking1.connect(signers[1])["withdrawStake(uint256,bool)"](stakingAmount.div(10), false);
1123
- const stakerFourGdBalanceAfterWithdraw = await goodDollar.balanceOf(signers[1].address);
1573
+ const stakerThreeGdBalanceAfterWithdraw = await goodDollar.balanceOf(
1574
+ signers[0].address
1575
+ );
1576
+ await simpleStaking1
1577
+ .connect(signers[1])
1578
+ ["withdrawStake(uint256,bool)"](stakingAmount.div(10), false);
1579
+ const stakerFourGdBalanceAfterWithdraw = await goodDollar.balanceOf(
1580
+ signers[1].address
1581
+ );
1124
1582
  const stakerOneCalculatedReward = rewardsPerBlock
1125
1583
  .add(rewardsPerBlock.mul(100).div(120)) // there is new staker so total stake units are 120 if call full stakingamount is 100
1126
1584
  .add(rewardsPerBlock.mul(100).div(145)) // there is new staker so total stake units are 145
@@ -1166,15 +1624,27 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1166
1624
  .add(rewardsPerBlock)
1167
1625
  .div(BN.from("2"))
1168
1626
  .add("1");
1169
- expect(stakerOneGdBalanceAfterWithdraw).to.be.equal(stakerOneGdBalanceAfterStake.add(stakerOneCalculatedReward));
1170
- expect(stakerTwoGdBalanceAfterWithdraw).to.be.equal(stakerTwoGdBalanceAfterStake.add(stakerTwoCalculatedReward));
1627
+ expect(stakerOneGdBalanceAfterWithdraw).to.be.equal(
1628
+ stakerOneGdBalanceAfterStake.add(stakerOneCalculatedReward)
1629
+ );
1630
+ expect(stakerTwoGdBalanceAfterWithdraw).to.be.equal(
1631
+ stakerTwoGdBalanceAfterStake.add(stakerTwoCalculatedReward)
1632
+ );
1171
1633
  expect(stakerThreeGdBalanceAfterWithdraw).to.be.equal(
1172
1634
  stakerThreeGdBalanceAfterStake.add(stakerThreeCalculatedReward)
1173
1635
  );
1174
- expect(stakerFourGdBalanceAfterWithdraw).to.be.equal(stakerFourGdBalanceAfterStake.add(stakerFourCalculatedReward));
1636
+ expect(stakerFourGdBalanceAfterWithdraw).to.be.equal(
1637
+ stakerFourGdBalanceAfterStake.add(stakerFourCalculatedReward)
1638
+ );
1175
1639
  encodedData = goodFundManager.interface.encodeFunctionData(
1176
1640
  "setStakingReward",
1177
- [rewardsPerBlock, simpleStaking1.address, currentBlock - 10, currentBlock + 1000, true] // set 10 gd per block
1641
+ [
1642
+ rewardsPerBlock,
1643
+ simpleStaking1.address,
1644
+ currentBlock - 10,
1645
+ currentBlock + 1000,
1646
+ true
1647
+ ] // set 10 gd per block
1178
1648
  );
1179
1649
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
1180
1650
  });
@@ -1195,26 +1665,53 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1195
1665
  const rewardsPerBlock = BN.from("100");
1196
1666
  let encodedData = goodFundManager.interface.encodeFunctionData(
1197
1667
  "setStakingReward",
1198
- [rewardsPerBlock, simpleStaking1.address, currentBlock - 10, currentBlock + 1000, false] // set 1 gd per block
1668
+ [
1669
+ rewardsPerBlock,
1670
+ simpleStaking1.address,
1671
+ currentBlock - 10,
1672
+ currentBlock + 1000,
1673
+ false
1674
+ ] // set 1 gd per block
1199
1675
  );
1200
1676
  await genericCall(goodFundManager.address, encodedData, avatar, 0);
1201
1677
  const stakingAmount = ethers.utils.parseEther("100");
1202
1678
  await bat["mint(address,uint256)"](founder.address, stakingAmount);
1203
1679
  await bat["mint(address,uint256)"](staker.address, stakingAmount);
1204
- await bat["approve(address,uint256)"](simpleStaking1.address, stakingAmount);
1205
- await bat.connect(staker)["approve(address,uint256)"](simpleStaking1.address, stakingAmount);
1206
- await simpleStaking1["stake(uint256,uint256,bool)"](stakingAmount, "0", false);
1207
- const founderGdBalanceAfterStake = await goodDollar.balanceOf(founder.address);
1680
+ await bat["approve(address,uint256)"](
1681
+ simpleStaking1.address,
1682
+ stakingAmount
1683
+ );
1684
+ await bat
1685
+ .connect(staker)
1686
+ ["approve(address,uint256)"](simpleStaking1.address, stakingAmount);
1687
+ await simpleStaking1["stake(uint256,uint256,bool)"](
1688
+ stakingAmount,
1689
+ "0",
1690
+ false
1691
+ );
1692
+ const founderGdBalanceAfterStake = await goodDollar.balanceOf(
1693
+ founder.address
1694
+ );
1208
1695
  const stakerStakeBlockNumber = (await ethers.provider.getBlockNumber()) + 1;
1209
- await simpleStaking1.connect(staker)["stake(uint256,uint256,bool)"](stakingAmount.div(20), "0", false); // should get ~0.009 gd each block
1210
- const stakerGdBalanceAfterStake = await goodDollar.balanceOf(staker.address);
1696
+ await simpleStaking1
1697
+ .connect(staker)
1698
+ ["stake(uint256,uint256,bool)"](stakingAmount.div(20), "0", false); // should get ~0.009 gd each block
1699
+ const stakerGdBalanceAfterStake = await goodDollar.balanceOf(
1700
+ staker.address
1701
+ );
1211
1702
  await advanceBlocks(100);
1212
- await simpleStaking1.connect(staker)["withdrawStake(uint256,bool)"](stakingAmount.div(20), false);
1703
+ await simpleStaking1
1704
+ .connect(staker)
1705
+ ["withdrawStake(uint256,bool)"](stakingAmount.div(20), false);
1213
1706
  const stakerWithdrawBlockNumber = await ethers.provider.getBlockNumber();
1214
- const stakerGdBalanceAfterWithdraw = await goodDollar.balanceOf(staker.address);
1707
+ const stakerGdBalanceAfterWithdraw = await goodDollar.balanceOf(
1708
+ staker.address
1709
+ );
1215
1710
  await simpleStaking1["withdrawStake(uint256,bool)"](stakingAmount, false);
1216
1711
  const founderWithdrawBlockNumber = await ethers.provider.getBlockNumber();
1217
- const founderGdBalanceAfterWithdraw = await goodDollar.balanceOf(founder.address);
1712
+ const founderGdBalanceAfterWithdraw = await goodDollar.balanceOf(
1713
+ founder.address
1714
+ );
1218
1715
  const stakerCalculatedRewards = rewardsPerBlock
1219
1716
  .mul(5)
1220
1717
  .mul(stakerWithdrawBlockNumber - stakerStakeBlockNumber)
@@ -1230,8 +1727,12 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1230
1727
  .div(105)
1231
1728
  )
1232
1729
  .div(BN.from("2"));
1233
- expect(stakerGdBalanceAfterWithdraw.sub(stakerGdBalanceAfterStake)).to.be.equal(stakerCalculatedRewards);
1234
- expect(founderGdBalanceAfterWithdraw.sub(founderGdBalanceAfterStake)).to.be.equal(founderCalculatedRewards);
1730
+ expect(
1731
+ stakerGdBalanceAfterWithdraw.sub(stakerGdBalanceAfterStake)
1732
+ ).to.be.equal(stakerCalculatedRewards);
1733
+ expect(
1734
+ founderGdBalanceAfterWithdraw.sub(founderGdBalanceAfterStake)
1735
+ ).to.be.equal(founderCalculatedRewards);
1235
1736
  });
1236
1737
  it("it should calculate price of spent gas in DAI properly", async () => {
1237
1738
  const gasAmount = BN.from("1100000"); // 1.1M
@@ -1241,7 +1742,10 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1241
1742
  .mul(BN.from("10").pow(18)) // we multiply with 1e18 so when we divide it to DAI/ETH rate we would get result in 18 decimals
1242
1743
  .div(daiToEthRate) // we divide gas price to DAI/ETH rate so we can get gas price in DAI
1243
1744
  .mul(gasAmount); // Result is in DAI and we accept 1$ = 1DAI
1244
- const onChainResult = await goodFundManager.getGasPriceIncDAIorDAI(gasAmount, true);
1745
+ const onChainResult = await goodFundManager.getGasPriceIncDAIorDAI(
1746
+ gasAmount,
1747
+ true
1748
+ );
1245
1749
  expect(calculatedResult).to.be.gt(0);
1246
1750
  expect(onChainResult).to.be.equal(calculatedResult);
1247
1751
  });
@@ -1255,7 +1759,10 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1255
1759
  .mul(BN.from("10").pow(28)) // we multiply it with mantissa which is 18 + tokenDecimals - cTokenDecimals so token is in 18 decimals and cToken is in 8 decimals therefore difference is 10 for more detail https://compound.finance/docs#protocol-math
1256
1760
  .div(await cDAI.exchangeRateStored()); // then we divide it exchange rate in order to get result
1257
1761
  const calculatedResult = gasPriceInCdai.mul(gasAmount);
1258
- const onChainResult = await goodFundManager.getGasPriceIncDAIorDAI(gasAmount, false);
1762
+ const onChainResult = await goodFundManager.getGasPriceIncDAIorDAI(
1763
+ gasAmount,
1764
+ false
1765
+ );
1259
1766
  expect(calculatedResult).to.be.gt(0);
1260
1767
  expect(onChainResult).to.be.equal(calculatedResult);
1261
1768
  });
@@ -1282,8 +1789,14 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1282
1789
  await bat.approve(simpleStaking.address, stakingAmount);
1283
1790
  await simpleStaking.stake(stakingAmount, "0", false);
1284
1791
  await cBat.increasePriceWithMultiplier(100);
1285
- const currentGainsWithBothFalse = await simpleStaking.currentGains(false, false);
1286
- const currentGainsWithBothTrue = await simpleStaking.currentGains(true, true);
1792
+ const currentGainsWithBothFalse = await simpleStaking.currentGains(
1793
+ false,
1794
+ false
1795
+ );
1796
+ const currentGainsWithBothTrue = await simpleStaking.currentGains(
1797
+ true,
1798
+ true
1799
+ );
1287
1800
  await simpleStaking.withdrawStake(stakingAmount, false);
1288
1801
  expect(currentGainsWithBothFalse[3]).to.be.equal(0);
1289
1802
  expect(currentGainsWithBothFalse[4]).to.be.equal(0);
@@ -1298,7 +1811,13 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1298
1811
 
1299
1812
  it("it should collectInterest when there is comp rewards but there is no interest from interest token for nonDAI-cDAI staking contract", async () => {
1300
1813
  const stakingAmount = ethers.utils.parseEther("100");
1301
- let { simpleStaking } = await compTestHelper(bat, cBat, batUsdOracle, stakingAmount, false);
1814
+ let { simpleStaking } = await compTestHelper(
1815
+ bat,
1816
+ cBat,
1817
+ batUsdOracle,
1818
+ stakingAmount,
1819
+ false
1820
+ );
1302
1821
 
1303
1822
  const currentGains = await simpleStaking.currentGains(false, true);
1304
1823
  expect(currentGains[4]).to.be.equal("0");
@@ -1313,7 +1832,13 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1313
1832
 
1314
1833
  it("it should collectInterest from interest token along with comp rewards for nonDAI-cDAI staking contract [ @skip-on-coverage ]", async () => {
1315
1834
  const stakingAmount = ethers.utils.parseEther("100");
1316
- let { simpleStaking } = await compTestHelper(bat, cBat, batUsdOracle, stakingAmount, true);
1835
+ let { simpleStaking } = await compTestHelper(
1836
+ bat,
1837
+ cBat,
1838
+ batUsdOracle,
1839
+ stakingAmount,
1840
+ true
1841
+ );
1317
1842
 
1318
1843
  const currentGains = await simpleStaking.currentGains(false, true);
1319
1844
  expect(currentGains[4]).to.be.equal("4"); // it's not equal due to precision loss
@@ -1328,7 +1853,13 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1328
1853
 
1329
1854
  it("it should collectInterest when there is comp rewards but there is no interest from interest token for DAI-cDAI staking contract", async () => {
1330
1855
  const stakingAmount = ethers.utils.parseEther("100");
1331
- let { simpleStaking } = await compTestHelper(dai, cDAI, daiUsdOracle, stakingAmount, false);
1856
+ let { simpleStaking } = await compTestHelper(
1857
+ dai,
1858
+ cDAI,
1859
+ daiUsdOracle,
1860
+ stakingAmount,
1861
+ false
1862
+ );
1332
1863
 
1333
1864
  const currentGains = await simpleStaking.currentGains(false, true);
1334
1865
  expect(currentGains[4]).to.be.equal("0");
@@ -1342,7 +1873,13 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1342
1873
  });
1343
1874
  it("it should collectInterest from interest token along with comp rewards for DAI-cDAI staking contract [ @skip-on-coverage ]", async () => {
1344
1875
  const stakingAmount = ethers.utils.parseEther("100");
1345
- let { simpleStaking } = await compTestHelper(dai, cDAI, daiUsdOracle, stakingAmount, true);
1876
+ let { simpleStaking } = await compTestHelper(
1877
+ dai,
1878
+ cDAI,
1879
+ daiUsdOracle,
1880
+ stakingAmount,
1881
+ true
1882
+ );
1346
1883
 
1347
1884
  const currentGains = await simpleStaking.currentGains(false, true);
1348
1885
  expect(currentGains[4]).to.be.lt("200"); //should be equal 0 but due to precision loss give some offset so make sure less than 200
@@ -1369,7 +1906,13 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1369
1906
  );
1370
1907
  let encodedData = goodFundManager.interface.encodeFunctionData(
1371
1908
  "setStakingReward",
1372
- ["1000", simpleStaking.address, currentBlockNumber - 5, currentBlockNumber + 1000, false] // set 10 gd per block
1909
+ [
1910
+ "1000",
1911
+ simpleStaking.address,
1912
+ currentBlockNumber - 5,
1913
+ currentBlockNumber + 1000,
1914
+ false
1915
+ ] // set 10 gd per block
1373
1916
  );
1374
1917
  await genericCall(goodFundManager.address, encodedData);
1375
1918
  const rewardsPerBlock = BN.from("1000");
@@ -1386,11 +1929,21 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1386
1929
  const GDBalanceAfterWithdraw = await goodDollar.balanceOf(founder.address);
1387
1930
 
1388
1931
  expect(GDBalanceAfterWithdraw).to.be.equal(
1389
- GDBalanceAfterStake.add(rewardsPerBlock.mul(withdrawRewardsBlockNumber - stakeBlockNumber).div(BN.from("2")))
1932
+ GDBalanceAfterStake.add(
1933
+ rewardsPerBlock
1934
+ .mul(withdrawRewardsBlockNumber - stakeBlockNumber)
1935
+ .div(BN.from("2"))
1936
+ )
1390
1937
  );
1391
1938
  encodedData = goodFundManager.interface.encodeFunctionData(
1392
1939
  "setStakingReward",
1393
- ["1000", simpleStaking.address, currentBlockNumber - 5, currentBlockNumber + 1000, true] // set 10 gd per block
1940
+ [
1941
+ "1000",
1942
+ simpleStaking.address,
1943
+ currentBlockNumber - 5,
1944
+ currentBlockNumber + 1000,
1945
+ true
1946
+ ] // set 10 gd per block
1394
1947
  );
1395
1948
  await genericCall(goodFundManager.address, encodedData);
1396
1949
  });
@@ -1409,37 +1962,70 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1409
1962
  );
1410
1963
  let encodedData = goodFundManager.interface.encodeFunctionData(
1411
1964
  "setStakingReward",
1412
- ["1000", simpleStaking.address, currentBlockNumber - 5, currentBlockNumber + 1000, false] // set 10 gd per block
1965
+ [
1966
+ "1000",
1967
+ simpleStaking.address,
1968
+ currentBlockNumber - 5,
1969
+ currentBlockNumber + 1000,
1970
+ false
1971
+ ] // set 10 gd per block
1972
+ );
1973
+ const overMintTestFactory = await ethers.getContractFactory(
1974
+ "OverMintTesterRegularStake"
1975
+ );
1976
+ const overMintTester = await overMintTestFactory.deploy(
1977
+ bat.address,
1978
+ simpleStaking.address,
1979
+ goodDollar.address
1413
1980
  );
1414
- const overMintTestFactory = await ethers.getContractFactory("OverMintTesterRegularStake");
1415
- const overMintTester = await overMintTestFactory.deploy(bat.address, simpleStaking.address, goodDollar.address);
1416
1981
  await genericCall(goodFundManager.address, encodedData);
1417
1982
  const stakingAmount = ethers.utils.parseEther("100");
1418
1983
  await bat["mint(address,uint256)"](overMintTester.address, stakingAmount);
1419
1984
  const rewardsPerBlock = BN.from("1000");
1420
1985
  const stakeBlockNumber = (await ethers.provider.getBlockNumber()) + 1;
1421
1986
  await overMintTester.stake();
1422
- const GDBalanceAfterStake = await goodDollar.balanceOf(overMintTester.address);
1987
+ const GDBalanceAfterStake = await goodDollar.balanceOf(
1988
+ overMintTester.address
1989
+ );
1423
1990
  await advanceBlocks(100);
1424
1991
  await overMintTester.overMintTest();
1425
1992
  const withdrawRewardsBlockNumber = await ethers.provider.getBlockNumber();
1426
- const GDBalanceAfterWithdrawReward = await goodDollar.balanceOf(overMintTester.address);
1993
+ const GDBalanceAfterWithdrawReward = await goodDollar.balanceOf(
1994
+ overMintTester.address
1995
+ );
1427
1996
  await advanceBlocks(20);
1428
1997
  await overMintTester.overMintTest();
1429
- const secondWithdrawRewardsBlockNumber = await ethers.provider.getBlockNumber();
1430
- const GDBalanceAfterSecondWithdrawReward = await goodDollar.balanceOf(overMintTester.address);
1998
+ const secondWithdrawRewardsBlockNumber =
1999
+ await ethers.provider.getBlockNumber();
2000
+ const GDBalanceAfterSecondWithdrawReward = await goodDollar.balanceOf(
2001
+ overMintTester.address
2002
+ );
1431
2003
 
1432
2004
  expect(GDBalanceAfterWithdrawReward).to.be.gt(GDBalanceAfterStake);
1433
2005
  expect(GDBalanceAfterWithdrawReward.sub(GDBalanceAfterStake)).to.be.equal(
1434
- rewardsPerBlock.mul(withdrawRewardsBlockNumber - stakeBlockNumber).div(BN.from("2"))
2006
+ rewardsPerBlock
2007
+ .mul(withdrawRewardsBlockNumber - stakeBlockNumber)
2008
+ .div(BN.from("2"))
2009
+ );
2010
+ expect(GDBalanceAfterSecondWithdrawReward).to.be.gt(
2011
+ GDBalanceAfterWithdrawReward
1435
2012
  );
1436
- expect(GDBalanceAfterSecondWithdrawReward).to.be.gt(GDBalanceAfterWithdrawReward);
1437
- expect(GDBalanceAfterSecondWithdrawReward.sub(GDBalanceAfterWithdrawReward)).to.be.equal(
1438
- rewardsPerBlock.mul(secondWithdrawRewardsBlockNumber - withdrawRewardsBlockNumber).div(BN.from("2"))
2013
+ expect(
2014
+ GDBalanceAfterSecondWithdrawReward.sub(GDBalanceAfterWithdrawReward)
2015
+ ).to.be.equal(
2016
+ rewardsPerBlock
2017
+ .mul(secondWithdrawRewardsBlockNumber - withdrawRewardsBlockNumber)
2018
+ .div(BN.from("2"))
1439
2019
  );
1440
2020
  encodedData = goodFundManager.interface.encodeFunctionData(
1441
2021
  "setStakingReward",
1442
- ["1000", simpleStaking.address, currentBlockNumber - 5, currentBlockNumber + 1000, true] // set 10 gd per block
2022
+ [
2023
+ "1000",
2024
+ simpleStaking.address,
2025
+ currentBlockNumber - 5,
2026
+ currentBlockNumber + 1000,
2027
+ true
2028
+ ] // set 10 gd per block
1443
2029
  );
1444
2030
  await genericCall(goodFundManager.address, encodedData);
1445
2031
  });
@@ -1472,15 +2058,22 @@ describe("StakingRewards - staking with cDAI mocks and get Rewards in GoodDollar
1472
2058
  await simpleStaking.stake(stakingAmount, "0", false);
1473
2059
  let currentGains = await simpleStaking.currentGains(false, true);
1474
2060
  expect(currentGains[4]).to.be.equal("0");
1475
- await comp["mint(address,uint256)"](simpleStaking.address, ethers.utils.parseEther("10"));
2061
+ await comp["mint(address,uint256)"](
2062
+ simpleStaking.address,
2063
+ ethers.utils.parseEther("10")
2064
+ );
1476
2065
  currentGains = await simpleStaking.currentGains(false, true);
1477
2066
  const compPriceInDollar = await compUsdOracle.latestAnswer();
1478
- expect(currentGains[4]).to.be.equal(BigNumber.from("10").mul(compPriceInDollar));
2067
+ expect(currentGains[4]).to.be.equal(
2068
+ BigNumber.from("10").mul(compPriceInDollar)
2069
+ );
1479
2070
  if (increasePriceOfCtoken) {
1480
2071
  await cToken.increasePriceWithMultiplier("1000");
1481
2072
  }
1482
2073
 
1483
- const contractAddressesToBeCollected = await goodFundManager.connect(staker).calcSortedContracts();
2074
+ const contractAddressesToBeCollected = await goodFundManager
2075
+ .connect(staker)
2076
+ .calcSortedContracts();
1484
2077
  const addressesToCollect = contractAddressesToBeCollected.map(x => x[0]);
1485
2078
  await goodFundManager.collectInterest(addressesToCollect, false);
1486
2079
  return { simpleStaking };