From bfb925d5fe9cd0b3c1bda7dbcfca80ce729a7623 Mon Sep 17 00:00:00 2001 From: Dzmitry Lahunouski Date: Sat, 27 Jul 2024 18:11:16 +0100 Subject: [PATCH] fuel depositsfor erc20 --- .apprc | 5 +- Makefile | 4 +- src/cli/fuel.ts | 10 --- src/cli/fuelERC.ts | 10 +++ src/cli/fuelNative.ts | 10 +++ src/core/fuel/depositERC.ts | 73 +++++++++++++++++++ .../{deposit.fuel.ts => depositNative.ts} | 17 ++--- src/core/fuel/index.ts | 3 +- src/types/configs.ts | 1 + 9 files changed, 109 insertions(+), 24 deletions(-) delete mode 100644 src/cli/fuel.ts create mode 100644 src/cli/fuelERC.ts create mode 100644 src/cli/fuelNative.ts create mode 100644 src/core/fuel/depositERC.ts rename src/core/fuel/{deposit.fuel.ts => depositNative.ts} (89%) diff --git a/.apprc b/.apprc index fd4681b..aaf1a15 100644 --- a/.apprc +++ b/.apprc @@ -1,6 +1,6 @@ { "cli": { - "cluster_id": "fuelDust2", + "cluster_id": "fuelDust", "funding": { "chain": "eth", "filters": [ @@ -20,7 +20,8 @@ "miller": "0x0000000000000000000000000000000000000000" }, "fuel": { - "minDeposit": 30 + "minDeposit": 30, + "token": "0x8c9532a60E0E7C6BbD2B2c1303F63aCE1c3E9811" }, "scroll": { "kelp": { diff --git a/Makefile b/Makefile index bee4254..3e742cc 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,9 @@ decrypt :; export FILE=$(in) && export OUTPUT=$(out) && npx tsx src/cli/decrypt. funding :; npx tsx src/cli/funding.ts -fuel :; npx tsx src/cli/fuel.ts +fuelNative :; npx tsx src/cli/fuelNative.ts + +fuelERC :; npx tsx src/cli/fuelNative.ts scroll-kelp :; npx tsx src/cli/scroll.kelp.ts diff --git a/src/cli/fuel.ts b/src/cli/fuel.ts deleted file mode 100644 index df01cc9..0000000 --- a/src/cli/fuel.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { initFuelDeposits } from "src/core/fuel"; -import { getAppConf } from "src/libs/configs"; -import { logger } from "src/logger"; - -(async function main() { - logger.info("initiated", { label: "CLI::fuel" }); - const conf = await getAppConf(); - await initFuelDeposits(conf.cli.fuel.minDeposit); - logger.info("finished", { label: "CLI::encrypt" }); -})(); diff --git a/src/cli/fuelERC.ts b/src/cli/fuelERC.ts new file mode 100644 index 0000000..84713a8 --- /dev/null +++ b/src/cli/fuelERC.ts @@ -0,0 +1,10 @@ +import { initERCFuelDeposits } from "src/core/fuel"; +import { getAppConf } from "src/libs/configs"; +import { logger } from "src/logger"; + +(async function main() { + logger.info("initiated", { label: "CLI::fuelERC" }); + const conf = await getAppConf(); + await initERCFuelDeposits(conf.cli.fuel.token); + logger.info("finished", { label: "CLI::fuelERC" }); +})(); diff --git a/src/cli/fuelNative.ts b/src/cli/fuelNative.ts new file mode 100644 index 0000000..8ef7d6a --- /dev/null +++ b/src/cli/fuelNative.ts @@ -0,0 +1,10 @@ +import { initNativeFuelDeposits } from "src/core/fuel"; +import { getAppConf } from "src/libs/configs"; +import { logger } from "src/logger"; + +(async function main() { + logger.info("initiated", { label: "CLI::fuelNative" }); + const conf = await getAppConf(); + await initNativeFuelDeposits(conf.cli.fuel.minDeposit); + logger.info("finished", { label: "CLI::fuelNative" }); +})(); diff --git a/src/core/fuel/depositERC.ts b/src/core/fuel/depositERC.ts new file mode 100644 index 0000000..6d83430 --- /dev/null +++ b/src/core/fuel/depositERC.ts @@ -0,0 +1,73 @@ +import { Hex } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import * as chains from "viem/chains"; +import { FUEL_POINTS_CONTRACT_ABI, FUEL_POINTS_CONTRACT } from "src/constants/fuel"; +import { getClient, getPublicClient } from "src/libs/clients"; +import Clock from "src/libs/clock"; +import { getEVMWallets } from "src/libs/configs"; +import { getBalance, approve } from "src/libs/erc20"; +import { getRandomArbitrary, loopUntil } from "src/libs/shared"; +import { logger } from "src/logger"; +import { EVMWallet } from "src/types/configs"; + +const chain = chains.mainnet; +const localClock = new Clock(); + +const approveAndDepositERC = async (wallet: EVMWallet, token: Hex, amount: bigint) => { + await approve({ + wallet, + tokenAddress: token, + spenderAddress: FUEL_POINTS_CONTRACT, + amount, + chain, + }); + const walletClient = await getClient(chain); + const account = privateKeyToAccount(wallet.pkᵻ); + const { request } = await walletClient.simulateContract({ + address: FUEL_POINTS_CONTRACT, + abi: FUEL_POINTS_CONTRACT_ABI, + functionName: "deposit", + args: [token, amount, 0x0], + value: amount, + account, + }); + const txHash = await walletClient.writeContract(request); + const receipt = await walletClient.waitForTransactionReceipt({ + hash: txHash, + }); + logger.info(`tx hash: ${receipt.transactionHash}`, { label: "fuel::depositERC" }); + return receipt; +}; + +const sleepForProperGasPrice = async () => + await loopUntil( + async () => { + const gasPrice = await (await getPublicClient(chains.mainnet)).getGasPrice(); + return gasPrice < 8000000000n; // 8 gwei + }, + 5 * 60 * 1000, + ); + +export async function initERCFuelDeposits(token: Hex) { + const EVMWallets = await getEVMWallets(); + + for (const wallet of EVMWallets) { + if (wallet === EVMWallets[0]) { + continue; + } + const [, balance] = await getBalance({ + walletAddress: wallet.address, + tokenAddress: token, + chain: chain, + }); + + if (balance === 0n) { + continue; + } + localClock.markTime(); + await sleepForProperGasPrice(); + await approveAndDepositERC(wallet, token, balance); + + await localClock.sleepMax(getRandomArbitrary(1 * 3_600_000, 2 * 3_600_000)); + } +} diff --git a/src/core/fuel/deposit.fuel.ts b/src/core/fuel/depositNative.ts similarity index 89% rename from src/core/fuel/deposit.fuel.ts rename to src/core/fuel/depositNative.ts index e39b9d8..691b3ef 100644 --- a/src/core/fuel/deposit.fuel.ts +++ b/src/core/fuel/depositNative.ts @@ -6,7 +6,7 @@ import { FUEL_POINTS_CONTRACT_ABI, FUEL_POINTS_CONTRACT } from "src/constants/fu import { getPrice } from "src/libs/chainlink"; import { getClient, getPublicClient } from "src/libs/clients"; import Clock from "src/libs/clock"; -import { getProfiles } from "src/libs/configs"; +import { getEVMWallets } from "src/libs/configs"; import { refreshProxy } from "src/libs/proxify"; import { getRandomArbitrary, loopUntil } from "src/libs/shared"; import { logger } from "src/logger"; @@ -15,7 +15,7 @@ import { EVMWallet } from "src/types/configs"; const chain = chains.mainnet; const localClock = new Clock(); -const deposit = async (wallet: EVMWallet, toDeposit: bigint) => { +const depositNative = async (wallet: EVMWallet, toDeposit: bigint) => { const axiosInstance = await refreshProxy(); const walletClient = await getClient(chain, axiosInstance); const account = privateKeyToAccount(wallet.pkᵻ); @@ -31,7 +31,7 @@ const deposit = async (wallet: EVMWallet, toDeposit: bigint) => { const receipt = await walletClient.waitForTransactionReceipt({ hash: txHash, }); - logger.info(`tx hash: ${receipt.transactionHash}`, { label: "fuel::deposit" }); + logger.info(`tx hash: ${receipt.transactionHash}`, { label: "fuel::depositNative" }); return receipt; }; @@ -103,20 +103,17 @@ const getAccountToDeposit = async (decodedEVMAccounts: EVMWallet[], minDeposit: const eligibleAccounts = await Promise.all( decodedEVMAccounts.map(prepare({ expenses, ethPrice, minDeposit: parseEther(String(minDeposit)) })), ).then((accounts) => accounts.filter(({ isEligible }) => isEligible)); - logger.info(`accounts to deposit ${eligibleAccounts.length}`, { label: "fuel::deposit" }); + logger.info(`accounts to deposit ${eligibleAccounts.length}`, { label: "fuel::depositNative" }); return eligibleAccounts[0]; }; -export async function initFuelDeposits(minDeposit: number) { - const profiles = await getProfiles(); - const decodedEVMAccounts = Object.values(profiles).map(({ wallets }) => ({ - ...(wallets.evm as EVMWallet), - })); +export async function initNativeFuelDeposits(minDeposit: number) { + const decodedEVMAccounts = await getEVMWallets(); let accountToDeposit = await getAccountToDeposit(decodedEVMAccounts, minDeposit); while (accountToDeposit !== undefined) { - await deposit(accountToDeposit.wallet, accountToDeposit.toDeposit); + await depositNative(accountToDeposit.wallet, accountToDeposit.toDeposit); localClock.markTime(); accountToDeposit = await getAccountToDeposit(decodedEVMAccounts, minDeposit); await localClock.sleepMax(getRandomArbitrary(1 * 3600000, 2 * 3600000)); diff --git a/src/core/fuel/index.ts b/src/core/fuel/index.ts index 48a5935..b20f014 100644 --- a/src/core/fuel/index.ts +++ b/src/core/fuel/index.ts @@ -1 +1,2 @@ -export { initFuelDeposits } from "./deposit.fuel"; +export { initNativeFuelDeposits } from "./depositNative"; +export { initERCFuelDeposits } from "./depositERC"; diff --git a/src/types/configs.ts b/src/types/configs.ts index 2d788ed..d302e65 100644 --- a/src/types/configs.ts +++ b/src/types/configs.ts @@ -67,6 +67,7 @@ export type AppConfig = { }; readonly fuel: { readonly minDeposit: number; + readonly token: Hex; }; readonly scroll: { readonly kelp: {