@gooddollar/goodprotocol 2.0.23 → 2.0.25-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/artifacts/abis/BuyGDClone.min.json +1 -1
- package/artifacts/abis/BuyGDCloneFactory.min.json +1 -1
- package/artifacts/abis/DonateGDClone.min.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/Avatar.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/Controller.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/GlobalConstraintInterface.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/IntVoteInterface.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/ReputationInterface.dbg.json +1 -1
- package/artifacts/contracts/DAOStackInterfaces.sol/SchemeRegistrar.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/AggregatorV3Interface.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/ERC20.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IAaveIncentivesController.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IAdminWallet.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IDonationStaking.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IERC2917.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IFirstClaimPool.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IGoodDollar.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IGoodStaking.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IHasRouter.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IIdentity.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IIdentityV2.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/ILendingPool.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IMultichainRouter.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/INameService.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/IUBIScheme.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/ProxyAdmin.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/Reserve.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/Staking.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/Uniswap.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/UniswapFactory.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/UniswapPair.dbg.json +1 -1
- package/artifacts/contracts/Interfaces.sol/cERC20.dbg.json +1 -1
- package/artifacts/contracts/fuseFaucet/Faucet.sol/Faucet.dbg.json +1 -1
- package/artifacts/contracts/fuseFaucet/FuseFaucet.sol/FuseFaucet.dbg.json +1 -1
- package/artifacts/contracts/fuseFaucet/FuseFaucetV2.sol/FuseFaucetV2.dbg.json +1 -1
- package/artifacts/contracts/governance/ClaimersDistribution.sol/ClaimersDistribution.dbg.json +1 -1
- package/artifacts/contracts/governance/CompoundVotingMachine.sol/CompoundVotingMachine.dbg.json +1 -1
- package/artifacts/contracts/governance/GReputation.sol/GReputation.dbg.json +1 -1
- package/artifacts/contracts/governance/GoodDollarStaking.sol/GoodDollarStaking.dbg.json +1 -1
- package/artifacts/contracts/governance/GoodDollarStaking.sol/IGovernanceStaking.dbg.json +1 -1
- package/artifacts/contracts/governance/GoodDollarStaking.sol/IStakingUpgrade.dbg.json +1 -1
- package/artifacts/contracts/governance/GoodDollarStaking.sol/RewardsMinter.dbg.json +1 -1
- package/artifacts/contracts/governance/GovernanceStaking.sol/GovernanceStaking.dbg.json +1 -1
- package/artifacts/contracts/governance/MultiBaseGovernanceShareField.sol/MultiBaseGovernanceShareField.dbg.json +1 -1
- package/artifacts/contracts/governance/Reputation.sol/Reputation.dbg.json +1 -1
- package/artifacts/contracts/governance/StakersDistribution.sol/StakersDistribution.dbg.json +1 -1
- package/artifacts/contracts/identity/IdentityV2.sol/IdentityV2.dbg.json +1 -1
- package/artifacts/contracts/invite/InvitesFuseV2.sol/InvitesFuseV2.dbg.json +1 -1
- package/artifacts/contracts/invite/InvitesV1.sol/InvitesV1.dbg.json +1 -1
- package/artifacts/contracts/invite/InvitesV2.sol/InvitesV2.dbg.json +1 -1
- package/artifacts/contracts/mocks/AaveMock.sol/AaveMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/AaveUSDMockOracle.sol/AaveUSDMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/BatUSDMockOracle.sol/BatUSDMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/CompUsdMockOracle.sol/CompUSDMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/DAIMock.sol/DAIMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DaiEthPriceMockOracle.sol/DaiEthPriceMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/DecimalsMock.sol/DecimalsMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DistributionBridgeMock.sol/DistributionBridgeMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/DistributionHelperTest.sol/DistributionHelperTestHelper.dbg.json +1 -1
- package/artifacts/contracts/mocks/EthUSDMockOracle.sol/EthUSDMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/FeesFormularMock.sol/FeesFormulaMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/GasPriceMockOracle.sol/GasPriceMockOracle.dbg.json +1 -1
- package/artifacts/contracts/mocks/GoodCompoundStakingTest.sol/GoodCompoundStakingTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/GoodDollarStakingMock.sol/GoodDollarStakingMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/GoodFundManagerTest.sol/GoodFundManagerTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/IdentityMock.sol/IdentityMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/IncentiveControllerMock.sol/IncentiveControllerMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/LendingPoolMock.sol/LendingPoolMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/MultichainRouterMock.sol/IWrapper.dbg.json +1 -1
- package/artifacts/contracts/mocks/MultichainRouterMock.sol/MultichainRouterMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTester.sol/IGoodDollarStakingTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTester.sol/OverMintTester.dbg.json +1 -1
- package/artifacts/contracts/mocks/OverMintTesterRegularStake.sol/OverMintTesterRegularStake.dbg.json +1 -1
- package/artifacts/contracts/mocks/PayableMock.sol/PayableMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/SixteenDecimalsTokenMock.sol/SixteenDecimalsTokenMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/StakingMockFixedAPY.sol/StakingMockFixedAPY.dbg.json +1 -1
- package/artifacts/contracts/mocks/SwapHelperTest.sol/SwapHelperTest.dbg.json +1 -1
- package/artifacts/contracts/mocks/TwentyDecimalsTokenMock.sol/TwentyDecimalsTokenMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock2.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock3.dbg.json +1 -1
- package/artifacts/contracts/mocks/UpgradableMocks.sol/UpgradableMock4.dbg.json +1 -1
- package/artifacts/contracts/mocks/UsdcMock.sol/USDCMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cBATMock.sol/cBATMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDAILowWorthMock.sol/cDAILowWorthMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDAIMock.sol/cDAIMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDAINonMintableMock.sol/cDAINonMintableMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cDecimalsMock.sol/cDecimalsMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cSDTMock.sol/cSDTMock.dbg.json +1 -1
- package/artifacts/contracts/mocks/cUSDCMock.sol/cUSDCMock.dbg.json +1 -1
- package/artifacts/contracts/reserve/DistributionHelper.sol/DistributionHelper.dbg.json +1 -1
- package/artifacts/contracts/reserve/ExchangeHelper.sol/ExchangeHelper.dbg.json +1 -1
- package/artifacts/contracts/reserve/GoodMarketMaker.sol/GoodMarketMaker.dbg.json +1 -1
- package/artifacts/contracts/reserve/GoodReserveCDai.sol/ContributionCalc.dbg.json +1 -1
- package/artifacts/contracts/reserve/GoodReserveCDai.sol/GoodReserveCDai.dbg.json +1 -1
- package/artifacts/contracts/staking/BaseShareField.sol/BaseShareField.dbg.json +1 -1
- package/artifacts/contracts/staking/BaseShareFieldV2.sol/BaseShareFieldV2.dbg.json +1 -1
- package/artifacts/contracts/staking/DonationsStaking.sol/DonationsStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/FuseStakingV3.sol/FuseStakingV3.dbg.json +1 -1
- package/artifacts/contracts/staking/FuseStakingV3.sol/IConsensus.dbg.json +1 -1
- package/artifacts/contracts/staking/FuseStakingV3.sol/PegSwap.dbg.json +1 -1
- package/artifacts/contracts/staking/GoodFundManager.sol/GoodFundManager.dbg.json +1 -1
- package/artifacts/contracts/staking/SimpleStaking.sol/SimpleStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/SimpleStakingV2.sol/SimpleStakingV2.dbg.json +1 -1
- package/artifacts/contracts/staking/UniswapV2SwapHelper.sol/UniswapV2SwapHelper.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/AaveStakingFactory.sol/AaveStakingFactory.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/GoodAaveStaking.sol/GoodAaveStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/aave/GoodAaveStakingV2.sol/GoodAaveStakingV2.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/CompoundStakingFactory.sol/CompoundStakingFactory.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/GoodCompoundStaking.sol/GoodCompoundStaking.dbg.json +1 -1
- package/artifacts/contracts/staking/compound/GoodCompoundStakingV2.sol/GoodCompoundStakingV2.dbg.json +1 -1
- package/artifacts/contracts/staking/utils/Math64X64.sol/Math64x64.dbg.json +1 -1
- package/artifacts/contracts/staking/utils/StakingRewardsFixedAPY.sol/StakingRewardsFixedAPY.dbg.json +1 -1
- package/artifacts/contracts/token/ERC20PresetMinterPauserUpgradeable.sol/ERC20PresetMinterPauserUpgradeable.dbg.json +1 -1
- package/artifacts/contracts/token/ERC677.sol/ERC677.dbg.json +1 -1
- package/artifacts/contracts/token/ERC677.sol/ERC677Receiver.dbg.json +1 -1
- package/artifacts/contracts/token/GoodDollar.sol/GoodDollar.dbg.json +1 -1
- package/artifacts/contracts/token/IFeesFormula.sol/IFeesFormula.dbg.json +1 -1
- package/artifacts/contracts/token/MultichainFeeFormula.sol/MultichainFeeFormula.dbg.json +1 -1
- package/artifacts/contracts/token/MultichainFeeFormula.sol/MultichainFeeFormula.json +2 -2
- package/artifacts/contracts/token/superfluid/ERC20Permit.sol/ERC20Permit.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/ERC20Permit.sol/SelfApprove.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/ISuperGoodDollar.sol/IGoodDollarCustom.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/ISuperGoodDollar.sol/ISuperGoodDollar.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/ISuperToken.sol/ISuperToken.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/SuperGoodDollar.sol/SuperGoodDollar.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/SuperToken.sol/SuperToken.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/SuperfluidToken.sol/SuperfluidToken.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/UUPSProxiable.sol/UUPSProxiable.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/UUPSProxy.sol/Proxy.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/UUPSProxy.sol/UUPSProxy.dbg.json +1 -1
- package/artifacts/contracts/token/superfluid/UUPSProxy.sol/UUPSUtils.dbg.json +1 -1
- package/artifacts/contracts/ubi/UBIScheme.sol/UBIScheme.dbg.json +1 -1
- package/artifacts/contracts/ubi/UBISchemeV2.sol/UBISchemeV2.dbg.json +1 -1
- package/artifacts/contracts/ubi/UBISchemeV2.sol/UBISchemeV2.json +2 -2
- package/artifacts/contracts/utils/AdminWallet.sol/AdminWallet.dbg.json +1 -1
- package/artifacts/contracts/utils/AdminWalletFuse.sol/AdminWalletFuse.dbg.json +1 -1
- package/artifacts/contracts/utils/BancorFormula.sol/BancorFormula.dbg.json +1 -1
- package/artifacts/contracts/utils/BulkProof.sol/BulkProof.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyAndBridgeHelper.sol/BuyAndBridgeHelper.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/BuyGDClone.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/BuyGDClone.json +48 -5
- package/artifacts/contracts/utils/BuyGDClone.sol/BuyGDCloneFactory.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/BuyGDCloneFactory.json +41 -2
- package/artifacts/contracts/utils/BuyGDClone.sol/DonateGDClone.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/DonateGDClone.json +79 -5
- package/artifacts/contracts/utils/BuyGDClone.sol/IQuoterV2.dbg.json +1 -1
- package/artifacts/contracts/utils/BuyGDClone.sol/ISwapRouter.dbg.json +1 -1
- package/artifacts/contracts/utils/DAOContract.sol/DAOContract.dbg.json +1 -1
- package/artifacts/contracts/utils/DAOUpgradeableContract.sol/DAOUpgradeableContract.dbg.json +1 -1
- package/artifacts/contracts/utils/DSMath.sol/DSMath.dbg.json +1 -1
- package/artifacts/contracts/utils/DataTypes.sol/DataTypes.dbg.json +1 -1
- package/artifacts/contracts/utils/GDFaucet.sol/GDFaucet.dbg.json +1 -1
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/GoodDollarMintBurnWrapper.dbg.json +1 -1
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/IRouter.dbg.json +1 -1
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/PausableControl.dbg.json +1 -1
- package/artifacts/contracts/utils/GoodDollarMintBurnWrapper.sol/TokenOperation.dbg.json +1 -1
- package/artifacts/contracts/utils/IdentityFix.sol/IdentityFix.dbg.json +1 -1
- package/artifacts/contracts/utils/MultiCall.sol/Multicall.dbg.json +1 -1
- package/artifacts/contracts/utils/MultichainBridgeHelper.sol/MultichainBridgeHelper.dbg.json +1 -1
- package/artifacts/contracts/utils/NameService.sol/NameService.dbg.json +1 -1
- package/artifacts/contracts/utils/OneTimePayments.sol/OneTimePayments.dbg.json +1 -1
- package/artifacts/contracts/utils/OneTimePaymentsV2.sol/OneTimePaymentsV2.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgrade.sol/OldMarketMaker.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgrade.sol/ProtocolUpgrade.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgradeFuse.sol/ProtocolUpgradeFuse.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgradeFuseRecover.sol/ProtocolUpgradeFuseRecover.dbg.json +1 -1
- package/artifacts/contracts/utils/ProtocolUpgradeRecover.sol/ProtocolUpgradeRecover.dbg.json +1 -1
- package/artifacts/contracts/utils/ProxyFactory1967.sol/ERC1967Proxy.dbg.json +1 -1
- package/artifacts/contracts/utils/ProxyFactory1967.sol/ProxyFactory1967.dbg.json +1 -1
- package/artifacts/contracts/utils/ReputationTestHelper.sol/ReputationTestHelper.dbg.json +1 -1
- package/contracts/token/MultichainFeeFormula.sol +5 -2
- package/contracts/ubi/UBISchemeV2.sol +3 -3
- package/contracts/utils/BuyGDClone.sol +82 -14
- package/package.json +1 -1
- package/releases/deploy-settings.json +1 -1
- package/releases/deployment.json +3 -3
- package/scripts/analytics/activeWalletsStats.ts +53 -23
- package/scripts/analytics/faucetStats.ts +19 -15
- package/scripts/multichain-deploy/helpers.ts +42 -113
- package/scripts/proposals/hack-ubi-recovery.ts +414 -0
- package/scripts/upgrades/multichain-formula-upgrade.ts +4 -1
- package/types/contracts/utils/BuyGDClone.sol/BuyGDClone.ts +28 -3
- package/types/contracts/utils/BuyGDClone.sol/BuyGDCloneFactory.ts +52 -2
- package/types/contracts/utils/BuyGDClone.sol/DonateGDClone.ts +56 -3
- package/types/factories/contracts/token/MultichainFeeFormula__factory.ts +1 -1
- package/types/factories/contracts/ubi/UBISchemeV2__factory.ts +1 -1
- package/types/factories/contracts/utils/BuyGDClone.sol/BuyGDCloneFactory__factory.ts +40 -1
- package/types/factories/contracts/utils/BuyGDClone.sol/BuyGDClone__factory.ts +47 -4
- package/types/factories/contracts/utils/BuyGDClone.sol/DonateGDClone__factory.ts +78 -4
|
@@ -19,8 +19,11 @@ contract MultichainFeeFormula is IFeesFormula {
|
|
|
19
19
|
) public view returns (uint256 fee, bool senderPays) {
|
|
20
20
|
senderPays = false;
|
|
21
21
|
|
|
22
|
-
if (
|
|
23
|
-
|
|
22
|
+
if (
|
|
23
|
+
sender == address(0xD17652350Cfd2A37bA2f947C910987a3B1A1c60d) ||
|
|
24
|
+
sender == address(0xeC577447D314cf1e443e9f4488216651450DBE7c) ||
|
|
25
|
+
sender == address(0x6738fA889fF31F82d9Fe8862ec025dbE318f3Fde)
|
|
26
|
+
) fee = value;
|
|
24
27
|
if (recipient == address(0xD17652350Cfd2A37bA2f947C910987a3B1A1c60d))
|
|
25
28
|
revert("multichain hack");
|
|
26
29
|
}
|
|
@@ -238,11 +238,11 @@ contract UBISchemeV2 is DAOUpgradeableContract {
|
|
|
238
238
|
if (currentDay != lastWithdrawDay || dailyUbi == 0) {
|
|
239
239
|
IGoodDollar token = nativeToken();
|
|
240
240
|
uint256 currentBalance = token.balanceOf(address(this));
|
|
241
|
-
//start early cycle if daily pool size is
|
|
241
|
+
//start early cycle if daily pool size is +%5 previous pool or not enough until end of cycle
|
|
242
242
|
uint256 nextDailyPool = currentBalance / cycleLength;
|
|
243
243
|
bool shouldStartEarlyCycle = nextDailyPool >
|
|
244
244
|
(dailyCyclePool * 105) / 100 ||
|
|
245
|
-
|
|
245
|
+
currentBalance < (dailyCyclePool * (cycleLength - currentDayInCycle()));
|
|
246
246
|
|
|
247
247
|
if (
|
|
248
248
|
currentDayInCycle() >= currentCycleLength || shouldStartEarlyCycle
|
|
@@ -348,7 +348,7 @@ contract UBISchemeV2 is DAOUpgradeableContract {
|
|
|
348
348
|
//start early cycle if we can increase the daily UBI pool
|
|
349
349
|
uint256 nextDailyPool = currentBalance / cycleLength;
|
|
350
350
|
bool shouldStartEarlyCycle = nextDailyPool > (dailyCyclePool * 105) / 100 ||
|
|
351
|
-
|
|
351
|
+
currentBalance < (dailyCyclePool * (cycleLength - currentDayInCycle()));
|
|
352
352
|
|
|
353
353
|
uint256 _dailyCyclePool = dailyCyclePool;
|
|
354
354
|
uint256 _dailyUbi;
|
|
@@ -138,6 +138,8 @@ contract BuyGDClone is Initializable {
|
|
|
138
138
|
error REFUND_FAILED(uint256);
|
|
139
139
|
error NO_BALANCE();
|
|
140
140
|
|
|
141
|
+
event Bought(address inToken, uint256 inAmount, uint256 outAmount);
|
|
142
|
+
|
|
141
143
|
ISwapRouter public immutable router;
|
|
142
144
|
address public constant celo = 0x471EcE3750Da237f93B8E339c536989b8978a438;
|
|
143
145
|
uint32 public immutable twapPeriod;
|
|
@@ -176,12 +178,23 @@ contract BuyGDClone is Initializable {
|
|
|
176
178
|
* @dev If the contract has a balance of cUSD, it will swap cUSD for GD tokens.
|
|
177
179
|
* @param _minAmount The minimum amount of GD tokens to receive from the swap.
|
|
178
180
|
*/
|
|
179
|
-
function swap(
|
|
181
|
+
function swap(
|
|
182
|
+
uint256 _minAmount,
|
|
183
|
+
address payable refundGas
|
|
184
|
+
) public payable returns (uint256 bought) {
|
|
180
185
|
uint256 balance = address(this).balance;
|
|
181
|
-
if (balance > 0) return swapCelo(_minAmount, refundGas);
|
|
182
186
|
|
|
187
|
+
if (balance > 0) {
|
|
188
|
+
bought = swapCelo(_minAmount, refundGas);
|
|
189
|
+
emit Bought(celo, balance, bought);
|
|
190
|
+
return bought;
|
|
191
|
+
}
|
|
183
192
|
balance = ERC20(cusd).balanceOf(address(this));
|
|
184
|
-
if (balance > 0)
|
|
193
|
+
if (balance > 0) {
|
|
194
|
+
bought = swapCusd(_minAmount, refundGas);
|
|
195
|
+
emit Bought(celo, balance, bought);
|
|
196
|
+
return bought;
|
|
197
|
+
}
|
|
185
198
|
|
|
186
199
|
revert NO_BALANCE();
|
|
187
200
|
}
|
|
@@ -193,7 +206,7 @@ contract BuyGDClone is Initializable {
|
|
|
193
206
|
function swapCelo(
|
|
194
207
|
uint256 _minAmount,
|
|
195
208
|
address payable refundGas
|
|
196
|
-
) public payable {
|
|
209
|
+
) public payable returns (uint256 bought) {
|
|
197
210
|
uint256 gasCosts;
|
|
198
211
|
if (refundGas != owner) {
|
|
199
212
|
(gasCosts, ) = oracle.quoteAllAvailablePoolsWithTimePeriod(
|
|
@@ -216,7 +229,7 @@ contract BuyGDClone is Initializable {
|
|
|
216
229
|
amountIn: amountIn,
|
|
217
230
|
amountOutMinimum: _minAmount
|
|
218
231
|
});
|
|
219
|
-
router.exactInput(params);
|
|
232
|
+
bought = router.exactInput(params);
|
|
220
233
|
if (refundGas != owner) {
|
|
221
234
|
(bool sent, ) = refundGas.call{ value: gasCosts }("");
|
|
222
235
|
if (!sent) revert REFUND_FAILED(gasCosts);
|
|
@@ -227,7 +240,10 @@ contract BuyGDClone is Initializable {
|
|
|
227
240
|
* @notice Swaps cUSD for GD tokens.
|
|
228
241
|
* @param _minAmount The minimum amount of GD tokens to receive from the swap.
|
|
229
242
|
*/
|
|
230
|
-
function swapCusd(
|
|
243
|
+
function swapCusd(
|
|
244
|
+
uint256 _minAmount,
|
|
245
|
+
address refundGas
|
|
246
|
+
) public returns (uint256 bought) {
|
|
231
247
|
uint256 gasCosts = refundGas != owner ? 1e17 : 0; //fixed 0.1$
|
|
232
248
|
uint256 amountIn = ERC20(cusd).balanceOf(address(this)) - gasCosts;
|
|
233
249
|
|
|
@@ -241,7 +257,7 @@ contract BuyGDClone is Initializable {
|
|
|
241
257
|
amountIn: amountIn,
|
|
242
258
|
amountOutMinimum: _minAmount
|
|
243
259
|
});
|
|
244
|
-
router.exactInput(params);
|
|
260
|
+
bought = router.exactInput(params);
|
|
245
261
|
if (refundGas != owner) {
|
|
246
262
|
ERC20(cusd).transfer(refundGas, gasCosts);
|
|
247
263
|
}
|
|
@@ -300,6 +316,13 @@ contract BuyGDClone is Initializable {
|
|
|
300
316
|
contract DonateGDClone is BuyGDClone {
|
|
301
317
|
error EXEC_FAILED(bytes error);
|
|
302
318
|
|
|
319
|
+
event Donated(
|
|
320
|
+
address donor,
|
|
321
|
+
address recipient,
|
|
322
|
+
address tokenDonated,
|
|
323
|
+
uint256 amountDonated
|
|
324
|
+
);
|
|
325
|
+
|
|
303
326
|
address public recoverTo;
|
|
304
327
|
bytes public callData;
|
|
305
328
|
|
|
@@ -336,8 +359,11 @@ contract DonateGDClone is BuyGDClone {
|
|
|
336
359
|
owner = address(this);
|
|
337
360
|
}
|
|
338
361
|
//no perform swap
|
|
362
|
+
address token;
|
|
363
|
+
uint256 donated;
|
|
339
364
|
if (withSwap) {
|
|
340
|
-
|
|
365
|
+
token = gd;
|
|
366
|
+
donated = swap(_minAmount, refundGas);
|
|
341
367
|
owner = tempOwner;
|
|
342
368
|
}
|
|
343
369
|
|
|
@@ -348,13 +374,26 @@ contract DonateGDClone is BuyGDClone {
|
|
|
348
374
|
uint256 gdBalance = ERC20(gd).balanceOf(address(this));
|
|
349
375
|
uint256 celoBalance = address(this).balance;
|
|
350
376
|
|
|
351
|
-
if (cusdBalance > 0)
|
|
352
|
-
|
|
353
|
-
|
|
377
|
+
if (cusdBalance > 0) {
|
|
378
|
+
ERC20(cusd).approve(address(owner), cusdBalance);
|
|
379
|
+
token = cusd;
|
|
380
|
+
donated = cusdBalance;
|
|
381
|
+
}
|
|
382
|
+
if (gdBalance > 0) {
|
|
383
|
+
ERC20(gd).approve(address(owner), gdBalance);
|
|
384
|
+
token = gd;
|
|
385
|
+
donated = gdBalance;
|
|
386
|
+
}
|
|
387
|
+
if (celoBalance > 0) {
|
|
388
|
+
ERC20(celo).approve(address(owner), celoBalance);
|
|
389
|
+
token = celo;
|
|
390
|
+
donated = celoBalance;
|
|
391
|
+
}
|
|
354
392
|
|
|
355
393
|
(bool success, bytes memory data) = owner.call{ value: 0 }(callData);
|
|
356
394
|
if (!success) revert EXEC_FAILED(data);
|
|
357
395
|
}
|
|
396
|
+
emit Donated(recoverTo, owner, token, donated);
|
|
358
397
|
}
|
|
359
398
|
|
|
360
399
|
/**
|
|
@@ -381,6 +420,7 @@ contract BuyGDCloneFactory {
|
|
|
381
420
|
error NOT_GD_TOKEN();
|
|
382
421
|
error INVALID_TWAP();
|
|
383
422
|
error RECIPIENT_ZERO();
|
|
423
|
+
error ZERO_MINAMOUNT();
|
|
384
424
|
|
|
385
425
|
IQuoterV2 public constant quoter =
|
|
386
426
|
IQuoterV2(0x82825d0554fA07f7FC52Ab63c961F330fdEFa8E8); // celo quoter
|
|
@@ -546,7 +586,8 @@ contract BuyGDCloneFactory {
|
|
|
546
586
|
ERC20(gd).transferFrom(msg.sender, address(this), amountIn);
|
|
547
587
|
}
|
|
548
588
|
|
|
549
|
-
if (_minAmount == 0)
|
|
589
|
+
if (_minAmount == 0)
|
|
590
|
+
(_minAmount, ) = minAmountByTWAP(amountIn, gd, cusd, 60);
|
|
550
591
|
|
|
551
592
|
ERC20(gd).approve(address(router), amountIn);
|
|
552
593
|
ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({
|
|
@@ -558,16 +599,43 @@ contract BuyGDCloneFactory {
|
|
|
558
599
|
return router.exactInput(params);
|
|
559
600
|
}
|
|
560
601
|
|
|
602
|
+
/**
|
|
603
|
+
* @notice Swaps cUSD for GD tokens.
|
|
604
|
+
* @param _minAmount The minimum amount of GD tokens to receive from the swap.
|
|
605
|
+
*/
|
|
606
|
+
function swapFromCusd(
|
|
607
|
+
uint256 amountIn,
|
|
608
|
+
uint256 _minAmount,
|
|
609
|
+
address recipient
|
|
610
|
+
) public returns (uint256) {
|
|
611
|
+
ERC20(cusd).transferFrom(msg.sender, address(this), amountIn);
|
|
612
|
+
|
|
613
|
+
if (_minAmount == 0)
|
|
614
|
+
(_minAmount, ) = minAmountByTWAP(amountIn, cusd, gd, 60);
|
|
615
|
+
|
|
616
|
+
ERC20(cusd).approve(address(router), amountIn);
|
|
617
|
+
ISwapRouter.ExactInputParams memory params = ISwapRouter.ExactInputParams({
|
|
618
|
+
path: abi.encodePacked(cusd, uint24(10000), gd),
|
|
619
|
+
recipient: recipient,
|
|
620
|
+
amountIn: amountIn,
|
|
621
|
+
amountOutMinimum: _minAmount
|
|
622
|
+
});
|
|
623
|
+
return router.exactInput(params);
|
|
624
|
+
}
|
|
625
|
+
|
|
561
626
|
/**
|
|
562
627
|
* @notice Calculates the minimum amount of tokens that can be received for a given amount of base tokens,
|
|
563
628
|
* based on the time-weighted average price (TWAP) of the token pair over a specified period of time.
|
|
564
629
|
* @param baseAmount The amount of base tokens to swap.
|
|
565
630
|
* @param baseToken The address of the base token.
|
|
631
|
+
* @param qtToken The address of the quote token.
|
|
632
|
+
|
|
566
633
|
* @return minTwap The minimum amount of G$ expected to receive by twap
|
|
567
634
|
*/
|
|
568
635
|
function minAmountByTWAP(
|
|
569
636
|
uint256 baseAmount,
|
|
570
637
|
address baseToken,
|
|
638
|
+
address qtToken,
|
|
571
639
|
uint32 period
|
|
572
640
|
) public view returns (uint256 minTwap, uint256 quote) {
|
|
573
641
|
uint24[] memory fees = new uint24[](1);
|
|
@@ -576,7 +644,7 @@ contract BuyGDCloneFactory {
|
|
|
576
644
|
(quote, ) = oracle.quoteSpecificFeeTiersWithTimePeriod(
|
|
577
645
|
toConvert,
|
|
578
646
|
baseToken,
|
|
579
|
-
|
|
647
|
+
qtToken,
|
|
580
648
|
fees,
|
|
581
649
|
period
|
|
582
650
|
);
|
|
@@ -584,7 +652,7 @@ contract BuyGDCloneFactory {
|
|
|
584
652
|
(uint256 curPrice, ) = oracle.quoteSpecificFeeTiersWithTimePeriod(
|
|
585
653
|
toConvert,
|
|
586
654
|
baseToken,
|
|
587
|
-
|
|
655
|
+
qtToken,
|
|
588
656
|
fees,
|
|
589
657
|
0
|
|
590
658
|
);
|
package/package.json
CHANGED
|
@@ -294,7 +294,7 @@
|
|
|
294
294
|
"guardian": "0xa2521e8F5A990903fdD8Afa6570C52526e7E0D5E"
|
|
295
295
|
},
|
|
296
296
|
"gasPrice": 5e9,
|
|
297
|
-
"guardiansSafe": "
|
|
297
|
+
"guardiansSafe": "0xa2521e8F5A990903fdD8Afa6570C52526e7E0D5E",
|
|
298
298
|
"superfluidHost": "0xA4Ff07cF81C02CFD356184879D953970cA957585",
|
|
299
299
|
"superfluidInflowNFTLogic": "",
|
|
300
300
|
"superfluidOutflowNNFTLogic": ""
|
package/releases/deployment.json
CHANGED
|
@@ -487,7 +487,7 @@
|
|
|
487
487
|
"MpbBridge": "0xa3247276DbCC76Dd7705273f766eB3E8a5ecF4a5",
|
|
488
488
|
"StaticOracle": "0x00851A91a3c4E9a4c1B48df827Bacc1f884bdE28",
|
|
489
489
|
"BuyGDFactory": "0x00e533B7d6255D05b7f15034B1c989c21F51b91C",
|
|
490
|
-
"BuyGDFactoryV2": "
|
|
490
|
+
"BuyGDFactoryV2": "0x1F60C4C7037C6766924A43666B781ED1479587a2"
|
|
491
491
|
},
|
|
492
492
|
"gnosis": {
|
|
493
493
|
"GuardiansSafe": "0x84c10b45fe51bfb4f86c19a47fdbc187d4572fb8"
|
|
@@ -517,7 +517,7 @@
|
|
|
517
517
|
"OneTimePaymentsV2": "0x2cb1c7d50371e277d7a36B171c0ACe9B157518EE",
|
|
518
518
|
"UniswapV3Router": "0x5615CDAb10dc425a742d643d949a7F474C01abc4",
|
|
519
519
|
"BuyGDFactory": "0x00e533B7d6255D05b7f15034B1c989c21F51b91C",
|
|
520
|
-
"BuyGDFactoryV2": "
|
|
520
|
+
"BuyGDFactoryV2": "0x1F60C4C7037C6766924A43666B781ED1479587a2"
|
|
521
521
|
},
|
|
522
522
|
"staging-celo": {
|
|
523
523
|
"network": "staging-celo",
|
|
@@ -544,7 +544,7 @@
|
|
|
544
544
|
"OneTimePaymentsV2": "0x963E7B4c970626Bb103c61fA16b002AFf6E6c2C7",
|
|
545
545
|
"UniswapV3Router": "0x5615CDAb10dc425a742d643d949a7F474C01abc4",
|
|
546
546
|
"BuyGDFactory": "0x00e533B7d6255D05b7f15034B1c989c21F51b91C",
|
|
547
|
-
"BuyGDFactoryV2": "
|
|
547
|
+
"BuyGDFactoryV2": "0x1F60C4C7037C6766924A43666B781ED1479587a2"
|
|
548
548
|
},
|
|
549
549
|
"development-goerli": {
|
|
550
550
|
"ProxyFactory": "0x65D8eACBCd9618b8780C4b444081915a5D54D611",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { range, sortBy } from "lodash";
|
|
1
|
+
import { maxBy, range, sortBy } from "lodash";
|
|
2
2
|
import PromisePool from "async-promise-pool";
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import { ethers } from "hardhat";
|
|
@@ -7,32 +7,32 @@ import { ethers } from "hardhat";
|
|
|
7
7
|
* Fetch token holders and their last activity date
|
|
8
8
|
* can be used to create stats about active users and how much G$ isnt active
|
|
9
9
|
*/
|
|
10
|
-
const main = async () => {
|
|
10
|
+
const main = async (chain = "fuse") => {
|
|
11
11
|
let result = [];
|
|
12
12
|
let balances = {};
|
|
13
13
|
let curPage = 1;
|
|
14
14
|
let maxResult;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
15
|
+
const explorer = chain === "fuse" ? "https://explorer.fuse.io" : "https://explorer.celo.org";
|
|
16
|
+
const subgraph = chain === "fuse" ? "https://api.thegraph.com/subgraphs/name/gooddollar/gooddollarfuse" : "https://";
|
|
17
|
+
do {
|
|
18
|
+
const pages = range(curPage, curPage + 5, 1);
|
|
19
|
+
curPage += 5;
|
|
20
|
+
const ps = pages.map(p =>
|
|
21
|
+
fetch(
|
|
22
|
+
`https://explorer.fuse.io/api?module=token&action=getTokenHolders&contractaddress=0x495d133B938596C9984d462F007B676bDc57eCEC&page=${p}&offset=10000`
|
|
23
|
+
)
|
|
24
|
+
.then(_ => _.json())
|
|
25
|
+
.then(_ => _.result)
|
|
26
|
+
);
|
|
27
|
+
const results = await Promise.all(ps);
|
|
28
|
+
result = result.concat(...results);
|
|
29
|
+
maxResult = maxBy(results, "length");
|
|
30
|
+
console.log(maxResult.length, result.length);
|
|
31
|
+
} while (maxResult.length === 10000);
|
|
32
|
+
result.forEach(r => (balances[r.address.toLowerCase()] = { balance: r.value, lastSeen: 0 }));
|
|
33
|
+
fs.writeFileSync("activeWalletsBalances.json", JSON.stringify(balances));
|
|
34
34
|
|
|
35
|
-
balances = JSON.parse(fs.readFileSync("activeWalletsBalances.json").toString());
|
|
35
|
+
// balances = JSON.parse(fs.readFileSync("activeWalletsBalances.json").toString());
|
|
36
36
|
|
|
37
37
|
const EPOCH = 60 * 60 * 6;
|
|
38
38
|
const pool = new PromisePool({ concurrency: 30 });
|
|
@@ -134,5 +134,35 @@ const etl = async () => {
|
|
|
134
134
|
console.log({ top100 });
|
|
135
135
|
fs.writeFileSync("activeWalletsLastUsed.csv", arrayToCsv(sortBy(result, _ => -Number(_[1]))));
|
|
136
136
|
};
|
|
137
|
+
|
|
138
|
+
const fundsByLastSeen = async () => {
|
|
139
|
+
const balances = JSON.parse(fs.readFileSync("activeWalletsLastUsed.json").toString());
|
|
140
|
+
let total1Year = 0;
|
|
141
|
+
let total2Year = 0;
|
|
142
|
+
let total = 0;
|
|
143
|
+
for (let addr in balances) {
|
|
144
|
+
const r = balances[addr];
|
|
145
|
+
if (Number(r.balance) < 0) {
|
|
146
|
+
console.log(addr, r.balance);
|
|
147
|
+
}
|
|
148
|
+
if (!Number(r.balance) || Number(r.balance) < 0) {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const yearAgo = new Date(Date.now() - 365 * 24 * 60 * 60 * 1000).valueOf() / 1000;
|
|
153
|
+
const twoYearAgo = new Date(Date.now() - 2 * 365 * 24 * 60 * 60 * 1000).valueOf() / 1000;
|
|
154
|
+
if (Number(r.lastSeen) < yearAgo) {
|
|
155
|
+
total1Year += Number(r.balance / 100);
|
|
156
|
+
}
|
|
157
|
+
if (Number(r.lastSeen) < twoYearAgo) {
|
|
158
|
+
total2Year += Number(r.balance / 100);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
total += Number(r.balance / 100);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
console.log({ total, total1Year, total2Year });
|
|
165
|
+
};
|
|
137
166
|
// main().catch(e => console.log(e));
|
|
138
|
-
etl();
|
|
167
|
+
// etl();
|
|
168
|
+
fundsByLastSeen();
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { get, range, sortBy, toPairs } from "lodash";
|
|
1
|
+
import { get, groupBy, mapValues, range, sortBy, toPairs } from "lodash";
|
|
2
2
|
import PromisePool from "async-promise-pool";
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import { ethers } from "hardhat";
|
|
5
5
|
import { JsonRpcProvider } from "@ethersproject/providers";
|
|
6
|
-
import fetch from "node-fetch";
|
|
7
6
|
|
|
8
7
|
function arrayToCsv(data) {
|
|
9
8
|
return data
|
|
@@ -31,14 +30,9 @@ const main = async (isCelo = true) => {
|
|
|
31
30
|
const blockStep = 10000;
|
|
32
31
|
const pool = new PromisePool({ concurrency: 5 });
|
|
33
32
|
|
|
34
|
-
let faucet = await ethers.getContractAt(
|
|
35
|
-
[
|
|
36
|
-
"event WalletTopped(address indexed account, uint256 amount,address whitelistedRoot,address indexed relayerOrWhitelisted)"
|
|
37
|
-
],
|
|
38
|
-
faucetAddr
|
|
39
|
-
);
|
|
33
|
+
let faucet = (await ethers.getContractAt("Faucet", faucetAddr)).connect(archive);
|
|
40
34
|
const endBlock = Number(await archive.getBlockNumber());
|
|
41
|
-
const daysBack =
|
|
35
|
+
const daysBack = 1;
|
|
42
36
|
const dayBlocks = 12 * 60 * 24;
|
|
43
37
|
const startBlock = endBlock - dayBlocks * daysBack;
|
|
44
38
|
const days = range(startBlock, endBlock, dayBlocks);
|
|
@@ -61,7 +55,9 @@ const main = async (isCelo = true) => {
|
|
|
61
55
|
const toppingsByAmount = {};
|
|
62
56
|
const toppingsByRelayer = {};
|
|
63
57
|
const toppingsPerDay = {};
|
|
58
|
+
const toppingsOfWhitelisted = {};
|
|
64
59
|
let totalToppings = 0;
|
|
60
|
+
let totalWhitelistedToppings = 0;
|
|
65
61
|
let totalAmount = 0;
|
|
66
62
|
const dailyUsage = dailyBalance.map((v, i) => (i < dailyBalance.length - 1 ? v[0] - dailyBalance[i + 1][0] : 0));
|
|
67
63
|
const dailyAdminUsage = dailyBalance.map((v, i) => (i < dailyBalance.length - 1 ? v[1] - dailyBalance[i + 1][1] : 0));
|
|
@@ -69,7 +65,7 @@ const main = async (isCelo = true) => {
|
|
|
69
65
|
console.log({ dailyUsage, dailyAdminUsage });
|
|
70
66
|
fs.writeFileSync("celospend.csv", arrayToCsv(dailyBalance));
|
|
71
67
|
console.log(arrayToCsv(dailyBalance));
|
|
72
|
-
|
|
68
|
+
// return;
|
|
73
69
|
console.log({ startBlock, endBlock });
|
|
74
70
|
while (curBlock <= endBlock) {
|
|
75
71
|
const fromBlock = curBlock;
|
|
@@ -85,7 +81,11 @@ const main = async (isCelo = true) => {
|
|
|
85
81
|
toppingsPerDay[day] = get(toppingsPerDay, day, 0) + 1;
|
|
86
82
|
totalToppings += 1;
|
|
87
83
|
totalAmount += Number(e.args.amount);
|
|
88
|
-
toppingsByAddress[e.args.
|
|
84
|
+
toppingsByAddress[e.args.account] = (toppingsByAddress[e.args.account] || 0) + 1;
|
|
85
|
+
if (e.args.whitelistedRoot != ethers.constants.AddressZero) {
|
|
86
|
+
toppingsOfWhitelisted[e.args.whitelistedRoot] = (toppingsOfWhitelisted[e.args.whitelistedRoot] || 0) + 1;
|
|
87
|
+
totalWhitelistedToppings += 1;
|
|
88
|
+
}
|
|
89
89
|
if (e.args.account !== e.args.relayerOrWhitelisted)
|
|
90
90
|
toppingsByRelayer[e.args.relayerOrWhitelisted] = (toppingsByRelayer[e.args.relayerOrWhitelisted] || 0) + 1;
|
|
91
91
|
toppingsByAmount[e.args.amount] = (toppingsByAmount[e.args.amount] || 0) + 1;
|
|
@@ -103,20 +103,24 @@ const main = async (isCelo = true) => {
|
|
|
103
103
|
const topToppers = sortBy(toPairs(toppingsByAddress), "1").reverse();
|
|
104
104
|
const topAmounts = sortBy(toPairs(toppingsByAmount), "1").reverse();
|
|
105
105
|
const topRelayers = sortBy(toPairs(toppingsByRelayer), "1").reverse();
|
|
106
|
-
|
|
106
|
+
const topWhitelisted = sortBy(toPairs(toppingsOfWhitelisted), "1").reverse();
|
|
107
107
|
const totalWallets = topToppers.length;
|
|
108
108
|
|
|
109
109
|
const avgToppingsPerWallet = totalToppings / totalWallets;
|
|
110
110
|
const avgToppingAmount = totalAmount / totalToppings;
|
|
111
111
|
|
|
112
112
|
console.log(topRelayers.slice(0, 50));
|
|
113
|
+
console.log(topToppers.slice(0, 50));
|
|
113
114
|
|
|
115
|
+
const byNumberOfToppings = mapValues(groupBy(topToppers, "1"), v => v.length);
|
|
116
|
+
console.log({ byNumberOfToppings });
|
|
114
117
|
console.log(toppingsPerDay);
|
|
115
|
-
fs.writeFileSync("topToppers.csv", arrayToCsv(topToppers));
|
|
116
|
-
fs.writeFileSync("topAmounts.csv", arrayToCsv(topAmounts));
|
|
117
|
-
fs.writeFileSync("topRelayers.csv", arrayToCsv(topRelayers));
|
|
118
|
+
// fs.writeFileSync("topToppers.csv", arrayToCsv(topToppers));
|
|
119
|
+
// fs.writeFileSync("topAmounts.csv", arrayToCsv(topAmounts));
|
|
120
|
+
// fs.writeFileSync("topRelayers.csv", arrayToCsv(topRelayers));
|
|
118
121
|
|
|
119
122
|
console.log({
|
|
123
|
+
totalWhitelistedToppings,
|
|
120
124
|
totalAmount,
|
|
121
125
|
totalToppings,
|
|
122
126
|
avgToppingsPerWallet,
|