@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.
- package/artifacts/abis/ISuperToken.min.json +1 -1
- package/artifacts/abis/SuperGoodDollar.min.json +1 -1
- package/artifacts/abis/SuperToken.min.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/Avatar.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/Controller.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/GlobalConstraintInterface.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/IntVoteInterface.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/ReputationInterface.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/SchemeRegistrar.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/AggregatorV3Interface.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/ERC20.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IAaveIncentivesController.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IAdminWallet.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IDonationStaking.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IERC2917.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IFirstClaimPool.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IGoodDollar.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IGoodStaking.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IHasRouter.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IIdentity.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IIdentityV2.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/ILendingPool.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IMultichainRouter.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/INameService.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IUBIScheme.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/ProxyAdmin.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/Reserve.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/Staking.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/Uniswap.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/UniswapFactory.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/UniswapPair.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/cERC20.dbg.json +1 -1
- package/artifacts/contracts/fuseFaucet/Faucet.sol/Faucet.dbg.json +1 -1
- package/artifacts/contracts/fuseFaucet/FuseFaucet.sol/FuseFaucet.dbg.json +1 -1
- package/artifacts/contracts/fuseFaucet/FuseFaucetV2.sol/FuseFaucetV2.dbg.json +1 -1
- package/artifacts/contracts/governance/ClaimersDistribution.sol/ClaimersDistribution.dbg.json +1 -1
- package/artifacts/contracts/governance/CompoundVotingMachine.sol/CompoundVotingMachine.dbg.json +1 -1
- package/artifacts/contracts/governance/GReputation.sol/GReputation.dbg.json +1 -1
- package/artifacts/contracts/governance/GoodDollarStaking.sol/GoodDollarStaking.dbg.json +1 -1
- package/artifacts/contracts/governance/GoodDollarStaking.sol/IGovernanceStaking.dbg.json +1 -1
- package/artifacts/contracts/governance/GoodDollarStaking.sol/IStakingUpgrade.dbg.json +1 -1
- package/artifacts/contracts/governance/GoodDollarStaking.sol/RewardsMinter.dbg.json +1 -1
- package/artifacts/contracts/governance/GovernanceStaking.sol/GovernanceStaking.dbg.json +1 -1
- package/artifacts/contracts/governance/MultiBaseGovernanceShareField.sol/MultiBaseGovernanceShareField.dbg.json +1 -1
- package/artifacts/contracts/governance/Reputation.sol/Reputation.dbg.json +1 -1
- package/artifacts/contracts/governance/StakersDistribution.sol/StakersDistribution.dbg.json +1 -1
- package/artifacts/contracts/identity/IdentityV2.sol/IdentityV2.dbg.json +1 -1
- package/artifacts/contracts/invite/InvitesFuseV2.sol/InvitesFuseV2.dbg.json +1 -1
- package/artifacts/contracts/invite/InvitesV1.sol/InvitesV1.dbg.json +1 -1
- package/artifacts/contracts/invite/InvitesV2.sol/InvitesV2.dbg.json +1 -1
- package/artifacts/contracts/mocks/AaveMock.sol/AaveMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/AaveUSDMockOracle.sol/AaveUSDMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/BatUSDMockOracle.sol/BatUSDMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/CompUsdMockOracle.sol/CompUSDMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/DAIMock.sol/DAIMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DaiEthPriceMockOracle.sol/DaiEthPriceMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/DecimalsMock.sol/DecimalsMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DistributionBridgeMock.sol/DistributionBridgeMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTestHelper.dbg.json +1 -1
- package/artifacts/contracts/mocks/EthUSDMockOracle.sol/EthUSDMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/FeesFormularMock.sol/FeesFormulaMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/GasPriceMockOracle.sol/GasPriceMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/GoodCompoundStakingTest.sol/GoodCompoundStakingTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/GoodDollarStakingMock.sol/GoodDollarStakingMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/GoodFundManagerTest.sol/GoodFundManagerTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/IdentityMock.sol/IdentityMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/IncentiveControllerMock.sol/IncentiveControllerMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/LendingPoolMock.sol/LendingPoolMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/MultichainRouterMock.sol/IWrapper.dbg.json +1 -1
- package/artifacts/contracts/mocks/MultichainRouterMock.sol/MultichainRouterMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTester.sol/IGoodDollarStakingTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTester.sol/OverMintTester.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTesterRegularStake.sol/OverMintTesterRegularStake.dbg.json +1 -1
- package/artifacts/contracts/mocks/PayableMock.sol/PayableMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/SixteenDecimalsTokenMock.sol/SixteenDecimalsTokenMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/StakingMockFixedAPY.sol/StakingMockFixedAPY.dbg.json +1 -1
- package/artifacts/contracts/mocks/SwapHelperTest.sol/SwapHelperTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/TwentyDecimalsTokenMock.sol/TwentyDecimalsTokenMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock2.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock3.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock4.dbg.json +1 -1
- package/artifacts/contracts/mocks/UsdcMock.sol/USDCMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cBATMock.sol/cBATMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDAILowWorthMock.sol/cDAILowWorthMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDAIMock.sol/cDAIMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDAINonMintableMock.sol/cDAINonMintableMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDecimalsMock.sol/cDecimalsMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cSDTMock.sol/cSDTMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cUSDCMock.sol/cUSDCMock.dbg.json +1 -1
- package/artifacts/contracts/reserve/DistributionHelper.sol/DistributionHelper.dbg.json +1 -1
- package/artifacts/contracts/reserve/ExchangeHelper.sol/ExchangeHelper.dbg.json +1 -1
- package/artifacts/contracts/reserve/GoodMarketMaker.sol/GoodMarketMaker.dbg.json +1 -1
- package/artifacts/contracts/reserve/GoodReserveCDai.sol/ContributionCalc.dbg.json +1 -1
- package/artifacts/contracts/reserve/GoodReserveCDai.sol/GoodReserveCDai.dbg.json +1 -1
- package/artifacts/contracts/staking/BaseShareField.sol/BaseShareField.dbg.json +1 -1
- package/artifacts/contracts/staking/BaseShareFieldV2.sol/BaseShareFieldV2.dbg.json +1 -1
- package/artifacts/contracts/staking/DonationsStaking.sol/DonationsStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/FuseStakingV3.sol/FuseStakingV3.dbg.json +1 -1
- package/artifacts/contracts/staking/FuseStakingV3.sol/IConsensus.dbg.json +1 -1
- package/artifacts/contracts/staking/FuseStakingV3.sol/PegSwap.dbg.json +1 -1
- package/artifacts/contracts/staking/GoodFundManager.sol/GoodFundManager.dbg.json +1 -1
- package/artifacts/contracts/staking/SimpleStaking.sol/SimpleStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/SimpleStakingV2.sol/SimpleStakingV2.dbg.json +1 -1
- package/artifacts/contracts/staking/UniswapV2SwapHelper.sol/UniswapV2SwapHelper.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/AaveStakingFactory.sol/AaveStakingFactory.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/GoodAaveStaking.sol/GoodAaveStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/GoodAaveStakingV2.sol/GoodAaveStakingV2.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/CompoundStakingFactory.sol/CompoundStakingFactory.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/GoodCompoundStaking.sol/GoodCompoundStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/GoodCompoundStakingV2.sol/GoodCompoundStakingV2.dbg.json +1 -1
- package/artifacts/contracts/staking/utils/Math64X64.sol/Math64x64.dbg.json +1 -1
- package/artifacts/contracts/staking/utils/StakingRewardsFixedAPY.sol/StakingRewardsFixedAPY.dbg.json +1 -1
- package/artifacts/contracts/token/ERC20PresetMinterPauserUpgradeable.sol/ERC20PresetMinterPauserUpgradeable.dbg.json +1 -1
- package/artifacts/contracts/token/ERC677.sol/ERC677.dbg.json +1 -1
- package/artifacts/contracts/token/ERC677.sol/ERC677Receiver.dbg.json +1 -1
- package/artifacts/contracts/token/GoodDollar.sol/GoodDollar.dbg.json +1 -1
- package/artifacts/contracts/token/IFeesFormula.sol/IFeesFormula.dbg.json +1 -1
- package/artifacts/contracts/token/MultichainFeeFormula.sol/MultichainFeeFormula.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/ERC20Permit.sol/ERC20Permit.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/ERC20Permit.sol/SelfApprove.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/ISuperGoodDollar.sol/IGoodDollarCustom.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/ISuperGoodDollar.sol/ISuperGoodDollar.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/ISuperToken.sol/ISuperToken.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/ISuperToken.sol/ISuperToken.json +5 -0
- package/artifacts/contracts/token/superfluid/SuperGoodDollar.sol/SuperGoodDollar.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/SuperGoodDollar.sol/SuperGoodDollar.json +25 -2
- package/artifacts/contracts/token/superfluid/SuperToken.sol/SuperToken.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/SuperToken.sol/SuperToken.json +7 -2
- package/artifacts/contracts/token/superfluid/SuperfluidToken.sol/SuperfluidToken.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/UUPSProxiable.sol/UUPSProxiable.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/UUPSProxy.sol/Proxy.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/UUPSProxy.sol/UUPSProxy.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/UUPSProxy.sol/UUPSUtils.dbg.json +1 -1
- package/artifacts/contracts/ubi/UBIScheme.sol/UBIScheme.dbg.json +1 -1
- package/artifacts/contracts/ubi/UBISchemeV2.sol/UBISchemeV2.dbg.json +1 -1
- package/artifacts/contracts/utils/AdminWallet.sol/AdminWallet.dbg.json +1 -1
- package/artifacts/contracts/utils/AdminWalletFuse.sol/AdminWalletFuse.dbg.json +1 -1
- package/artifacts/contracts/utils/BancorFormula.sol/BancorFormula.dbg.json +1 -1
- package/artifacts/contracts/utils/BulkProof.sol/BulkProof.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyAndBridgeHelper.sol/BuyAndBridgeHelper.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/BuyGDClone.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/BuyGDCloneFactory.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/DonateGDClone.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/IQuoterV2.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/ISwapRouter.dbg.json +1 -1
- package/artifacts/contracts/utils/DAOContract.sol/DAOContract.dbg.json +1 -1
- package/artifacts/contracts/utils/DAOUpgradeableContract.sol/DAOUpgradeableContract.dbg.json +1 -1
- package/artifacts/contracts/utils/DSMath.sol/DSMath.dbg.json +1 -1
- package/artifacts/contracts/utils/DataTypes.sol/DataTypes.dbg.json +1 -1
- package/artifacts/contracts/utils/GDFaucet.sol/GDFaucet.dbg.json +1 -1
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/GoodDollarMintBurnWrapper.dbg.json +1 -1
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/IRouter.dbg.json +1 -1
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/PausableControl.dbg.json +1 -1
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/TokenOperation.dbg.json +1 -1
- package/artifacts/contracts/utils/IdentityFix.sol/IdentityFix.dbg.json +1 -1
- package/artifacts/contracts/utils/MultiCall.sol/Multicall.dbg.json +1 -1
- package/artifacts/contracts/utils/MultichainBridgeHelper.sol/MultichainBridgeHelper.dbg.json +1 -1
- package/artifacts/contracts/utils/NameService.sol/NameService.dbg.json +1 -1
- package/artifacts/contracts/utils/OneTimePayments.sol/OneTimePayments.dbg.json +1 -1
- package/artifacts/contracts/utils/OneTimePaymentsV2.sol/OneTimePaymentsV2.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgrade.sol/OldMarketMaker.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgrade.sol/ProtocolUpgrade.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgradeFuse.sol/ProtocolUpgradeFuse.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgradeFuseRecover.sol/ProtocolUpgradeFuseRecover.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgradeRecover.sol/ProtocolUpgradeRecover.dbg.json +1 -1
- package/artifacts/contracts/utils/ProxyFactory1967.sol/ERC1967Proxy.dbg.json +1 -1
- package/artifacts/contracts/utils/ProxyFactory1967.sol/ProxyFactory1967.dbg.json +1 -1
- package/artifacts/contracts/utils/ReputationTestHelper.sol/ReputationTestHelper.dbg.json +1 -1
- package/contracts/token/superfluid/ISuperToken.sol +1 -0
- package/contracts/token/superfluid/SuperGoodDollar.sol +11 -2
- package/contracts/token/superfluid/SuperToken.sol +8 -0
- package/dist/artifacts/contracts/token/superfluid/SuperGoodDollar.sol/SuperGoodDollar.json +25 -2
- package/hardhat.config.ts +1 -1
- package/package.json +4 -3
- package/scripts/blockchainTestSetup.sh +1 -1
- package/test/faucet/Faucet.test.ts +63 -19
- package/test/faucet/FuseFaucet.test.ts +43 -14
- package/test/governance/ClaimersDistribution.test.ts +3 -3
- package/test/governance/CompoundVotingMachine.castvote.test.ts +3 -6
- package/test/governance/CompoundVotingMachine.crossblockchain.ts +2 -2
- package/test/governance/CompoundVotingMachine.daoscheme.ts +1 -1
- package/test/governance/CompoundVotingMachine.guardian.test.ts +4 -4
- package/test/governance/CompoundVotingMachine.propose.test.ts +8 -8
- package/test/governance/CompoundVotingMachine.state.test.ts +4 -4
- package/test/governance/GReputation.test.ts +6 -6
- package/test/governance/GoodDollarStaking.gd.test.ts +44 -71
- package/test/governance/GoodDollarStaking.good.test.ts +52 -73
- package/test/governance/GovernanceStaking.test.ts +1 -1
- package/test/governance/Reputation.test.ts +2 -2
- package/test/helpers.ts +1 -1
- package/test/identity/IdentityV2.test.ts +12 -12
- package/test/invite/InvitesV1.test.ts +6 -6
- package/test/invite/InvitesV2.test.ts +272 -81
- package/test/reserve/DistributionHelper.test.ts +232 -139
- package/test/reserve/GoodMarketMaker.test.ts +17 -17
- package/test/reserve/GoodReserveCDai.cap.test.ts +4 -4
- package/test/reserve/GoodReserveCDai.distribution.test.ts +64 -42
- package/test/reserve/GoodReserveCDai.gdx.test.ts +1 -1
- package/test/reserve/GoodReserveCDai.pause.test.ts +8 -8
- package/test/reserve/GoodReserveCDai.test.ts +307 -101
- package/test/reserve/GoodReserveCDai.uniswap.test.ts +1 -1
- package/test/staking/DonationsStaking.test.ts +2 -2
- package/test/staking/FuseStaking.test.ts +3 -3
- package/test/staking/GoodAaveStakingFactory.test.ts +2 -2
- package/test/staking/StakingRewards.test.ts +913 -320
- package/test/staking/StakingRewardsFixedAPY.test.ts +62 -66
- package/test/token/CeloGasToken.test.ts +2 -2
- package/test/token/GoodDollar.test.ts +5 -5
- package/test/token/SuperGoodDollar.test.ts +17 -13
- package/test/ubi/UBIScheme.test.ts +1 -1
- package/test/utils/AdminWallet.test.ts +10 -10
- package/test/utils/BuyAndBridgeHelper.test.ts +33 -9
- package/test/utils/GoodDollarMintBurnWrapper.test.ts +265 -113
- package/test/utils/NameService.test.ts +1 -1
- package/test/utils/ProxyFactory.test.ts +2 -2
- package/types/contracts/token/superfluid/SuperGoodDollar.ts +26 -0
- package/types/factories/contracts/token/superfluid/ISuperToken__factory.ts +5 -0
- package/types/factories/contracts/token/superfluid/SuperGoodDollar__factory.ts +24 -1
- package/types/factories/contracts/token/superfluid/SuperToken__factory.ts +6 -1
- 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 {
|
|
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(
|
|
70
|
-
|
|
71
|
-
|
|
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(
|
|
97
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
164
|
+
const cdaiLowWorthFactory = await ethers.getContractFactory(
|
|
165
|
+
"cDAILowWorthMock"
|
|
166
|
+
);
|
|
145
167
|
cDAI2 = await cdaiLowWorthFactory.deploy(dai.address);
|
|
146
|
-
const cdaiNonMintableFactory = await ethers.getContractFactory(
|
|
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(
|
|
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)"](
|
|
178
|
-
|
|
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(
|
|
214
|
+
await addLiquidity(
|
|
215
|
+
ethers.utils.parseEther("2000000"),
|
|
216
|
+
ethers.utils.parseEther("2000000")
|
|
217
|
+
);
|
|
181
218
|
|
|
182
|
-
gasFeeOracle = await ethers.getContractAt(
|
|
183
|
-
|
|
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(
|
|
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
|
-
[
|
|
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(
|
|
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(
|
|
198
|
-
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
|
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
|
|
236
|
-
|
|
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
|
|
239
|
-
|
|
240
|
-
|
|
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
|
|
247
|
-
|
|
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
|
|
250
|
-
|
|
251
|
-
|
|
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
|
|
354
|
+
await dai
|
|
355
|
+
.connect(staker)
|
|
356
|
+
.approve(goodCompoundStaking.address, stakingAmount);
|
|
258
357
|
|
|
259
|
-
await goodCompoundStaking
|
|
260
|
-
|
|
261
|
-
|
|
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
|
|
268
|
-
|
|
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(
|
|
380
|
+
userStakeInfoBeforeWithdraw.effectiveStakes.sub(
|
|
381
|
+
withdrawFromEffectiveStake
|
|
382
|
+
)
|
|
272
383
|
);
|
|
273
|
-
expect(
|
|
274
|
-
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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)"](
|
|
396
|
-
|
|
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 =
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
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
|
|
405
|
-
|
|
406
|
-
|
|
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(
|
|
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
|
-
[
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
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
|
-
[
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
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
|
-
[
|
|
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(
|
|
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(
|
|
690
|
+
let gdBalanceStakerAfterWithdraw = await goodDollar.balanceOf(
|
|
691
|
+
staker.address
|
|
692
|
+
);
|
|
489
693
|
|
|
490
|
-
expect(
|
|
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
|
-
[
|
|
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
|
|
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
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
const
|
|
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(
|
|
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
|
|
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(
|
|
523
|
-
|
|
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 =
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
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))
|
|
767
|
+
expect(earnedRewardAfterWithdrawReward.lt(earnedRewardBeforeWithdrawReward))
|
|
768
|
+
.to.be.true;
|
|
538
769
|
expect(earnedRewardAfterWithdrawReward.toString()).to.be.equal("0");
|
|
539
|
-
await goodCompoundStaking
|
|
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(
|
|
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
|
-
[
|
|
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
|
|
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
|
|
563
|
-
|
|
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
|
|
568
|
-
|
|
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(
|
|
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(
|
|
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
|
-
[
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
[
|
|
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
|
|
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
|
|
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(
|
|
632
|
-
|
|
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
|
-
[
|
|
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
|
|
644
|
-
|
|
645
|
-
|
|
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
|
|
944
|
+
await goodCompoundStaking
|
|
945
|
+
.connect(signers[0])
|
|
946
|
+
.stake(stakingAmount, 100, false);
|
|
650
947
|
await advanceBlocks(5);
|
|
651
948
|
|
|
652
|
-
await goodCompoundStaking
|
|
653
|
-
|
|
654
|
-
|
|
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(
|
|
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(
|
|
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
|
-
[
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
10,
|
|
722
|
-
|
|
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
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
10,
|
|
744
|
-
|
|
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(
|
|
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
|
|
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
|
|
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(
|
|
769
|
-
|
|
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
|
|
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(
|
|
782
|
-
|
|
783
|
-
|
|
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(
|
|
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(
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
10,
|
|
804
|
-
|
|
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 =
|
|
1149
|
+
const contractsToInterestCollected =
|
|
1150
|
+
await goodFundManager.calcSortedContracts();
|
|
808
1151
|
expect(contractsToInterestCollected.length).to.be.equal(0);
|
|
809
|
-
encodedData = goodFundManagerFactory.interface.encodeFunctionData(
|
|
810
|
-
"
|
|
811
|
-
goodCompoundStaking.address,
|
|
812
|
-
|
|
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", [
|
|
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
|
|
826
|
-
|
|
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(
|
|
831
|
-
|
|
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(
|
|
836
|
-
|
|
837
|
-
|
|
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(
|
|
843
|
-
|
|
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(
|
|
848
|
-
|
|
849
|
-
|
|
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(
|
|
856
|
-
|
|
857
|
-
|
|
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
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
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(
|
|
881
|
-
"
|
|
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)"](
|
|
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)"](
|
|
888
|
-
|
|
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(
|
|
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(
|
|
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)"](
|
|
921
|
-
|
|
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(
|
|
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
|
|
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(
|
|
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 =
|
|
963
|
-
|
|
964
|
-
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
-
[
|
|
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)"](
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
const
|
|
1110
|
-
|
|
1111
|
-
|
|
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(
|
|
1116
|
-
|
|
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(
|
|
1119
|
-
|
|
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(
|
|
1122
|
-
|
|
1123
|
-
|
|
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(
|
|
1170
|
-
|
|
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(
|
|
1636
|
+
expect(stakerFourGdBalanceAfterWithdraw).to.be.equal(
|
|
1637
|
+
stakerFourGdBalanceAfterStake.add(stakerFourCalculatedReward)
|
|
1638
|
+
);
|
|
1175
1639
|
encodedData = goodFundManager.interface.encodeFunctionData(
|
|
1176
1640
|
"setStakingReward",
|
|
1177
|
-
[
|
|
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
|
-
[
|
|
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)"](
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
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
|
|
1210
|
-
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
1234
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
1286
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
-
[
|
|
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(
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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(
|
|
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(
|
|
1993
|
+
const GDBalanceAfterWithdrawReward = await goodDollar.balanceOf(
|
|
1994
|
+
overMintTester.address
|
|
1995
|
+
);
|
|
1427
1996
|
await advanceBlocks(20);
|
|
1428
1997
|
await overMintTester.overMintTest();
|
|
1429
|
-
const secondWithdrawRewardsBlockNumber =
|
|
1430
|
-
|
|
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
|
|
2006
|
+
rewardsPerBlock
|
|
2007
|
+
.mul(withdrawRewardsBlockNumber - stakeBlockNumber)
|
|
2008
|
+
.div(BN.from("2"))
|
|
2009
|
+
);
|
|
2010
|
+
expect(GDBalanceAfterSecondWithdrawReward).to.be.gt(
|
|
2011
|
+
GDBalanceAfterWithdrawReward
|
|
1435
2012
|
);
|
|
1436
|
-
expect(
|
|
1437
|
-
|
|
1438
|
-
|
|
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
|
-
[
|
|
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)"](
|
|
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(
|
|
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
|
|
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 };
|