@gooddollar/goodprotocol 1.0.28 → 1.0.29-beta.1
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/BulkProof.min.json +1 -1
- package/artifacts/abis/DistributionBridgeMock.min.json +1 -0
- package/artifacts/abis/DistributionHelper.min.json +1 -0
- package/artifacts/abis/DistributionHelperTest.min.json +1 -0
- package/artifacts/abis/DistributionHelperTestHelper.min.json +1 -0
- package/artifacts/abis/ERC20.min.json +1 -1
- package/artifacts/abis/GoodDollarMintBurnWrapper.min.json +1 -0
- package/artifacts/abis/GoodDollarStaking.min.json +1 -0
- package/artifacts/abis/GoodDollarStakingMock.min.json +1 -0
- package/artifacts/abis/GoodReserveCDai.min.json +1 -1
- package/artifacts/abis/IERC2917.min.json +1 -1
- package/artifacts/abis/IGoodDollarStakingTest.min.json +1 -0
- package/artifacts/abis/IMultichainRouter.min.json +1 -0
- package/artifacts/abis/IRouter.min.json +1 -0
- package/artifacts/abis/IWrapper.min.json +1 -0
- package/artifacts/abis/Math64x64.min.json +1 -0
- package/artifacts/abis/MultichainBridgeHelper.min.json +1 -0
- package/artifacts/abis/MultichainRouterMock.min.json +1 -0
- package/artifacts/abis/OverMintTester.min.json +1 -1
- package/artifacts/abis/PausableControl.min.json +1 -0
- package/artifacts/abis/RewardsMinter.min.json +1 -0
- package/artifacts/abis/StakingMockFixedAPY.min.json +1 -0
- package/artifacts/abis/StakingRewardsFixedAPY.min.json +1 -0
- package/artifacts/abis/TokenOperation.min.json +1 -0
- package/artifacts/abis/cERC20.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/ERC20.json +13 -0
- 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/IERC2917.json +13 -0
- package/artifacts/contracts/Interfaces.sol/IFirstClaimPool.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IGoodDollar.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IGoodStaking.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IHasRouter.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IIdentity.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/ILendingPool.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IMultichainRouter.dbg.json +4 -0
- package/artifacts/contracts/Interfaces.sol/IMultichainRouter.json +67 -0
- 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/Interfaces.sol/cERC20.json +13 -0
- package/artifacts/contracts/fuseFaucet/FuseFaucet.sol/FuseFaucet.dbg.json +1 -1
- package/artifacts/contracts/fuseFaucet/FuseFaucet.sol/FuseFaucet.json +2 -2
- package/artifacts/contracts/governance/ClaimersDistribution.sol/ClaimersDistribution.dbg.json +1 -1
- package/artifacts/contracts/governance/ClaimersDistribution.sol/ClaimersDistribution.json +2 -2
- package/artifacts/contracts/governance/CompoundVotingMachine.sol/CompoundVotingMachine.dbg.json +1 -1
- package/artifacts/contracts/governance/CompoundVotingMachine.sol/CompoundVotingMachine.json +2 -2
- package/artifacts/contracts/governance/GReputation.sol/GReputation.dbg.json +1 -1
- package/artifacts/contracts/governance/GReputation.sol/GReputation.json +2 -2
- package/artifacts/contracts/governance/GoodDollarStaking.sol/GoodDollarStaking.dbg.json +4 -0
- package/artifacts/contracts/governance/GoodDollarStaking.sol/GoodDollarStaking.json +1322 -0
- package/artifacts/contracts/governance/GoodDollarStaking.sol/RewardsMinter.dbg.json +4 -0
- package/artifacts/contracts/governance/GoodDollarStaking.sol/RewardsMinter.json +35 -0
- package/artifacts/contracts/governance/GovernanceStaking.sol/GovernanceStaking.dbg.json +1 -1
- package/artifacts/contracts/governance/GovernanceStaking.sol/GovernanceStaking.json +2 -2
- 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/Reputation.sol/Reputation.json +2 -2
- package/artifacts/contracts/governance/StakersDistribution.sol/StakersDistribution.dbg.json +1 -1
- package/artifacts/contracts/governance/StakersDistribution.sol/StakersDistribution.json +2 -2
- package/artifacts/contracts/invite/InvitesV1.sol/InvitesV1.dbg.json +1 -1
- package/artifacts/contracts/invite/InvitesV1.sol/InvitesV1.json +2 -2
- package/artifacts/contracts/mocks/AaveMock.sol/AaveMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DAIMock.sol/DAIMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DecimalsMock.sol/DecimalsMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DistributionBridgeMock.sol/DistributionBridgeMock.dbg.json +4 -0
- package/artifacts/contracts/mocks/DistributionBridgeMock.sol/DistributionBridgeMock.json +152 -0
- package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTest.dbg.json +4 -0
- package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTest.json +662 -0
- package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTestHelper.dbg.json +4 -0
- package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTestHelper.json +680 -0
- package/artifacts/contracts/mocks/GoodCompoundStakingTest.sol/GoodCompoundStakingTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/GoodCompoundStakingTest.sol/GoodCompoundStakingTest.json +2 -2
- package/artifacts/contracts/mocks/GoodDollarStakingMock.sol/GoodDollarStakingMock.dbg.json +4 -0
- package/artifacts/contracts/mocks/GoodDollarStakingMock.sol/GoodDollarStakingMock.json +1322 -0
- package/artifacts/contracts/mocks/GoodFundManagerTest.sol/GoodFundManagerTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/GoodFundManagerTest.sol/GoodFundManagerTest.json +2 -2
- 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 +4 -0
- package/artifacts/contracts/mocks/MultichainRouterMock.sol/IWrapper.json +59 -0
- package/artifacts/contracts/mocks/MultichainRouterMock.sol/MultichainRouterMock.dbg.json +4 -0
- package/artifacts/contracts/mocks/MultichainRouterMock.sol/MultichainRouterMock.json +81 -0
- package/artifacts/contracts/mocks/OverMintTester.sol/IGoodDollarStakingTest.dbg.json +4 -0
- package/artifacts/contracts/mocks/OverMintTester.sol/IGoodDollarStakingTest.json +49 -0
- package/artifacts/contracts/mocks/OverMintTester.sol/OverMintTester.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTester.sol/OverMintTester.json +4 -4
- package/artifacts/contracts/mocks/OverMintTesterRegularStake.sol/OverMintTesterRegularStake.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTesterRegularStake.sol/OverMintTesterRegularStake.json +2 -2
- package/artifacts/contracts/mocks/SixteenDecimalsTokenMock.sol/SixteenDecimalsTokenMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/StakingMockFixedAPY.sol/StakingMockFixedAPY.dbg.json +4 -0
- package/artifacts/contracts/mocks/StakingMockFixedAPY.sol/StakingMockFixedAPY.json +682 -0
- package/artifacts/contracts/mocks/SwapHelperTest.sol/SwapHelperTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/SwapHelperTest.sol/SwapHelperTest.json +2 -2
- 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/UpgradableMock.json +2 -2
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock2.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock2.json +2 -2
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock3.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock3.json +2 -2
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock4.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock4.json +2 -2
- 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 +4 -0
- package/artifacts/contracts/reserve/DistributionHelper.sol/DistributionHelper.json +662 -0
- package/artifacts/contracts/reserve/ExchangeHelper.sol/ExchangeHelper.dbg.json +1 -1
- package/artifacts/contracts/reserve/ExchangeHelper.sol/ExchangeHelper.json +2 -2
- package/artifacts/contracts/reserve/GoodMarketMaker.sol/GoodMarketMaker.dbg.json +1 -1
- package/artifacts/contracts/reserve/GoodMarketMaker.sol/GoodMarketMaker.json +2 -2
- 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/reserve/GoodReserveCDai.sol/GoodReserveCDai.json +75 -35
- package/artifacts/contracts/staking/BaseShareField.sol/BaseShareField.dbg.json +1 -1
- package/artifacts/contracts/staking/BaseShareField.sol/BaseShareField.json +2 -2
- package/artifacts/contracts/staking/BaseShareFieldV2.sol/BaseShareFieldV2.dbg.json +1 -1
- package/artifacts/contracts/staking/BaseShareFieldV2.sol/BaseShareFieldV2.json +2 -2
- package/artifacts/contracts/staking/DonationsStaking.sol/DonationsStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/DonationsStaking.sol/DonationsStaking.json +2 -2
- package/artifacts/contracts/staking/FuseStakingV3.sol/FuseStakingV3.dbg.json +1 -1
- package/artifacts/contracts/staking/FuseStakingV3.sol/FuseStakingV3.json +2 -2
- 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/GoodFundManager.sol/GoodFundManager.json +2 -2
- 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/UniswapV2SwapHelper.sol/UniswapV2SwapHelper.json +2 -2
- package/artifacts/contracts/staking/aave/AaveStakingFactory.sol/AaveStakingFactory.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/AaveStakingFactory.sol/AaveStakingFactory.json +2 -2
- package/artifacts/contracts/staking/aave/GoodAaveStaking.sol/GoodAaveStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/GoodAaveStaking.sol/GoodAaveStaking.json +2 -2
- package/artifacts/contracts/staking/aave/GoodAaveStakingV2.sol/GoodAaveStakingV2.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/GoodAaveStakingV2.sol/GoodAaveStakingV2.json +2 -2
- package/artifacts/contracts/staking/compound/CompoundStakingFactory.sol/CompoundStakingFactory.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/CompoundStakingFactory.sol/CompoundStakingFactory.json +2 -2
- package/artifacts/contracts/staking/compound/GoodCompoundStaking.sol/GoodCompoundStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/GoodCompoundStaking.sol/GoodCompoundStaking.json +2 -2
- package/artifacts/contracts/staking/compound/GoodCompoundStakingV2.sol/GoodCompoundStakingV2.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/GoodCompoundStakingV2.sol/GoodCompoundStakingV2.json +2 -2
- package/artifacts/contracts/staking/utils/Math64X64.sol/Math64x64.dbg.json +4 -0
- package/artifacts/contracts/staking/utils/Math64X64.sol/Math64x64.json +10 -0
- package/artifacts/contracts/staking/utils/StakingRewardsFixedAPY.sol/StakingRewardsFixedAPY.dbg.json +4 -0
- package/artifacts/contracts/staking/utils/StakingRewardsFixedAPY.sol/StakingRewardsFixedAPY.json +268 -0
- package/artifacts/contracts/ubi/UBIScheme.sol/UBIScheme.dbg.json +1 -1
- package/artifacts/contracts/ubi/UBIScheme.sol/UBIScheme.json +2 -2
- package/artifacts/contracts/utils/AdminWallet.sol/AdminWallet.dbg.json +1 -1
- package/artifacts/contracts/utils/AdminWallet.sol/AdminWallet.json +2 -2
- 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/BulkProof.sol/BulkProof.json +3 -34
- package/artifacts/contracts/utils/DAOContract.sol/DAOContract.dbg.json +1 -1
- package/artifacts/contracts/utils/DAOContract.sol/DAOContract.json +2 -2
- package/artifacts/contracts/utils/DAOUpgradeableContract.sol/DAOUpgradeableContract.dbg.json +1 -1
- package/artifacts/contracts/utils/DAOUpgradeableContract.sol/DAOUpgradeableContract.json +2 -2
- 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/GoodDollarMintBurnWrapper.sol/GoodDollarMintBurnWrapper.dbg.json +4 -0
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/GoodDollarMintBurnWrapper.json +1263 -0
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/IRouter.dbg.json +4 -0
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/IRouter.json +59 -0
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/PausableControl.dbg.json +4 -0
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/PausableControl.json +69 -0
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/TokenOperation.dbg.json +4 -0
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/TokenOperation.json +10 -0
- package/artifacts/contracts/utils/MultichainBridgeHelper.sol/MultichainBridgeHelper.dbg.json +4 -0
- package/artifacts/contracts/utils/MultichainBridgeHelper.sol/MultichainBridgeHelper.json +79 -0
- package/artifacts/contracts/utils/NameService.sol/NameService.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgrade.sol/OldMarketMaker.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgrade.sol/ProtocolUpgrade.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgrade.sol/ProtocolUpgrade.json +2 -2
- package/artifacts/contracts/utils/ProtocolUpgradeFuse.sol/ProtocolUpgradeFuse.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgradeFuse.sol/ProtocolUpgradeFuse.json +2 -2
- package/artifacts/contracts/utils/ProtocolUpgradeFuseRecover.sol/ProtocolUpgradeFuseRecover.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgradeFuseRecover.sol/ProtocolUpgradeFuseRecover.json +2 -2
- package/artifacts/contracts/utils/ProtocolUpgradeRecover.sol/ProtocolUpgradeRecover.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgradeRecover.sol/ProtocolUpgradeRecover.json +2 -2
- 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/artifacts/contracts/utils/ReputationTestHelper.sol/ReputationTestHelper.json +2 -2
- package/contracts/Interfaces.sol +20 -0
- package/contracts/governance/GoodDollarStaking.sol +510 -0
- package/contracts/governance/MultiBaseGovernanceShareField.sol +1 -0
- package/contracts/mocks/DistributionBridgeMock.sol +50 -0
- package/contracts/mocks/DistributionHelperTest.sol +22 -0
- package/contracts/mocks/GoodDollarStakingMock.sol +24 -0
- package/contracts/mocks/MultichainRouterMock.sol +38 -0
- package/contracts/mocks/OverMintTester.sol +39 -25
- package/contracts/mocks/StakingMockFixedAPY.sol +78 -0
- package/contracts/reserve/DistributionHelper.sol +142 -0
- package/contracts/reserve/GoodReserveCDai.sol +95 -41
- package/contracts/staking/utils/Math64X64.sol +268 -0
- package/contracts/staking/utils/StakingRewardsFixedAPY.sol +336 -0
- package/contracts/utils/BulkProof.sol +10 -10
- package/contracts/utils/GoodDollarMintBurnWrapper.sol +638 -0
- package/contracts/utils/MultichainBridgeHelper.sol +39 -0
- package/hardhat.config.ts +5 -3
- package/package.json +7 -4
- package/patches/@openzeppelin+hardhat-upgrades+1.7.0.patch.depracate +67 -0
- package/releases/deployment.json +10 -3
- package/releases/olddao.json +1 -1
- package/scripts/analytics/activeUsersCount.ts +65 -0
- package/scripts/analytics/activeWalletsStats.ts +150 -0
- package/scripts/analytics/claimIncidentStats.ts +117 -0
- package/scripts/analytics/faucetStats.ts +103 -0
- package/scripts/analytics/goodHolders.ts +50 -0
- package/scripts/{misc → analytics}/goodgiveback.ts +0 -0
- package/scripts/governance/airdropCalculation.ts +1 -0
- package/scripts/multichain-deploy/basicdao-deploy.ts +20 -5
- package/scripts/multichain-deploy/gdSavings-deploy.ts +232 -0
- package/scripts/multichain-deploy/helpers.ts +73 -8
- package/scripts/multichain-deploy/multichainWrapper-deploy.ts +56 -0
- package/scripts/multichain-deploy/nonubiDistribution-deploy.ts +170 -0
- package/scripts/voltageswaps.ts +47 -0
- package/test/governance/ClaimersDistribution.test.ts +1 -1
- package/test/governance/GoodDollarStaking.gd.test.ts +559 -0
- package/test/governance/GoodDollarStaking.good.test.ts +998 -0
- package/test/governance/GovernanceStaking.test.ts +43 -0
- package/test/helpers.ts +9 -12
- package/test/reserve/DistributionHelper.test.ts +394 -0
- package/test/reserve/GoodReserveCDai.distribution.test.ts +296 -0
- package/test/reserve/GoodReserveCDai.gdx.test.ts +21 -16
- package/test/reserve/GoodReserveCDai.pause.test.ts +116 -0
- package/test/staking/StakingRewardsFixedAPY.test.ts +900 -0
- package/test/utils/AdminWallet.test.ts +35 -6
- package/test/utils/GoodDollarMintBurnWrapper.test.ts +796 -0
- package/tsconfig.json +4 -9
- package/types/AccessControl.ts +361 -0
- package/types/CERC20.ts +25 -0
- package/types/DistributionBridgeMock.ts +251 -0
- package/types/DistributionHelper.ts +908 -0
- package/types/DistributionHelperTest.ts +909 -0
- package/types/DistributionHelperTestHelper.ts +945 -0
- package/types/ERC165.ts +104 -0
- package/types/ERC20.ts +101 -49
- package/types/GoodDollarMintBurnWrapper.ts +1806 -0
- package/types/GoodDollarStaking.ts +1855 -0
- package/types/GoodDollarStakingMock.ts +1855 -0
- package/types/GoodReserveCDai.ts +90 -55
- package/types/IAccessControl.ts +306 -0
- package/types/IERC165.ts +104 -0
- package/types/IERC20.ts +300 -0
- package/types/IERC20Metadata.ts +339 -0
- package/types/IERC2917.ts +25 -0
- package/types/IGoodDollarStakingTest.ts +160 -0
- package/types/IMultichainRouter.ts +166 -0
- package/types/IRouter.ts +143 -0
- package/types/IWrapper.ts +143 -0
- package/types/MultichainBridgeHelper.ts +170 -0
- package/types/MultichainRouterMock.ts +141 -0
- package/types/Pausable.ts +103 -0
- package/types/PausableControl.ts +125 -0
- package/types/{BulkProof.ts → RewardsMinter.ts} +24 -28
- package/types/StakingMockFixedAPY.ts +995 -0
- package/types/StakingRewardsFixedAPY.ts +428 -0
- package/types/factories/AaveStakingFactory__factory.ts +1 -1
- package/types/factories/AccessControl__factory.ts +227 -0
- package/types/factories/AdminWallet__factory.ts +1 -1
- package/types/factories/BaseShareFieldV2__factory.ts +1 -1
- package/types/factories/BaseShareField__factory.ts +1 -1
- package/types/factories/CERC20__factory.ts +13 -0
- package/types/factories/ClaimersDistribution__factory.ts +1 -1
- package/types/factories/CompoundStakingFactory__factory.ts +1 -1
- package/types/factories/CompoundVotingMachine__factory.ts +1 -1
- package/types/factories/DAOContract__factory.ts +1 -1
- package/types/factories/DAOUpgradeableContract__factory.ts +1 -1
- package/types/factories/DistributionBridgeMock__factory.ts +207 -0
- package/types/factories/DistributionHelperTestHelper__factory.ts +737 -0
- package/types/factories/DistributionHelperTest__factory.ts +717 -0
- package/types/factories/DistributionHelper__factory.ts +713 -0
- package/types/factories/DonationsStaking__factory.ts +1 -1
- package/types/factories/ERC165__factory.ts +39 -0
- package/types/factories/ERC20__factory.ts +13 -0
- package/types/factories/ExchangeHelper__factory.ts +1 -1
- package/types/factories/FuseFaucet__factory.ts +1 -1
- package/types/factories/FuseStakingV3__factory.ts +1 -1
- package/types/factories/GReputation__factory.ts +1 -1
- package/types/factories/GoodAaveStakingV2__factory.ts +1 -1
- package/types/factories/GoodAaveStaking__factory.ts +1 -1
- package/types/factories/GoodCompoundStakingTest__factory.ts +1 -1
- package/types/factories/GoodCompoundStakingV2__factory.ts +1 -1
- package/types/factories/GoodCompoundStaking__factory.ts +1 -1
- package/types/factories/GoodDollarMintBurnWrapper__factory.ts +1318 -0
- package/types/factories/GoodDollarStakingMock__factory.ts +1404 -0
- package/types/factories/GoodDollarStaking__factory.ts +1400 -0
- package/types/factories/GoodFundManagerTest__factory.ts +1 -1
- package/types/factories/GoodFundManager__factory.ts +1 -1
- package/types/factories/GoodMarketMaker__factory.ts +1 -1
- package/types/factories/GoodReserveCDai__factory.ts +74 -34
- package/types/factories/GovernanceStaking__factory.ts +1 -1
- package/types/factories/IAccessControl__factory.ts +198 -0
- package/types/factories/IERC165__factory.ts +42 -0
- package/types/factories/IERC20Metadata__factory.ts +248 -0
- package/types/factories/IERC20__factory.ts +203 -0
- package/types/factories/IERC2917__factory.ts +13 -0
- package/types/factories/IGoodDollarStakingTest__factory.ts +68 -0
- package/types/factories/IMultichainRouter__factory.ts +82 -0
- package/types/factories/IRouter__factory.ts +71 -0
- package/types/factories/IWrapper__factory.ts +71 -0
- package/types/factories/InvitesV1__factory.ts +1 -1
- package/types/factories/MultichainBridgeHelper__factory.ts +134 -0
- package/types/factories/MultichainRouterMock__factory.ts +141 -0
- package/types/factories/OverMintTesterRegularStake__factory.ts +1 -1
- package/types/factories/OverMintTester__factory.ts +3 -3
- package/types/factories/PausableControl__factory.ts +84 -0
- package/types/factories/Pausable__factory.ts +62 -0
- package/types/factories/ProtocolUpgradeFuseRecover__factory.ts +1 -1
- package/types/factories/ProtocolUpgradeFuse__factory.ts +1 -1
- package/types/factories/ProtocolUpgradeRecover__factory.ts +1 -1
- package/types/factories/ProtocolUpgrade__factory.ts +1 -1
- package/types/factories/ReputationTestHelper__factory.ts +1 -1
- package/types/factories/Reputation__factory.ts +1 -1
- package/types/factories/RewardsMinter__factory.ts +47 -0
- package/types/factories/StakersDistribution__factory.ts +1 -1
- package/types/factories/StakingMockFixedAPY__factory.ts +745 -0
- package/types/factories/StakingRewardsFixedAPY__factory.ts +287 -0
- package/types/factories/SwapHelperTest__factory.ts +1 -1
- package/types/factories/UBIScheme__factory.ts +1 -1
- package/types/factories/UniswapV2SwapHelper__factory.ts +1 -1
- package/types/factories/UpgradableMock2__factory.ts +1 -1
- package/types/factories/UpgradableMock3__factory.ts +1 -1
- package/types/factories/UpgradableMock4__factory.ts +1 -1
- package/types/factories/UpgradableMock__factory.ts +1 -1
- package/types/hardhat.d.ts +225 -9
- package/types/index.ts +50 -4
- package/yarn.lock +180 -104
- package/types/factories/BulkProof__factory.ts +0 -89
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
import { default as hre, ethers, upgrades, waffle } from "hardhat";
|
|
2
|
+
import { Contract, Signer } from "ethers";
|
|
3
|
+
import { expect } from "chai";
|
|
4
|
+
import {
|
|
5
|
+
GoodReserveCDai,
|
|
6
|
+
GReputation,
|
|
7
|
+
GoodDollarStaking,
|
|
8
|
+
GovernanceStaking,
|
|
9
|
+
GoodDollarMintBurnWrapper,
|
|
10
|
+
IGoodDollar
|
|
11
|
+
} from "../../types";
|
|
12
|
+
import { createDAO, advanceBlocks, increaseTime } from "../helpers";
|
|
13
|
+
import { FormatTypes } from "ethers/lib/utils";
|
|
14
|
+
|
|
15
|
+
const BN = ethers.BigNumber;
|
|
16
|
+
export const NULL_ADDRESS = ethers.constants.AddressZero;
|
|
17
|
+
export const BLOCK_INTERVAL = 30;
|
|
18
|
+
const DONATION_10_PERCENT = 10;
|
|
19
|
+
const DONATION_30_PERCENT = 30;
|
|
20
|
+
const STAKE_AMOUNT = 10000;
|
|
21
|
+
const BLOCKS_ONE_YEAR = 6307200;
|
|
22
|
+
// APY=5% | per block = nroot(1+0.05,numberOfBlocksPerYear) = 1000000007735630000
|
|
23
|
+
const INTEREST_RATE_5APY_X64 = BN.from("1000000007735630000"); // x64 representation of same number
|
|
24
|
+
const INTEREST_RATE_5APY_128 = BN.from("18446744216406738474"); // 128 representation of same number
|
|
25
|
+
// APY = 10% | nroot(1+0.10,numberOfBlocksPerYear) = 1000000015111330000
|
|
26
|
+
const INTEREST_RATE_10APY_X64 = BN.from("1000000015111330000"); // x64 representation of same number
|
|
27
|
+
const INTEREST_RATE_10APY_128 = BN.from("18446744352464388739"); // 128 representation of same number
|
|
28
|
+
const INITIAL_CAP = 100000000000; //1B G$s
|
|
29
|
+
|
|
30
|
+
describe("GoodDollarStaking - check fixed APY G$ rewards", () => {
|
|
31
|
+
let dai: Contract;
|
|
32
|
+
let cDAI: Contract;
|
|
33
|
+
let goodReserve: GoodReserveCDai;
|
|
34
|
+
let grep: GReputation;
|
|
35
|
+
let avatar,
|
|
36
|
+
goodDollar: IGoodDollar,
|
|
37
|
+
controller,
|
|
38
|
+
founder,
|
|
39
|
+
schemeMock,
|
|
40
|
+
signers,
|
|
41
|
+
nameService,
|
|
42
|
+
setDAOAddress,
|
|
43
|
+
setSchemes,
|
|
44
|
+
genericCall,
|
|
45
|
+
runAsAvatarOnly,
|
|
46
|
+
staker1,
|
|
47
|
+
staker2;
|
|
48
|
+
|
|
49
|
+
before(async () => {
|
|
50
|
+
[founder, staker1, staker2, ...signers] = await ethers.getSigners();
|
|
51
|
+
schemeMock = signers.pop();
|
|
52
|
+
const cdaiFactory = await ethers.getContractFactory("cDAIMock");
|
|
53
|
+
|
|
54
|
+
let {
|
|
55
|
+
controller: ctrl,
|
|
56
|
+
avatar: av,
|
|
57
|
+
gd,
|
|
58
|
+
identity,
|
|
59
|
+
nameService: ns,
|
|
60
|
+
setDAOAddress: sda,
|
|
61
|
+
daiAddress,
|
|
62
|
+
cdaiAddress,
|
|
63
|
+
reserve,
|
|
64
|
+
reputation,
|
|
65
|
+
runAsAvatarOnly: ras,
|
|
66
|
+
setSchemes: ss,
|
|
67
|
+
genericCall: gc
|
|
68
|
+
} = await createDAO();
|
|
69
|
+
|
|
70
|
+
setSchemes = ss;
|
|
71
|
+
runAsAvatarOnly = ras;
|
|
72
|
+
dai = await ethers.getContractAt("DAIMock", daiAddress);
|
|
73
|
+
cDAI = await ethers.getContractAt("cDAIMock", cdaiAddress);
|
|
74
|
+
avatar = av;
|
|
75
|
+
controller = ctrl;
|
|
76
|
+
setDAOAddress = sda;
|
|
77
|
+
nameService = ns;
|
|
78
|
+
goodReserve = reserve as GoodReserveCDai;
|
|
79
|
+
genericCall = gc;
|
|
80
|
+
console.log("deployed dao", {
|
|
81
|
+
founder: founder.address,
|
|
82
|
+
gd,
|
|
83
|
+
identity,
|
|
84
|
+
controller,
|
|
85
|
+
avatar
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
grep = (await ethers.getContractAt(
|
|
89
|
+
"GReputation",
|
|
90
|
+
reputation
|
|
91
|
+
)) as GReputation;
|
|
92
|
+
|
|
93
|
+
goodDollar = (await ethers.getContractAt("IGoodDollar", gd)) as IGoodDollar;
|
|
94
|
+
|
|
95
|
+
//This set addresses should be another function because when we put this initialization of addresses in initializer then nameservice is not ready yet so no proper addresses
|
|
96
|
+
// await goodReserve.setAddresses();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
async function stake(_staker, _amount, stakingContract) {
|
|
100
|
+
await goodDollar.mint(_staker.address, _amount);
|
|
101
|
+
await goodDollar.connect(_staker).approve(stakingContract.address, _amount);
|
|
102
|
+
await stakingContract.connect(_staker).stake(_amount);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const fixture_staked1year = async (wallets, provider) => {
|
|
106
|
+
const { staking, goodDollarMintBurnWrapper } = await fixture_ready(
|
|
107
|
+
wallets,
|
|
108
|
+
provider
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
await stake(staker1, STAKE_AMOUNT, staking);
|
|
112
|
+
await advanceBlocks(BLOCKS_ONE_YEAR);
|
|
113
|
+
|
|
114
|
+
return { staking, goodDollarMintBurnWrapper };
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const fixture_ready = async (wallets, provider) => {
|
|
118
|
+
const f = await ethers.getContractFactory("GoodDollarStakingMock");
|
|
119
|
+
|
|
120
|
+
wallets = provider.getWallets();
|
|
121
|
+
const staking = (await waffle.deployContract(
|
|
122
|
+
wallets[0],
|
|
123
|
+
{
|
|
124
|
+
abi: JSON.parse(
|
|
125
|
+
f.interface.format(FormatTypes.json) as string
|
|
126
|
+
) as any[],
|
|
127
|
+
bytecode: f.bytecode
|
|
128
|
+
},
|
|
129
|
+
[nameService.address, BN.from("1000000007735630000"), 518400 * 12, 30]
|
|
130
|
+
)) as GoodDollarStaking;
|
|
131
|
+
|
|
132
|
+
await staking.upgrade();
|
|
133
|
+
|
|
134
|
+
await setDAOAddress("GDAO_STAKING", staking.address);
|
|
135
|
+
|
|
136
|
+
const mintBurnWrapperFactory = await ethers.getContractFactory(
|
|
137
|
+
"GoodDollarMintBurnWrapper"
|
|
138
|
+
);
|
|
139
|
+
let goodDollarMintBurnWrapper = (await upgrades.deployProxy(
|
|
140
|
+
mintBurnWrapperFactory,
|
|
141
|
+
[avatar, nameService.address],
|
|
142
|
+
{ kind: "uups" }
|
|
143
|
+
)) as unknown as GoodDollarMintBurnWrapper;
|
|
144
|
+
await setSchemes([goodDollarMintBurnWrapper.address]);
|
|
145
|
+
await setDAOAddress("MINTBURN_WRAPPER", goodDollarMintBurnWrapper.address);
|
|
146
|
+
|
|
147
|
+
await goodDollar.mint(founder.address, "200000000000"); //mint so that 30bps cap can mint some G$
|
|
148
|
+
|
|
149
|
+
let encodedCall = goodDollarMintBurnWrapper.interface.encodeFunctionData(
|
|
150
|
+
"addMinter",
|
|
151
|
+
[staking.address, 0, 0, 30, 0, 0, 30, true]
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const ictrl = await ethers.getContractAt(
|
|
155
|
+
"Controller",
|
|
156
|
+
controller,
|
|
157
|
+
schemeMock
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
await ictrl.genericCall(
|
|
161
|
+
goodDollarMintBurnWrapper.address,
|
|
162
|
+
encodedCall,
|
|
163
|
+
avatar,
|
|
164
|
+
0
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
return { staking: staking.connect(staker1), goodDollarMintBurnWrapper };
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const fixture_upgradeTest = async (wallets, provider) => {
|
|
171
|
+
const f = await ethers.getContractFactory("GoodDollarStaking");
|
|
172
|
+
const gf = await ethers.getContractFactory("GovernanceStaking");
|
|
173
|
+
|
|
174
|
+
wallets = provider.getWallets();
|
|
175
|
+
const staking = (await waffle.deployContract(
|
|
176
|
+
wallets[0],
|
|
177
|
+
{
|
|
178
|
+
abi: JSON.parse(
|
|
179
|
+
f.interface.format(FormatTypes.json) as string
|
|
180
|
+
) as any[],
|
|
181
|
+
bytecode: f.bytecode
|
|
182
|
+
},
|
|
183
|
+
[nameService.address, BN.from("1000000007735630000"), 518400 * 12, 30]
|
|
184
|
+
)) as GoodDollarStaking;
|
|
185
|
+
|
|
186
|
+
const govStaking = (await waffle.deployContract(
|
|
187
|
+
wallets[0],
|
|
188
|
+
{
|
|
189
|
+
abi: JSON.parse(
|
|
190
|
+
gf.interface.format(FormatTypes.json) as string
|
|
191
|
+
) as any[],
|
|
192
|
+
bytecode: gf.bytecode
|
|
193
|
+
},
|
|
194
|
+
[nameService.address]
|
|
195
|
+
)) as GovernanceStaking;
|
|
196
|
+
|
|
197
|
+
await setDAOAddress("GDAO_STAKING", govStaking.address);
|
|
198
|
+
|
|
199
|
+
await setSchemes([staking.address]);
|
|
200
|
+
|
|
201
|
+
return { staking, govStaking };
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
it("should update stakingrewardsfixedapy staker info and global stats when staking", async () => {
|
|
205
|
+
const { staking } = await waffle.loadFixture(fixture_ready);
|
|
206
|
+
const statsBefore = await staking.stats();
|
|
207
|
+
const PRECISION = await staking.PRECISION();
|
|
208
|
+
|
|
209
|
+
await stake(staker1, STAKE_AMOUNT, staking);
|
|
210
|
+
|
|
211
|
+
expect(await goodDollar.balanceOf(staking.address)).equal(STAKE_AMOUNT);
|
|
212
|
+
const info = await staking.stakersInfo(staker1.address);
|
|
213
|
+
expect(await staking.getSavings(staker1.address)).to.equal(STAKE_AMOUNT);
|
|
214
|
+
expect(info.rewardsPaid).to.equal(0);
|
|
215
|
+
expect(await staking.sharesOf(staker1.address)).to.equal(
|
|
216
|
+
(await staking.SHARE_DECIMALS()).mul(STAKE_AMOUNT)
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
const stats = await staking.stats();
|
|
220
|
+
expect(stats.lastUpdateBlock.gt(statsBefore.lastUpdateBlock));
|
|
221
|
+
expect(stats.totalStaked).to.equal(STAKE_AMOUNT);
|
|
222
|
+
expect(await staking.sharesSupply()).eq(
|
|
223
|
+
(await staking.SHARE_DECIMALS()).mul(STAKE_AMOUNT)
|
|
224
|
+
);
|
|
225
|
+
expect(stats.totalRewardsPaid).to.equal(0);
|
|
226
|
+
expect(stats.totalStaked).to.equal(STAKE_AMOUNT);
|
|
227
|
+
expect(stats.savings).to.equal(PRECISION.mul(STAKE_AMOUNT));
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("should withdraw only rewards when calling withdrawRewards", async () => {
|
|
231
|
+
const { staking } = await waffle.loadFixture(fixture_ready);
|
|
232
|
+
|
|
233
|
+
// collect 350 earned rewards: 10,000 * 5%APY = 500 total rewards, minus 30% donation
|
|
234
|
+
await stake(staker1, STAKE_AMOUNT, staking);
|
|
235
|
+
expect(await goodDollar.balanceOf(staking.address)).equal(STAKE_AMOUNT);
|
|
236
|
+
await advanceBlocks(BLOCKS_ONE_YEAR);
|
|
237
|
+
const stakeBefore = await staking.principle(staker1.address);
|
|
238
|
+
const savingsBefore = await staking.getSavings(staker1.address);
|
|
239
|
+
|
|
240
|
+
await staking.connect(staker1).withdrawRewards();
|
|
241
|
+
|
|
242
|
+
const savingsAfter = await staking.getSavings(staker1.address);
|
|
243
|
+
const infoAfter = await staking.stakersInfo(staker1.address);
|
|
244
|
+
expect(await staking.principle(staker1.address))
|
|
245
|
+
.to.equal(stakeBefore)
|
|
246
|
+
.to.equal(STAKE_AMOUNT);
|
|
247
|
+
expect(await goodDollar.balanceOf(staker1.address)).equal(500);
|
|
248
|
+
expect(infoAfter.rewardsPaid).to.equal(500);
|
|
249
|
+
expect(savingsAfter).to.equal(savingsBefore.sub(500));
|
|
250
|
+
expect(await staking.earned(staker1.address)).eq(0);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it("should withdraw from deposit and undo rewards if unable to mint rewards", async () => {
|
|
254
|
+
const { staking, goodDollarMintBurnWrapper } = await waffle.loadFixture(
|
|
255
|
+
fixture_ready
|
|
256
|
+
);
|
|
257
|
+
const PAUSE_ALL_ROLE = await goodDollarMintBurnWrapper.PAUSE_ALL_ROLE();
|
|
258
|
+
expect(await goodDollarMintBurnWrapper.paused(PAUSE_ALL_ROLE)).to.be.false;
|
|
259
|
+
|
|
260
|
+
// pause goodDollarMintBurnWrapper
|
|
261
|
+
const encodedCall = goodDollarMintBurnWrapper.interface.encodeFunctionData(
|
|
262
|
+
"pause",
|
|
263
|
+
[PAUSE_ALL_ROLE]
|
|
264
|
+
);
|
|
265
|
+
await genericCall(goodDollarMintBurnWrapper.address, encodedCall);
|
|
266
|
+
expect(await goodDollarMintBurnWrapper.paused(PAUSE_ALL_ROLE)).to.be.true;
|
|
267
|
+
|
|
268
|
+
await stake(staker1, STAKE_AMOUNT, staking);
|
|
269
|
+
expect(await goodDollar.balanceOf(staking.address)).equal(STAKE_AMOUNT);
|
|
270
|
+
await advanceBlocks(BLOCKS_ONE_YEAR);
|
|
271
|
+
const savingsBefore = await staking.getSavings(staker1.address);
|
|
272
|
+
const infoBefore = await staking.stakersInfo(staker1.address);
|
|
273
|
+
|
|
274
|
+
// withdraw so undo rewards will be called on rewards part
|
|
275
|
+
await staking.withdrawStake(await staking.sharesOf(staker1.address));
|
|
276
|
+
|
|
277
|
+
const savingsAfter = await staking.getSavings(staker1.address);
|
|
278
|
+
const infoAfter = await staking.stakersInfo(staker1.address);
|
|
279
|
+
expect(await goodDollar.balanceOf(staker1.address)).to.eq(STAKE_AMOUNT); //we expect only the stake to have been withdrawn successfully, no rewards yet
|
|
280
|
+
expect(savingsBefore).to.equal(STAKE_AMOUNT + 500);
|
|
281
|
+
expect(savingsAfter).to.equal(500);
|
|
282
|
+
expect(await staking.earned(staker1.address)).to.equal(500);
|
|
283
|
+
expect(infoBefore.lastSharePrice).to.gt(0);
|
|
284
|
+
expect(infoAfter.lastSharePrice).to.eq(0); //we have withdrawn all stake, so all shares are rewards (ie profit)
|
|
285
|
+
expect(infoAfter.rewardsPaid).to.equal(0);
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it("should withdraw rewards after mint rewards is enabled again", async () => {
|
|
289
|
+
const { staking, goodDollarMintBurnWrapper } = await waffle.loadFixture(
|
|
290
|
+
fixture_ready
|
|
291
|
+
);
|
|
292
|
+
const PAUSE_ALL_ROLE = await goodDollarMintBurnWrapper.PAUSE_ALL_ROLE();
|
|
293
|
+
// pause goodDollarMintBurnWrapper
|
|
294
|
+
let encodedCall = goodDollarMintBurnWrapper.interface.encodeFunctionData(
|
|
295
|
+
"pause",
|
|
296
|
+
[PAUSE_ALL_ROLE]
|
|
297
|
+
);
|
|
298
|
+
await genericCall(goodDollarMintBurnWrapper.address, encodedCall);
|
|
299
|
+
await stake(staker1, STAKE_AMOUNT, staking);
|
|
300
|
+
await advanceBlocks(BLOCKS_ONE_YEAR);
|
|
301
|
+
// withdraw so undo rewards will be called on rewards part
|
|
302
|
+
await staking.withdrawStake(await staking.sharesOf(staker1.address));
|
|
303
|
+
encodedCall = goodDollarMintBurnWrapper.interface.encodeFunctionData(
|
|
304
|
+
"unpause",
|
|
305
|
+
[PAUSE_ALL_ROLE]
|
|
306
|
+
);
|
|
307
|
+
await genericCall(goodDollarMintBurnWrapper.address, encodedCall);
|
|
308
|
+
expect(await goodDollarMintBurnWrapper.paused(PAUSE_ALL_ROLE)).to.be.false;
|
|
309
|
+
|
|
310
|
+
expect(await goodDollar.balanceOf(staker1.address)).to.equal(STAKE_AMOUNT);
|
|
311
|
+
await staking.withdrawStake(await staking.sharesOf(staker1.address));
|
|
312
|
+
|
|
313
|
+
const stakerInfo = await staking.stakersInfo(staker1.address);
|
|
314
|
+
expect(await goodDollar.balanceOf(staker1.address)).to.equal(
|
|
315
|
+
STAKE_AMOUNT + 500
|
|
316
|
+
);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it("should have upgrade deadline < 60 days", async () => {
|
|
320
|
+
const f = await ethers.getContractFactory("GoodDollarStaking");
|
|
321
|
+
await expect(
|
|
322
|
+
f.deploy(
|
|
323
|
+
nameService.address,
|
|
324
|
+
BN.from("1000000007735630000"),
|
|
325
|
+
518400 * 12,
|
|
326
|
+
61
|
|
327
|
+
)
|
|
328
|
+
).revertedWith("max two");
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
it("should not perform upgrade when not deadline", async () => {
|
|
332
|
+
const { staking } = await waffle.loadFixture(fixture_upgradeTest);
|
|
333
|
+
await expect(staking.upgrade()).to.revertedWith("deadline");
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
it("should perform upgrade after deadline", async () => {
|
|
337
|
+
const { staking, govStaking } = await waffle.loadFixture(
|
|
338
|
+
fixture_upgradeTest
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
const gdaoStakingBefore = await nameService.getAddress("GDAO_STAKING");
|
|
342
|
+
|
|
343
|
+
await increaseTime(60 * 60 * 24 * 31); //pass > 30 days of
|
|
344
|
+
await expect(staking.upgrade()).to.not.reverted;
|
|
345
|
+
const ctrl = await ethers.getContractAt("Controller", controller);
|
|
346
|
+
|
|
347
|
+
await expect(staking.upgrade()).to.reverted; //should not be able to call upgrade again
|
|
348
|
+
|
|
349
|
+
//verify nameService address changed
|
|
350
|
+
expect(gdaoStakingBefore).to.equal(govStaking.address);
|
|
351
|
+
expect(await nameService.getAddress("GDAO_STAKING")).to.equal(
|
|
352
|
+
staking.address
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
//verify no longer registered as scheme
|
|
356
|
+
expect(await ctrl.isSchemeRegistered(staking.address, avatar)).to.be.false;
|
|
357
|
+
|
|
358
|
+
//verify rewards have changed
|
|
359
|
+
expect((await staking.getRewardsPerBlock())[0]).gt(0);
|
|
360
|
+
expect(await govStaking.getRewardsPerBlock()).eq(0);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
it("should set APY and change getRewardsPerBlock only by avatar", async () => {
|
|
364
|
+
const { staking } = await waffle.loadFixture(fixture_ready);
|
|
365
|
+
|
|
366
|
+
const [, gdRewardsPerBlockBeforeSet] = await staking.getRewardsPerBlock();
|
|
367
|
+
expect(gdRewardsPerBlockBeforeSet.add(1)).to.equal(INTEREST_RATE_5APY_X64);
|
|
368
|
+
const gdInterestRateIn128BeforeSet =
|
|
369
|
+
await staking.interestRatePerBlockX64();
|
|
370
|
+
expect(gdInterestRateIn128BeforeSet).to.equal(INTEREST_RATE_5APY_128);
|
|
371
|
+
|
|
372
|
+
await runAsAvatarOnly(
|
|
373
|
+
staking,
|
|
374
|
+
"setGdApy(uint128)",
|
|
375
|
+
INTEREST_RATE_10APY_X64
|
|
376
|
+
);
|
|
377
|
+
|
|
378
|
+
const [, gdRewardsPerBlockAfterSet] = await staking.getRewardsPerBlock();
|
|
379
|
+
expect(gdRewardsPerBlockAfterSet.add(1)).to.equal(INTEREST_RATE_10APY_X64);
|
|
380
|
+
const gdInterestRateIn128AfterSet = await staking.interestRatePerBlockX64();
|
|
381
|
+
expect(gdInterestRateIn128AfterSet).to.equal(INTEREST_RATE_10APY_128);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it("should be pausable by avatar", async () => {
|
|
385
|
+
const { staking } = await waffle.loadFixture(fixture_ready);
|
|
386
|
+
|
|
387
|
+
await runAsAvatarOnly(staking, "pause(bool,uint128)", true, "0");
|
|
388
|
+
expect(await staking.paused()).to.equal(true);
|
|
389
|
+
let [, gdRewardsPerBlockAfterSet] = await staking.getRewardsPerBlock();
|
|
390
|
+
expect(gdRewardsPerBlockAfterSet).to.equal("0");
|
|
391
|
+
|
|
392
|
+
await runAsAvatarOnly(
|
|
393
|
+
staking,
|
|
394
|
+
"pause(bool,uint128)",
|
|
395
|
+
false,
|
|
396
|
+
"1000000029000000000"
|
|
397
|
+
);
|
|
398
|
+
expect(await staking.paused()).to.equal(false);
|
|
399
|
+
[, gdRewardsPerBlockAfterSet] = await staking.getRewardsPerBlock();
|
|
400
|
+
expect(gdRewardsPerBlockAfterSet.add(1)).to.equal("1000000029000000000");
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it("should not be able to stake when paused", async () => {
|
|
404
|
+
const { staking } = await waffle.loadFixture(fixture_ready);
|
|
405
|
+
|
|
406
|
+
await runAsAvatarOnly(staking, "pause(bool,uint128)", true, "0");
|
|
407
|
+
await expect(stake(staker2, "1000", staking)).to.revertedWith("pause");
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
it("should have max yearly apy of 20%", async () => {
|
|
411
|
+
const { staking } = await waffle.loadFixture(fixture_ready);
|
|
412
|
+
|
|
413
|
+
await runAsAvatarOnly(staking, "setGdApy(uint128)", "1000000029000000000");
|
|
414
|
+
|
|
415
|
+
let [, gdRewardsPerBlockAfterSet] = await staking.getRewardsPerBlock();
|
|
416
|
+
expect(gdRewardsPerBlockAfterSet.add(1)).to.equal("1000000029000000000");
|
|
417
|
+
|
|
418
|
+
//shout not be set as > 20% apy
|
|
419
|
+
await runAsAvatarOnly(staking, "setGdApy(uint128)", "1000000030000000000");
|
|
420
|
+
|
|
421
|
+
[, gdRewardsPerBlockAfterSet] = await staking.getRewardsPerBlock();
|
|
422
|
+
expect(gdRewardsPerBlockAfterSet.add(1)).to.equal("1000000029000000000");
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
it("should handle stakingrewardsfixed apy correctly when transfering staking tokens to new staker", async () => {
|
|
426
|
+
const { staking } = await waffle.loadFixture(fixture_staked1year);
|
|
427
|
+
|
|
428
|
+
const RECEIVER_STAKE = 10000;
|
|
429
|
+
const receiver = staker2;
|
|
430
|
+
await stake(receiver, RECEIVER_STAKE, staking);
|
|
431
|
+
const receiverInfo = await staking.stakersInfo(receiver.address);
|
|
432
|
+
const stakerInfo = await staking.stakersInfo(staker1.address);
|
|
433
|
+
|
|
434
|
+
expect(await staking.getSavings(staker1.address)).to.equal(
|
|
435
|
+
STAKE_AMOUNT + 500
|
|
436
|
+
); // 500 yearly earned reward
|
|
437
|
+
expect(await staking.getSavings(receiver.address)).to.equal(
|
|
438
|
+
RECEIVER_STAKE - 1 //precision loss
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
const sharesToTransfer = await staking.amountToShares(200);
|
|
442
|
+
await staking.transfer(receiver.address, sharesToTransfer);
|
|
443
|
+
|
|
444
|
+
expect(
|
|
445
|
+
(await staking.stakersInfo(staker1.address)).lastSharePrice
|
|
446
|
+
).to.equal(stakerInfo.lastSharePrice); // keep staker relative earnings
|
|
447
|
+
|
|
448
|
+
expect(await staking.getSavings(staker1.address)).to.equal(
|
|
449
|
+
STAKE_AMOUNT + 500 - 200
|
|
450
|
+
);
|
|
451
|
+
expect(await staking.earned(staker1.address)).to.equal(490);
|
|
452
|
+
expect(await staking.earned(receiver.address)).to.equal(9); //the rewards part should have been transfered, there's precision loss
|
|
453
|
+
expect((await staking.stakersInfo(receiver.address)).lastSharePrice).to.lt(
|
|
454
|
+
receiverInfo.lastSharePrice
|
|
455
|
+
); // increase receiver rewards part = lower lastSharePrice
|
|
456
|
+
|
|
457
|
+
expect(await staking.getSavings(receiver.address)).to.equal(
|
|
458
|
+
RECEIVER_STAKE + 200
|
|
459
|
+
);
|
|
460
|
+
const senderInfo = await staking.stakersInfo(staker1.address);
|
|
461
|
+
expect(senderInfo.rewardsPaid).to.equal(0); //no rewards transfer
|
|
462
|
+
expect(await goodDollar.balanceOf(staking.address)).to.equal(
|
|
463
|
+
STAKE_AMOUNT + RECEIVER_STAKE
|
|
464
|
+
); // no withdrawals yet
|
|
465
|
+
|
|
466
|
+
//should be able to withdraw everything successfully, ie making sure all calculations add up
|
|
467
|
+
await staking.withdrawStake(await staking.sharesOf(staker1.address));
|
|
468
|
+
|
|
469
|
+
expect(await staking.earned(receiver.address)).to.equal(9); //the rewards part should have been transfered, there's precision loss, it is "fixed" when withdrawing
|
|
470
|
+
await staking
|
|
471
|
+
.connect(receiver)
|
|
472
|
+
.withdrawStake(await staking.sharesOf(receiver.address));
|
|
473
|
+
|
|
474
|
+
expect((await staking.stakersInfo(receiver.address)).rewardsPaid).eq(10); //withdraw transfered 1 GD to the rewards part, to make sure contract balance withdraws are correct
|
|
475
|
+
expect((await staking.stakersInfo(staker1.address)).rewardsPaid).eq(490);
|
|
476
|
+
expect(await goodDollar.balanceOf(staking.address)).eq(0);
|
|
477
|
+
expect(await goodDollar.balanceOf(staker1.address)).eq(10300);
|
|
478
|
+
expect(await goodDollar.balanceOf(receiver.address)).eq(10200);
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
it("should be able to stake using onTokenTransfer", async () => {
|
|
482
|
+
const { staking, goodDollarMintBurnWrapper } = await waffle.loadFixture(
|
|
483
|
+
fixture_ready
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
await goodDollar.mint(staker1.address, "100000000");
|
|
487
|
+
|
|
488
|
+
await expect(
|
|
489
|
+
goodDollar
|
|
490
|
+
.connect(staker1)
|
|
491
|
+
.transferAndCall(
|
|
492
|
+
staking.address,
|
|
493
|
+
"100000000",
|
|
494
|
+
ethers.constants.HashZero
|
|
495
|
+
)
|
|
496
|
+
).not.reverted;
|
|
497
|
+
expect(await staking.getSavings(staker1.address)).to.equal("100000000");
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
it("should asure getStaked returns correct value", async () => {
|
|
501
|
+
const { staking } = await waffle.loadFixture(fixture_ready);
|
|
502
|
+
|
|
503
|
+
// correct after stake
|
|
504
|
+
await stake(staker1, STAKE_AMOUNT, staking);
|
|
505
|
+
let [userProductivity, totalProductivity] = await staking[
|
|
506
|
+
"getStaked(address)"
|
|
507
|
+
](staker1.address);
|
|
508
|
+
let stakerShares = await staking.sharesOf(staker1.address);
|
|
509
|
+
let totalStaked = (await staking.stats()).totalStaked;
|
|
510
|
+
expect(userProductivity).eq(totalProductivity).to.equal(stakerShares);
|
|
511
|
+
expect(totalStaked).to.equal(STAKE_AMOUNT);
|
|
512
|
+
|
|
513
|
+
await staking.connect(staker1).withdrawStake(stakerShares.div(2));
|
|
514
|
+
|
|
515
|
+
let [userProductivity2, totalProductivity2] = await staking[
|
|
516
|
+
"getStaked(address)"
|
|
517
|
+
](staker1.address);
|
|
518
|
+
|
|
519
|
+
expect(userProductivity2).to.equal(stakerShares.div(2));
|
|
520
|
+
expect(totalProductivity2).to.equal(stakerShares.div(2));
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
it("it should return getUserPendingReward G$ value equal to earned() rewards after donation", async () => {
|
|
524
|
+
const { staking } = await waffle.loadFixture(fixture_ready);
|
|
525
|
+
await stake(staker1, STAKE_AMOUNT, staking);
|
|
526
|
+
await advanceBlocks(BLOCKS_ONE_YEAR);
|
|
527
|
+
|
|
528
|
+
const [, earnedGdRewards] = await staking["getUserPendingReward(address)"](
|
|
529
|
+
staker1.address
|
|
530
|
+
);
|
|
531
|
+
const earnedRewards = await staking.earned(staker1.address);
|
|
532
|
+
|
|
533
|
+
expect(earnedGdRewards)
|
|
534
|
+
.to.equal(earnedRewards)
|
|
535
|
+
.to.equal(BN.from(STAKE_AMOUNT).mul(5).div(100)); // 5% apy
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
it("should return G$ totalRewardsPerShare equal sharePrice()", async () => {
|
|
539
|
+
const { staking } = await waffle.loadFixture(fixture_ready);
|
|
540
|
+
await stake(staker1, STAKE_AMOUNT, staking);
|
|
541
|
+
await advanceBlocks(BLOCKS_ONE_YEAR);
|
|
542
|
+
const stats = await staking.stats();
|
|
543
|
+
const sharePrice = await staking.sharePrice();
|
|
544
|
+
let [, accumulatedGdRewardsPerShare] = await staking[
|
|
545
|
+
"totalRewardsPerShare()"
|
|
546
|
+
]();
|
|
547
|
+
// to be changed
|
|
548
|
+
//rewards per share = (savings - deposit) / number of shares = 10500 - 10000 / 1000000
|
|
549
|
+
expect(accumulatedGdRewardsPerShare.div(1e6)) //div by 1e6 to not compare exact precision due to compounding interest precision
|
|
550
|
+
.to.equal(
|
|
551
|
+
BN.from("10500")
|
|
552
|
+
.sub("10000")
|
|
553
|
+
.mul(await staking.SHARE_PRECISION())
|
|
554
|
+
.div(await staking.sharesSupply())
|
|
555
|
+
.div(1e6)
|
|
556
|
+
)
|
|
557
|
+
.to.gt(0);
|
|
558
|
+
});
|
|
559
|
+
});
|