@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,796 @@
|
|
|
1
|
+
import { ethers, waffle, upgrades } from "hardhat";
|
|
2
|
+
import { expect } from "chai";
|
|
3
|
+
import {
|
|
4
|
+
GoodReserveCDai,
|
|
5
|
+
GoodDollarMintBurnWrapper,
|
|
6
|
+
ERC20,
|
|
7
|
+
IGoodDollar,
|
|
8
|
+
MultichainRouterMock
|
|
9
|
+
} from "../../types";
|
|
10
|
+
import { createDAO, increaseTime } from "../helpers";
|
|
11
|
+
import { FormatTypes } from "@ethersproject/abi";
|
|
12
|
+
|
|
13
|
+
const BN = ethers.BigNumber;
|
|
14
|
+
export const NULL_ADDRESS = ethers.constants.AddressZero;
|
|
15
|
+
export const BLOCK_INTERVAL = 1;
|
|
16
|
+
|
|
17
|
+
const MINTER_CAP = 1000000;
|
|
18
|
+
const MINTER_TX_MAX = 100000;
|
|
19
|
+
const REWARD_BPS = 300;
|
|
20
|
+
|
|
21
|
+
describe("GoodDollarMintBurnWrapper", () => {
|
|
22
|
+
let goodReserve: GoodReserveCDai;
|
|
23
|
+
let goodDollar: IGoodDollar,
|
|
24
|
+
genericCall,
|
|
25
|
+
avatar,
|
|
26
|
+
founder,
|
|
27
|
+
minter,
|
|
28
|
+
minterUncapped,
|
|
29
|
+
rewarder,
|
|
30
|
+
guardian,
|
|
31
|
+
router,
|
|
32
|
+
wrapperAdmin,
|
|
33
|
+
signers,
|
|
34
|
+
setDAOAddress,
|
|
35
|
+
nameService,
|
|
36
|
+
cDai,
|
|
37
|
+
controller;
|
|
38
|
+
|
|
39
|
+
before(async () => {
|
|
40
|
+
[
|
|
41
|
+
founder,
|
|
42
|
+
wrapperAdmin,
|
|
43
|
+
minter,
|
|
44
|
+
rewarder,
|
|
45
|
+
guardian,
|
|
46
|
+
minterUncapped,
|
|
47
|
+
router,
|
|
48
|
+
...signers
|
|
49
|
+
] = await ethers.getSigners();
|
|
50
|
+
|
|
51
|
+
let {
|
|
52
|
+
controller: ctrl,
|
|
53
|
+
avatar: av,
|
|
54
|
+
gd,
|
|
55
|
+
identity,
|
|
56
|
+
setDAOAddress: sda,
|
|
57
|
+
setSchemes: ss,
|
|
58
|
+
reserve,
|
|
59
|
+
cdaiAddress,
|
|
60
|
+
genericCall: gc,
|
|
61
|
+
nameService: ns
|
|
62
|
+
} = await createDAO();
|
|
63
|
+
|
|
64
|
+
nameService = ns;
|
|
65
|
+
genericCall = gc;
|
|
66
|
+
cDai = cdaiAddress;
|
|
67
|
+
avatar = av;
|
|
68
|
+
setDAOAddress = sda;
|
|
69
|
+
controller = ctrl;
|
|
70
|
+
|
|
71
|
+
console.log("deployed dao", {
|
|
72
|
+
founder: founder.address,
|
|
73
|
+
gd,
|
|
74
|
+
identity,
|
|
75
|
+
avatar
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
goodDollar = (await ethers.getContractAt("IGoodDollar", gd)) as IGoodDollar;
|
|
79
|
+
|
|
80
|
+
console.log("deployed contribution, deploying reserve...", {
|
|
81
|
+
founder: founder.address
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
goodReserve = reserve as GoodReserveCDai;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const fixture = async (wallets, provider) => {
|
|
88
|
+
wallets = provider.getWallets();
|
|
89
|
+
|
|
90
|
+
const gf = await ethers.getContractFactory("GoodDollarMintBurnWrapper");
|
|
91
|
+
const ictrl = await ethers.getContractAt(
|
|
92
|
+
"Controller",
|
|
93
|
+
controller,
|
|
94
|
+
wallets[wallets.length - 1] //has scheme permissions set by createDAO()
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const wrapper = (await upgrades.deployProxy(
|
|
98
|
+
await ethers.getContractFactory("GoodDollarMintBurnWrapper"),
|
|
99
|
+
[wrapperAdmin.address, nameService.address],
|
|
100
|
+
{
|
|
101
|
+
kind: "uups"
|
|
102
|
+
}
|
|
103
|
+
)) as GoodDollarMintBurnWrapper;
|
|
104
|
+
|
|
105
|
+
await wrapper
|
|
106
|
+
.connect(wrapperAdmin)
|
|
107
|
+
.grantRole(await wrapper.GUARDIAN_ROLE(), guardian.address);
|
|
108
|
+
|
|
109
|
+
await goodDollar.mint(controller, 10000000); //so bps limit is significant
|
|
110
|
+
|
|
111
|
+
await wrapper
|
|
112
|
+
.connect(wrapperAdmin)
|
|
113
|
+
.addMinter(
|
|
114
|
+
router.address,
|
|
115
|
+
MINTER_CAP,
|
|
116
|
+
MINTER_TX_MAX,
|
|
117
|
+
REWARD_BPS,
|
|
118
|
+
MINTER_CAP,
|
|
119
|
+
MINTER_TX_MAX,
|
|
120
|
+
REWARD_BPS,
|
|
121
|
+
false
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
await wrapper
|
|
125
|
+
.connect(wrapperAdmin)
|
|
126
|
+
.addMinter(
|
|
127
|
+
minter.address,
|
|
128
|
+
MINTER_CAP,
|
|
129
|
+
MINTER_TX_MAX,
|
|
130
|
+
REWARD_BPS,
|
|
131
|
+
MINTER_CAP,
|
|
132
|
+
MINTER_TX_MAX,
|
|
133
|
+
REWARD_BPS,
|
|
134
|
+
false
|
|
135
|
+
);
|
|
136
|
+
await wrapper
|
|
137
|
+
.connect(wrapperAdmin)
|
|
138
|
+
.addMinter(rewarder.address, 0, 0, REWARD_BPS, 0, 0, 0, true);
|
|
139
|
+
|
|
140
|
+
await ictrl.registerScheme(
|
|
141
|
+
wrapper.address,
|
|
142
|
+
ethers.constants.HashZero,
|
|
143
|
+
"0x00000001",
|
|
144
|
+
avatar
|
|
145
|
+
);
|
|
146
|
+
return { wrapper };
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const fixture_withMultichain = async (wallets, provider) => {
|
|
150
|
+
wallets = provider.getWallets();
|
|
151
|
+
|
|
152
|
+
const gf = await ethers.getContractFactory("GoodDollarMintBurnWrapper");
|
|
153
|
+
const rf = await ethers.getContractFactory("MultichainRouterMock");
|
|
154
|
+
|
|
155
|
+
const ictrl = await ethers.getContractAt(
|
|
156
|
+
"Controller",
|
|
157
|
+
controller,
|
|
158
|
+
wallets[wallets.length - 1] //has scheme permissions set by createDAO()
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
const wrapper = (await upgrades.deployProxy(
|
|
162
|
+
await ethers.getContractFactory("GoodDollarMintBurnWrapper"),
|
|
163
|
+
[wrapperAdmin.address, nameService.address],
|
|
164
|
+
{
|
|
165
|
+
kind: "uups"
|
|
166
|
+
}
|
|
167
|
+
)) as GoodDollarMintBurnWrapper;
|
|
168
|
+
|
|
169
|
+
const multiChainRouter = (await rf.deploy(
|
|
170
|
+
wrapper.address
|
|
171
|
+
)) as MultichainRouterMock;
|
|
172
|
+
|
|
173
|
+
await wrapper
|
|
174
|
+
.connect(wrapperAdmin)
|
|
175
|
+
.addMinter(
|
|
176
|
+
multiChainRouter.address,
|
|
177
|
+
MINTER_CAP,
|
|
178
|
+
MINTER_TX_MAX,
|
|
179
|
+
REWARD_BPS,
|
|
180
|
+
MINTER_CAP,
|
|
181
|
+
MINTER_TX_MAX,
|
|
182
|
+
REWARD_BPS,
|
|
183
|
+
false
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
await setDAOAddress("MULTICHAIN_ROUTER", multiChainRouter.address);
|
|
187
|
+
await goodDollar.mint(controller, 10000000); //so bps limit is significant
|
|
188
|
+
|
|
189
|
+
return { wrapper, multiChainRouter };
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
it("should be safe for upgrades", async () => {
|
|
193
|
+
const result = await upgrades
|
|
194
|
+
.deployProxy(
|
|
195
|
+
await ethers.getContractFactory("GoodDollarMintBurnWrapper"),
|
|
196
|
+
[wrapperAdmin.address, nameService.address],
|
|
197
|
+
{
|
|
198
|
+
kind: "uups"
|
|
199
|
+
}
|
|
200
|
+
)
|
|
201
|
+
.catch(e => false);
|
|
202
|
+
expect(result).not.false;
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("should have avatar as default admin ", async () => {
|
|
206
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
207
|
+
|
|
208
|
+
expect(await wrapper.owner()).to.equal(avatar);
|
|
209
|
+
expect(await wrapper.hasRole(await wrapper.DEFAULT_ADMIN_ROLE(), avatar)).to
|
|
210
|
+
.be.true;
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it("should have admin from params as default admin ", async () => {
|
|
214
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
215
|
+
|
|
216
|
+
expect(
|
|
217
|
+
await wrapper.hasRole(
|
|
218
|
+
await wrapper.DEFAULT_ADMIN_ROLE(),
|
|
219
|
+
wrapperAdmin.address
|
|
220
|
+
)
|
|
221
|
+
).to.be.true;
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it("should have erc20 token info", async () => {
|
|
225
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
226
|
+
|
|
227
|
+
expect(await wrapper.decimals()).to.equal(2);
|
|
228
|
+
expect(await wrapper.name()).to.equal("GoodDollar");
|
|
229
|
+
expect(await wrapper.symbol()).to.equal("G$");
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it("should update updateFrequency only by admin or guardian role", async () => {
|
|
233
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
234
|
+
|
|
235
|
+
expect(await wrapper.updateFrequency()).to.equal(60 * 60 * 24 * 90); //default 90 days;
|
|
236
|
+
|
|
237
|
+
await expect(wrapper.setUpdateFrequency(0)).to.be.revertedWith("role");
|
|
238
|
+
await expect(wrapper.connect(wrapperAdmin).setUpdateFrequency(0)).to.not
|
|
239
|
+
.reverted;
|
|
240
|
+
expect(await wrapper.updateFrequency()).to.equal(0);
|
|
241
|
+
await expect(wrapper.connect(guardian).setUpdateFrequency(1)).to.not
|
|
242
|
+
.reverted;
|
|
243
|
+
expect(await wrapper.updateFrequency()).to.equal(1);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it("should be able to pause roles only by admin or guardian role", async () => {
|
|
247
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
248
|
+
|
|
249
|
+
await expect(
|
|
250
|
+
wrapper.unpause(await wrapper.PAUSE_ALL_ROLE())
|
|
251
|
+
).to.be.revertedWith("role");
|
|
252
|
+
|
|
253
|
+
await expect(
|
|
254
|
+
wrapper.connect(wrapperAdmin).pause(await wrapper.PAUSE_BURN_ROLE())
|
|
255
|
+
).to.not.reverted;
|
|
256
|
+
await expect(
|
|
257
|
+
wrapper.connect(guardian).pause(await wrapper.PAUSE_ALL_ROLE())
|
|
258
|
+
).to.not.reverted;
|
|
259
|
+
|
|
260
|
+
expect(await wrapper.paused(await wrapper.PAUSE_BURN_ROLE())).to.equal(
|
|
261
|
+
true
|
|
262
|
+
);
|
|
263
|
+
expect(await wrapper.paused(await wrapper.PAUSE_ALL_ROLE())).to.equal(true);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("should be able to unpause roles only by admin or guardian role", async () => {
|
|
267
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
268
|
+
|
|
269
|
+
await expect(
|
|
270
|
+
wrapper.unpause(await wrapper.PAUSE_ALL_ROLE())
|
|
271
|
+
).to.be.revertedWith("role");
|
|
272
|
+
|
|
273
|
+
await expect(
|
|
274
|
+
wrapper.connect(wrapperAdmin).pause(await wrapper.PAUSE_BURN_ROLE())
|
|
275
|
+
).to.not.reverted;
|
|
276
|
+
|
|
277
|
+
await expect(
|
|
278
|
+
wrapper.connect(wrapperAdmin).pause(await wrapper.PAUSE_ALL_ROLE())
|
|
279
|
+
).to.not.reverted;
|
|
280
|
+
|
|
281
|
+
await expect(
|
|
282
|
+
wrapper.connect(guardian).unpause(await wrapper.PAUSE_ALL_ROLE())
|
|
283
|
+
).to.not.reverted;
|
|
284
|
+
|
|
285
|
+
await expect(
|
|
286
|
+
wrapper.connect(wrapperAdmin).unpause(await wrapper.PAUSE_BURN_ROLE())
|
|
287
|
+
).to.not.reverted;
|
|
288
|
+
|
|
289
|
+
expect(await wrapper.paused(await wrapper.PAUSE_BURN_ROLE())).to.equal(
|
|
290
|
+
false
|
|
291
|
+
);
|
|
292
|
+
expect(await wrapper.paused(await wrapper.PAUSE_ALL_ROLE())).to.equal(
|
|
293
|
+
false
|
|
294
|
+
);
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
it("should be able to mint only by minter role", async () => {
|
|
298
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
299
|
+
|
|
300
|
+
await expect(wrapper.mint(founder.address, 1000)).to.revertedWith("role");
|
|
301
|
+
await expect(wrapper.connect(minter).mint(signers[0].address, 1000)).to.not
|
|
302
|
+
.reverted;
|
|
303
|
+
expect(await goodDollar.balanceOf(signers[0].address)).to.equal(1000);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it("should not be able to mint when minter is paused", async () => {
|
|
307
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
308
|
+
|
|
309
|
+
await expect(
|
|
310
|
+
wrapper.connect(guardian).pause(await wrapper.PAUSE_MINT_ROLE())
|
|
311
|
+
).to.not.reverted;
|
|
312
|
+
|
|
313
|
+
await expect(
|
|
314
|
+
wrapper.connect(minter).mint(signers[0].address, 1000)
|
|
315
|
+
).revertedWith("pause");
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it("should not be able to mint when passed daily cap", async () => {
|
|
319
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
320
|
+
|
|
321
|
+
try {
|
|
322
|
+
while (true) {
|
|
323
|
+
await wrapper.connect(minter).mint(signers[0].address, MINTER_TX_MAX);
|
|
324
|
+
}
|
|
325
|
+
} catch (e) {
|
|
326
|
+
expect(e.message).to.contain("daily");
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it("should not be able to mint when passed tx cap", async () => {
|
|
331
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
332
|
+
|
|
333
|
+
await expect(
|
|
334
|
+
wrapper.connect(minter).mint(signers[0].address, MINTER_TX_MAX + 1)
|
|
335
|
+
).revertedWith("max");
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
it("should not be able to mint when passed minter cap", async () => {
|
|
339
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
340
|
+
|
|
341
|
+
for (let i = 0; i < MINTER_CAP / MINTER_TX_MAX; i++) {
|
|
342
|
+
if (i % 3 === 0) {
|
|
343
|
+
await increaseTime(60 * 60 * 24); //pass daily cap
|
|
344
|
+
}
|
|
345
|
+
await wrapper.connect(minter).mint(signers[0].address, MINTER_TX_MAX);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
await expect(
|
|
349
|
+
wrapper.connect(minter).mint(signers[0].address, MINTER_TX_MAX)
|
|
350
|
+
).revertedWith("minter cap");
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
xit("should not be able to mint when passed global cap", async () => {
|
|
354
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
355
|
+
|
|
356
|
+
await wrapper
|
|
357
|
+
.connect(wrapperAdmin)
|
|
358
|
+
.addMinter(minterUncapped.address, 0, 10000000000, 0, 0, 0, 0, false);
|
|
359
|
+
|
|
360
|
+
for (let i = 0; i < 100000000000 / 10000000000; i++)
|
|
361
|
+
await wrapper
|
|
362
|
+
.connect(minterUncapped)
|
|
363
|
+
.mint(signers[0].address, 10000000000);
|
|
364
|
+
|
|
365
|
+
await expect(
|
|
366
|
+
wrapper.connect(minterUncapped).mint(signers[0].address, 10000000000)
|
|
367
|
+
).revertedWith("total mint");
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it("should not be able to burn when passed daily cap", async () => {
|
|
371
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
372
|
+
await goodDollar.mint(signers[0].address, 100000000);
|
|
373
|
+
await goodDollar.connect(signers[0]).approve(wrapper.address, 100000000);
|
|
374
|
+
try {
|
|
375
|
+
while (true) {
|
|
376
|
+
await wrapper.connect(router).burn(signers[0].address, MINTER_TX_MAX);
|
|
377
|
+
}
|
|
378
|
+
} catch (e) {
|
|
379
|
+
expect(e.message).to.contain("daily");
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it("should not be able to burn when passed tx cap", async () => {
|
|
384
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
385
|
+
|
|
386
|
+
await goodDollar.mint(signers[0].address, 100000000);
|
|
387
|
+
await goodDollar.connect(signers[0]).approve(wrapper.address, 100000000);
|
|
388
|
+
await expect(
|
|
389
|
+
wrapper.connect(router).burn(signers[0].address, MINTER_TX_MAX + 1)
|
|
390
|
+
).revertedWith("max");
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
it("should not be able to burn when passed minter cap", async () => {
|
|
394
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
395
|
+
await goodDollar.mint(signers[0].address, 100000000);
|
|
396
|
+
await goodDollar.connect(signers[0]).approve(wrapper.address, 100000000);
|
|
397
|
+
|
|
398
|
+
for (let i = 0; i < MINTER_CAP / MINTER_TX_MAX; i++) {
|
|
399
|
+
if (i % 3 === 0) {
|
|
400
|
+
await increaseTime(60 * 60 * 24); //pass daily cap
|
|
401
|
+
}
|
|
402
|
+
await wrapper.connect(router).burn(signers[0].address, MINTER_TX_MAX);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
await expect(
|
|
406
|
+
wrapper.connect(router).burn(signers[0].address, MINTER_TX_MAX)
|
|
407
|
+
).revertedWith("minter cap");
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
it("should update stats after mint", async () => {
|
|
411
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
412
|
+
|
|
413
|
+
await wrapper.connect(minter).mint(signers[0].address, 1000);
|
|
414
|
+
|
|
415
|
+
expect(await goodDollar.balanceOf(signers[0].address)).to.eq(1000);
|
|
416
|
+
expect(await wrapper.totalMinted()).eq(1000);
|
|
417
|
+
|
|
418
|
+
const minterInfo = await wrapper.minterSupply(minter.address);
|
|
419
|
+
expect(minterInfo.totalIn).eq(1000);
|
|
420
|
+
|
|
421
|
+
await wrapper.connect(minter).mint(signers[0].address, 500);
|
|
422
|
+
const minterInfoAfter = await wrapper.minterSupply(minter.address);
|
|
423
|
+
expect(await wrapper.totalMinted()).eq(1500);
|
|
424
|
+
expect(minterInfoAfter.totalIn).eq(1500);
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
it("should be able to burn only by minter role", async () => {
|
|
428
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
429
|
+
await goodDollar.mint(founder.address, 1000);
|
|
430
|
+
await goodDollar.connect(founder).approve(wrapper.address, 1000);
|
|
431
|
+
await expect(
|
|
432
|
+
wrapper.connect(guardian).burn(founder.address, 1000)
|
|
433
|
+
).to.revertedWith("role");
|
|
434
|
+
await expect(wrapper.connect(router).burn(founder.address, 1000)).to.not
|
|
435
|
+
.reverted;
|
|
436
|
+
|
|
437
|
+
expect(await goodDollar.balanceOf(founder.address)).to.equal(0);
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
it("should not be able to burn when router is paused", async () => {
|
|
441
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
442
|
+
|
|
443
|
+
await expect(
|
|
444
|
+
wrapper.connect(guardian).pause(await wrapper.PAUSE_ROUTER_ROLE())
|
|
445
|
+
).to.not.reverted;
|
|
446
|
+
|
|
447
|
+
await goodDollar.mint(founder.address, 1000);
|
|
448
|
+
await goodDollar.connect(founder).approve(wrapper.address, 1000);
|
|
449
|
+
|
|
450
|
+
await expect(
|
|
451
|
+
wrapper.connect(router).burn(founder.address, 1000)
|
|
452
|
+
).revertedWith("pause");
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
it("should not update stats after burn when not minted yet", async () => {
|
|
456
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
457
|
+
|
|
458
|
+
await goodDollar.mint(founder.address, 1000);
|
|
459
|
+
await goodDollar.connect(founder).approve(wrapper.address, 1000);
|
|
460
|
+
await expect(wrapper.connect(router).burn(founder.address, 1000)).to.not
|
|
461
|
+
.reverted;
|
|
462
|
+
|
|
463
|
+
expect(await wrapper.totalMinted()).eq(0);
|
|
464
|
+
|
|
465
|
+
const minterInfo = await wrapper.minterSupply(minter.address);
|
|
466
|
+
expect(minterInfo.totalIn).eq(0);
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
it("should update global stats when minter!=burner after burn when already minted", async () => {
|
|
470
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
471
|
+
|
|
472
|
+
await wrapper.connect(minter).mint(signers[0].address, 1000);
|
|
473
|
+
|
|
474
|
+
await goodDollar.mint(founder.address, 500);
|
|
475
|
+
await goodDollar.connect(founder).approve(wrapper.address, 500);
|
|
476
|
+
await expect(wrapper.connect(router).burn(founder.address, 500)).to.not
|
|
477
|
+
.reverted;
|
|
478
|
+
|
|
479
|
+
expect(await wrapper.totalMinted()).eq(500);
|
|
480
|
+
|
|
481
|
+
const minterInfo = await wrapper.minterSupply(minter.address);
|
|
482
|
+
expect(minterInfo.totalIn).eq(1000);
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
it("should update both global and minter stats when minter==burner after burn when already minted", async () => {
|
|
486
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
487
|
+
|
|
488
|
+
await wrapper
|
|
489
|
+
.connect(wrapperAdmin)
|
|
490
|
+
.grantRole(await wrapper.ROUTER_ROLE(), minter.address);
|
|
491
|
+
await wrapper.connect(minter).mint(signers[0].address, 1000);
|
|
492
|
+
|
|
493
|
+
await goodDollar.mint(founder.address, 500);
|
|
494
|
+
await goodDollar.connect(founder).approve(wrapper.address, 500);
|
|
495
|
+
await expect(wrapper.connect(minter).burn(founder.address, 500)).to.not
|
|
496
|
+
.reverted;
|
|
497
|
+
|
|
498
|
+
expect(await wrapper.totalMinted()).eq(500);
|
|
499
|
+
|
|
500
|
+
const minterInfo = await wrapper.minterSupply(minter.address);
|
|
501
|
+
expect(minterInfo.totalIn).eq(500);
|
|
502
|
+
});
|
|
503
|
+
|
|
504
|
+
it("should reset minter total when burn amount > total", async () => {
|
|
505
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
506
|
+
|
|
507
|
+
await wrapper
|
|
508
|
+
.connect(wrapperAdmin)
|
|
509
|
+
.grantRole(await wrapper.ROUTER_ROLE(), minter.address);
|
|
510
|
+
await wrapper.connect(minter).mint(signers[0].address, 1000);
|
|
511
|
+
|
|
512
|
+
await goodDollar.mint(founder.address, 2000);
|
|
513
|
+
await goodDollar.connect(founder).approve(wrapper.address, 2000);
|
|
514
|
+
await expect(wrapper.connect(minter).burn(founder.address, 2000)).to.not
|
|
515
|
+
.reverted;
|
|
516
|
+
|
|
517
|
+
expect(await wrapper.totalMinted()).eq(0);
|
|
518
|
+
|
|
519
|
+
const minterInfo = await wrapper.minterSupply(minter.address);
|
|
520
|
+
expect(minterInfo.totalIn).eq(0);
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
it("should update mint stats after sendOrMint", async () => {
|
|
524
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
525
|
+
|
|
526
|
+
await wrapper.connect(rewarder).sendOrMint(signers[0].address, 1000);
|
|
527
|
+
const minterInfo = await wrapper.minterSupply(rewarder.address);
|
|
528
|
+
|
|
529
|
+
expect(await goodDollar.balanceOf(signers[0].address)).to.eq(1000);
|
|
530
|
+
expect(minterInfo.totalIn).eq(1000);
|
|
531
|
+
expect(minterInfo.mintedToday).eq(1000);
|
|
532
|
+
expect(minterInfo.totalRewards).eq(1000);
|
|
533
|
+
expect(await wrapper.totalMinted()).eq(1000);
|
|
534
|
+
expect(await wrapper.totalMintDebt()).eq(1000);
|
|
535
|
+
expect(await wrapper.totalRewards()).eq(1000);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
it("should not update mint stats after sendOrMint when wrapper has G$ balance", async () => {
|
|
539
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
540
|
+
|
|
541
|
+
await goodDollar.mint(wrapper.address, 1000);
|
|
542
|
+
|
|
543
|
+
await wrapper.connect(rewarder).sendOrMint(signers[0].address, 1000);
|
|
544
|
+
const minterInfo = await wrapper.minterSupply(rewarder.address);
|
|
545
|
+
|
|
546
|
+
expect(await goodDollar.balanceOf(signers[0].address)).to.eq(1000);
|
|
547
|
+
expect(minterInfo.totalIn).eq(0);
|
|
548
|
+
expect(minterInfo.totalRewards).eq(1000);
|
|
549
|
+
expect(minterInfo.mintedToday).eq(0);
|
|
550
|
+
expect(await wrapper.totalMinted()).eq(0);
|
|
551
|
+
expect(await wrapper.totalMintDebt()).eq(0);
|
|
552
|
+
expect(await wrapper.totalRewards()).eq(1000);
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
it("should perform send and mint when having partial balance for sendOrMint", async () => {
|
|
556
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
557
|
+
|
|
558
|
+
await goodDollar.mint(wrapper.address, 500);
|
|
559
|
+
|
|
560
|
+
await wrapper.connect(rewarder).sendOrMint(signers[0].address, 1000);
|
|
561
|
+
const minterInfo = await wrapper.minterSupply(rewarder.address);
|
|
562
|
+
|
|
563
|
+
expect(await goodDollar.balanceOf(signers[0].address)).to.eq(1000);
|
|
564
|
+
expect(await goodDollar.balanceOf(wrapper.address)).to.eq(0);
|
|
565
|
+
expect(minterInfo.totalIn).eq(500);
|
|
566
|
+
expect(minterInfo.totalRewards).eq(1000);
|
|
567
|
+
expect(minterInfo.mintedToday).eq(500);
|
|
568
|
+
expect(await wrapper.totalMinted()).eq(500);
|
|
569
|
+
expect(await wrapper.totalMintDebt()).eq(500);
|
|
570
|
+
expect(await wrapper.totalRewards()).eq(1000);
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
it("should reduce debt in sendOrMint", async () => {
|
|
574
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
575
|
+
|
|
576
|
+
await wrapper.connect(rewarder).sendOrMint(signers[0].address, 200); //200 debt
|
|
577
|
+
const minterInfo = await wrapper.minterSupply(rewarder.address);
|
|
578
|
+
expect(await wrapper.totalMintDebt()).eq(200);
|
|
579
|
+
expect(await wrapper.totalRewards()).eq(200);
|
|
580
|
+
expect(minterInfo.totalRewards).eq(200);
|
|
581
|
+
|
|
582
|
+
await goodDollar.mint(wrapper.address, 1200);
|
|
583
|
+
|
|
584
|
+
await wrapper.connect(rewarder).sendOrMint(signers[0].address, 1000);
|
|
585
|
+
const minterInfoAfter = await wrapper.minterSupply(rewarder.address);
|
|
586
|
+
|
|
587
|
+
expect(await wrapper.totalMintDebt()).eq(0);
|
|
588
|
+
expect(await wrapper.totalRewards()).eq(1200);
|
|
589
|
+
|
|
590
|
+
expect(minterInfoAfter.totalRewards).eq(1200);
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
it("should mint just partial amount if daily limit passed in sendOrMint", async () => {
|
|
594
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
595
|
+
|
|
596
|
+
let minterInfo = await wrapper.minterSupply(rewarder.address);
|
|
597
|
+
|
|
598
|
+
await wrapper
|
|
599
|
+
.connect(rewarder)
|
|
600
|
+
.sendOrMint(signers[0].address, minterInfo.dailyCapIn.add(1000));
|
|
601
|
+
|
|
602
|
+
minterInfo = await wrapper.minterSupply(rewarder.address);
|
|
603
|
+
|
|
604
|
+
expect(await goodDollar.balanceOf(signers[0].address)).to.eq(
|
|
605
|
+
minterInfo.dailyCapIn
|
|
606
|
+
);
|
|
607
|
+
expect(minterInfo.totalIn).eq(minterInfo.dailyCapIn);
|
|
608
|
+
expect(minterInfo.totalRewards).eq(minterInfo.dailyCapIn);
|
|
609
|
+
expect(minterInfo.mintedToday).eq(minterInfo.dailyCapIn);
|
|
610
|
+
expect(await wrapper.totalMinted()).eq(minterInfo.dailyCapIn);
|
|
611
|
+
expect(await wrapper.totalMintDebt()).eq(minterInfo.dailyCapIn);
|
|
612
|
+
expect(await wrapper.totalRewards()).eq(minterInfo.dailyCapIn);
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
it("should reset rewarder and minter mintedToday after day passed", async () => {
|
|
616
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
617
|
+
|
|
618
|
+
await wrapper.connect(rewarder).sendOrMint(signers[0].address, "1000");
|
|
619
|
+
|
|
620
|
+
await wrapper.connect(minter).mint(signers[0].address, "1000");
|
|
621
|
+
|
|
622
|
+
await increaseTime(60 * 60 * 24);
|
|
623
|
+
|
|
624
|
+
await expect(
|
|
625
|
+
wrapper.connect(rewarder).sendOrMint(signers[0].address, "1001")
|
|
626
|
+
).to.not.reverted;
|
|
627
|
+
|
|
628
|
+
await expect(wrapper.connect(minter).mint(signers[0].address, "1001")).to
|
|
629
|
+
.not.reverted;
|
|
630
|
+
|
|
631
|
+
expect(await goodDollar.balanceOf(signers[0].address)).to.eq("4002");
|
|
632
|
+
const minterInfo = await wrapper.minterSupply(rewarder.address);
|
|
633
|
+
const minterInfo2 = await wrapper.minterSupply(minter.address);
|
|
634
|
+
expect(minterInfo.mintedToday).eq(minterInfo2.mintedToday).eq("1001");
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
it("should update rewarder daily limit after updateFrequency days passed", async () => {
|
|
638
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
639
|
+
|
|
640
|
+
await goodDollar.mint(controller, 100000000000);
|
|
641
|
+
const totalSupplyBeforeMint = await goodDollar.totalSupply();
|
|
642
|
+
let minterInfo = await wrapper.minterSupply(rewarder.address);
|
|
643
|
+
|
|
644
|
+
const frequency = await wrapper.updateFrequency();
|
|
645
|
+
await increaseTime(frequency.toNumber());
|
|
646
|
+
|
|
647
|
+
await wrapper
|
|
648
|
+
.connect(rewarder)
|
|
649
|
+
.sendOrMint(signers[0].address, minterInfo.dailyCapIn.add(1000));
|
|
650
|
+
|
|
651
|
+
let minterInfoAfter = await wrapper.minterSupply(rewarder.address);
|
|
652
|
+
|
|
653
|
+
expect(minterInfoAfter.dailyCapIn).gt(minterInfo.dailyCapIn);
|
|
654
|
+
expect(minterInfoAfter.dailyCapIn).eq(
|
|
655
|
+
totalSupplyBeforeMint.mul(REWARD_BPS).div(10000)
|
|
656
|
+
); //we doubled the G$ supply so bps relative to supply should be double now
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
it("should not mint but not revert when rewarder passes daily limit", async () => {
|
|
660
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
661
|
+
|
|
662
|
+
const minterInfo = await wrapper.minterSupply(rewarder.address);
|
|
663
|
+
await wrapper
|
|
664
|
+
.connect(rewarder)
|
|
665
|
+
.sendOrMint(signers[0].address, minterInfo.dailyCapIn);
|
|
666
|
+
|
|
667
|
+
const tx = await (
|
|
668
|
+
await wrapper
|
|
669
|
+
.connect(rewarder)
|
|
670
|
+
.sendOrMint(signers[1].address, minterInfo.dailyCapIn)
|
|
671
|
+
).wait();
|
|
672
|
+
|
|
673
|
+
const sendOrMintEvent = tx.events.find(_ => _.event === "SendOrMint");
|
|
674
|
+
|
|
675
|
+
expect(await goodDollar.balanceOf(signers[1].address)).to.eq(0);
|
|
676
|
+
expect(sendOrMintEvent.args.minted).to.eq(0);
|
|
677
|
+
expect(sendOrMintEvent.args.sent).to.eq(0);
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
it("should allow guardian to update minter limits and rewarder daily limit", async () => {
|
|
681
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
682
|
+
|
|
683
|
+
await expect(
|
|
684
|
+
wrapper.setMinterCaps(minter.address, 0, 0, 0, 0, 0, 0)
|
|
685
|
+
).to.be.revertedWith("role");
|
|
686
|
+
|
|
687
|
+
await expect(
|
|
688
|
+
wrapper
|
|
689
|
+
.connect(guardian)
|
|
690
|
+
.setMinterCaps(minter.address, 0, 0, 50, 0, 0, 60)
|
|
691
|
+
).to.not.reverted;
|
|
692
|
+
|
|
693
|
+
const minterInfo = await wrapper.minterSupply(minter.address);
|
|
694
|
+
const minterOutLimits = await wrapper.minterOutLimits(minter.address);
|
|
695
|
+
|
|
696
|
+
expect(minterInfo.capIn).to.eq(0);
|
|
697
|
+
expect(minterInfo.maxIn).to.eq(0);
|
|
698
|
+
expect(minterInfo.bpsPerDayIn).to.eq(50);
|
|
699
|
+
expect(minterOutLimits.capOut).to.eq(0);
|
|
700
|
+
expect(minterOutLimits.maxOut).to.eq(0);
|
|
701
|
+
expect(minterOutLimits.bpsPerDayOut).to.eq(60);
|
|
702
|
+
expect(minterInfo.dailyCapIn).eq(
|
|
703
|
+
(await goodDollar.totalSupply()).mul(50).div(10000)
|
|
704
|
+
);
|
|
705
|
+
expect(minterOutLimits.dailyCapOut).eq(
|
|
706
|
+
(await goodDollar.totalSupply()).mul(60).div(10000)
|
|
707
|
+
);
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
xit("should allow guardian to update totalMintCap", async () => {
|
|
711
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
712
|
+
|
|
713
|
+
await expect(wrapper.setTotalMintCap(0)).to.be.revertedWith("role");
|
|
714
|
+
|
|
715
|
+
await expect(wrapper.connect(guardian).setTotalMintCap(0)).to.not.reverted;
|
|
716
|
+
|
|
717
|
+
expect(await wrapper.totalMintCap()).to.eq(0);
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
it("should support transferAndCall for multichain bridge transfer", async () => {
|
|
721
|
+
const { wrapper, multiChainRouter } = await waffle.loadFixture(
|
|
722
|
+
fixture_withMultichain
|
|
723
|
+
);
|
|
724
|
+
|
|
725
|
+
await goodDollar.mint(founder.address, 100000);
|
|
726
|
+
await goodDollar.transferAndCall(
|
|
727
|
+
wrapper.address,
|
|
728
|
+
100000,
|
|
729
|
+
ethers.utils.defaultAbiCoder.encode(
|
|
730
|
+
["address", "uint256"],
|
|
731
|
+
[minter.address, "4220"]
|
|
732
|
+
)
|
|
733
|
+
);
|
|
734
|
+
|
|
735
|
+
expect(await goodDollar.balanceOf(founder.address)).to.eq(0); //verify burn happened
|
|
736
|
+
expect(await goodDollar.balanceOf(wrapper.address)).to.eq(0); //verify burn happened
|
|
737
|
+
const events = await multiChainRouter.queryFilter(
|
|
738
|
+
multiChainRouter.filters.AnySwap()
|
|
739
|
+
);
|
|
740
|
+
expect(events[0].args.recipient).to.equal(minter.address);
|
|
741
|
+
expect(events[0].args.chainId).to.equal(4220);
|
|
742
|
+
});
|
|
743
|
+
|
|
744
|
+
it("should default to sender as recipient on transferAndCall if recipient=0", async () => {
|
|
745
|
+
const { wrapper, multiChainRouter } = await waffle.loadFixture(
|
|
746
|
+
fixture_withMultichain
|
|
747
|
+
);
|
|
748
|
+
|
|
749
|
+
await goodDollar.mint(founder.address, 100000);
|
|
750
|
+
await goodDollar.transferAndCall(
|
|
751
|
+
wrapper.address,
|
|
752
|
+
100000,
|
|
753
|
+
ethers.utils.defaultAbiCoder.encode(
|
|
754
|
+
["address", "uint256"],
|
|
755
|
+
[ethers.constants.AddressZero, "4220"]
|
|
756
|
+
)
|
|
757
|
+
);
|
|
758
|
+
|
|
759
|
+
expect(await goodDollar.balanceOf(founder.address)).to.eq(0); //verify burn happened
|
|
760
|
+
expect(await goodDollar.balanceOf(wrapper.address)).to.eq(0); //verify burn happened
|
|
761
|
+
const events = await multiChainRouter.queryFilter(
|
|
762
|
+
multiChainRouter.filters.AnySwap()
|
|
763
|
+
);
|
|
764
|
+
expect(events[0].args.recipient).to.equal(founder.address);
|
|
765
|
+
expect(events[0].args.chainId).to.equal(4220);
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
it("should fail transferAndCall for multichain if no chainid", async () => {
|
|
769
|
+
const { wrapper, multiChainRouter } = await waffle.loadFixture(
|
|
770
|
+
fixture_withMultichain
|
|
771
|
+
);
|
|
772
|
+
|
|
773
|
+
await goodDollar.mint(founder.address, 100000);
|
|
774
|
+
await expect(
|
|
775
|
+
goodDollar.transferAndCall(
|
|
776
|
+
wrapper.address,
|
|
777
|
+
100000,
|
|
778
|
+
ethers.utils.defaultAbiCoder.encode(
|
|
779
|
+
["address", "uint"],
|
|
780
|
+
[minter.address, 0]
|
|
781
|
+
)
|
|
782
|
+
)
|
|
783
|
+
).revertedWith("chainId");
|
|
784
|
+
});
|
|
785
|
+
|
|
786
|
+
it("should not mint or sendOrMint to self", async () => {
|
|
787
|
+
const { wrapper } = await waffle.loadFixture(fixture);
|
|
788
|
+
|
|
789
|
+
await expect(wrapper.connect(minter).mint(wrapper.address, 1)).revertedWith(
|
|
790
|
+
"self"
|
|
791
|
+
);
|
|
792
|
+
await expect(
|
|
793
|
+
wrapper.connect(rewarder).sendOrMint(wrapper.address, 1)
|
|
794
|
+
).revertedWith("self");
|
|
795
|
+
});
|
|
796
|
+
});
|