adding secret variables and tresure code
This commit is contained in:
@@ -6,55 +6,103 @@
|
|||||||
|
|
||||||
import { ethers } from 'ethers';
|
import { ethers } from 'ethers';
|
||||||
import { readFile } from 'fs/promises';
|
import { readFile } from 'fs/promises';
|
||||||
|
import { config } from 'dotenv';
|
||||||
import IPartyPlannerABI from "../src/contracts/IPartyPlannerABI.ts";
|
import IPartyPlannerABI from "../src/contracts/IPartyPlannerABI.ts";
|
||||||
|
|
||||||
|
// Load environment variables from .env-secret
|
||||||
|
config({ path: new URL('../.env-secret', import.meta.url).pathname });
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// CONFIGURATION
|
// CONFIGURATION
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
const RPC_URL = "https://eth-sepolia.g.alchemy.com/v2/sJ7rLYKJzdRqXUs9cOiLVvHN8aTI30dn"
|
const RPC_URL = process.env.MAINNET_RPC_URL;
|
||||||
|
const PRIVATE_KEY = process.env.PRIVATE_KEY;
|
||||||
|
const RECEIVER_ADDRESS = process.env.RECEIVER_ADDRESS;
|
||||||
|
|
||||||
// sepolia dev wallet
|
if (!RPC_URL || !PRIVATE_KEY || !RECEIVER_ADDRESS) {
|
||||||
const PRIVATE_KEY = '89c8f2542b5ff7f3cf0b73255e0a8d79d89c2be598e7f272a275a380ff56a212';
|
console.error('[!] Missing required environment variables in .env-secret file');
|
||||||
|
console.error(' Required: MAINNET_RPC_URL, PRIVATE_KEY, RECEIVER_ADDRESS');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
const RECEIVER_ADDRESS = '0xd3b310bd32d782f89eea49cb79656bcaccde7213';
|
// Curated token list with real addresses (Ethereum Mainnet)
|
||||||
|
|
||||||
// Test token addresses (mapping to real coins)
|
|
||||||
const TEST_TOKENS = {
|
const TEST_TOKENS = {
|
||||||
USDC: {
|
USDT: {
|
||||||
address: '0xCb2F4B07eFe0F06264AD28590aC7f03D5cdb0729', // USXD (mock) = USDC (real)
|
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // Mainnet USDT
|
||||||
coingeckoId: 'usd-coin',
|
coingeckoId: 'tether',
|
||||||
decimals: 6
|
decimals: 6,
|
||||||
|
feePpm: 400 // 0.00004 = 0.004% = 40 ppm
|
||||||
},
|
},
|
||||||
BTC: {
|
USDC: {
|
||||||
address: '0x19Ba3A189dc3DEbC07ADF7757dc8170702E91696', // BUTC (mock) = BTC (real)
|
address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // Mainnet USDC
|
||||||
coingeckoId: 'bitcoin',
|
coingeckoId: 'usd-coin',
|
||||||
decimals: 8
|
decimals: 6,
|
||||||
|
feePpm: 400 // 0.00004 = 0.004% = 40 ppm
|
||||||
|
},
|
||||||
|
WBTC: {
|
||||||
|
address: '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', // Mainnet WBTC
|
||||||
|
coingeckoId: 'wrapped-bitcoin',
|
||||||
|
decimals: 8,
|
||||||
|
feePpm: 3000 // 0.00030 = 0.03% = 300 ppm
|
||||||
},
|
},
|
||||||
WETH: {
|
WETH: {
|
||||||
address: '0xd406e1a6b028D17b72f826E45bF36BB8Ad4077dB', // WTETH (mock) = WETH (real)
|
address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // Mainnet WETH
|
||||||
coingeckoId: 'weth',
|
coingeckoId: 'weth',
|
||||||
decimals: 18
|
decimals: 18,
|
||||||
|
feePpm: 3500 // 0.00035 = 0.035% = 350 ppm
|
||||||
|
},
|
||||||
|
BNB: {
|
||||||
|
address: '0xB8c77482e45F1F44dE1745F52C74426C631bDD52', // Mainnet BNB (Binance-Peg)
|
||||||
|
coingeckoId: 'binancecoin',
|
||||||
|
decimals: 18,
|
||||||
|
feePpm: 4500 // 0.00045 = 0.045% = 450 ppm
|
||||||
|
},
|
||||||
|
WSOL: {
|
||||||
|
address: '0xD31a59c85aE9D8edEFeC411D448f90841571b89c', // Mainnet Wormhole Wrapped SOL
|
||||||
|
coingeckoId: 'solana',
|
||||||
|
decimals: 9,
|
||||||
|
feePpm: 9500 // 0.00095 = 0.095% = 950 ppm
|
||||||
|
},
|
||||||
|
TRX: {
|
||||||
|
address: '0x50327c6c5a14DCaDE707ABad2E27eB517df87AB5', // Mainnet TRX (Wrapped)
|
||||||
|
coingeckoId: 'tron',
|
||||||
|
decimals: 6,
|
||||||
|
feePpm: 9500 // 0.00095 = 0.095% = 950 ppm
|
||||||
|
},
|
||||||
|
AAVE: {
|
||||||
|
address: '0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9', // Mainnet AAVE
|
||||||
|
coingeckoId: 'aave',
|
||||||
|
decimals: 18,
|
||||||
|
feePpm: 14500 // 0.00145 = 0.145% = 1450 ppm
|
||||||
|
},
|
||||||
|
PEPE: {
|
||||||
|
address: '0x6982508145454Ce325dDbE47a25d4ec3d2311933', // Mainnet PEPE
|
||||||
|
coingeckoId: 'pepe',
|
||||||
|
decimals: 18,
|
||||||
|
feePpm: 21500 // 0.00215 = 0.215% = 2150 ppm
|
||||||
|
},
|
||||||
|
SHIB: {
|
||||||
|
address: '0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE', // Mainnet SHIB
|
||||||
|
coingeckoId: 'shiba-inu',
|
||||||
|
decimals: 18,
|
||||||
|
feePpm: 21500 // 0.00215 = 0.215% = 2150 ppm
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Default pool parameters
|
// Default pool parameters
|
||||||
const DEFAULT_POOL_PARAMS = {
|
const DEFAULT_POOL_PARAMS = {
|
||||||
name: 'Balanced Portfolio Pool',
|
name: 'Staging LP Pool',
|
||||||
symbol: 'BPP',
|
symbol: 'SLP',
|
||||||
kappa: ethers.BigNumber.from('100000000000000000'), // 0.1 * 1e18 = 1e17
|
kappa: ethers.BigNumber.from('10000000000000000'), // 0.01 * 1e18
|
||||||
swapFeesPpm: [
|
swapFeesPpm: Object.values(TEST_TOKENS).map(t => t.feePpm),
|
||||||
50, // 0.0050%
|
|
||||||
2450, // 0.2450%
|
|
||||||
2950, // 0.2950%
|
|
||||||
],
|
|
||||||
flashFeePpm: 5, // 0.0005%
|
flashFeePpm: 5, // 0.0005%
|
||||||
stable: false,
|
stable: false,
|
||||||
initialLpAmount: ethers.BigNumber.from('1000000000000000000') // 1e18
|
initialLpAmount: ethers.utils.parseUnits('100', 18) // 100 USD in 18 decimals
|
||||||
};
|
};
|
||||||
|
|
||||||
// Input amount in USD
|
// Input amount in USD
|
||||||
const INPUT_USD_AMOUNT = 100;
|
const INPUT_USD_AMOUNT = 1;
|
||||||
|
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -62,7 +110,7 @@ const INPUT_USD_AMOUNT = 100;
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
const chainInfoData = JSON.parse(await readFile(new URL('../src/contracts/liqp-deployments.json', import.meta.url), 'utf-8'));
|
const chainInfoData = JSON.parse(await readFile(new URL('../src/contracts/liqp-deployments.json', import.meta.url), 'utf-8'));
|
||||||
const PARTY_PLANNER_ADDRESS = chainInfoData['11155111'].v1.PartyPlanner;
|
const PARTY_PLANNER_ADDRESS = chainInfoData['1'].v1.PartyPlanner;
|
||||||
|
|
||||||
const ERC20ABI = [
|
const ERC20ABI = [
|
||||||
{ "type": "function", "name": "balanceOf", "stateMutability": "view", "inputs": [{ "name": "account", "type": "address" }], "outputs": [{ "name": "", "type": "uint256" }] },
|
{ "type": "function", "name": "balanceOf", "stateMutability": "view", "inputs": [{ "name": "account", "type": "address" }], "outputs": [{ "name": "", "type": "uint256" }] },
|
||||||
@@ -92,20 +140,19 @@ async function fetchCoinGeckoPrices() {
|
|||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
|
|
||||||
const prices = {
|
const prices = {};
|
||||||
USDC: data['usd-coin']?.usd || 1,
|
|
||||||
BTC: data['bitcoin']?.usd || 0,
|
|
||||||
WETH: data['weth']?.usd || 0
|
|
||||||
};
|
|
||||||
|
|
||||||
if (prices.BTC === 0 || prices.WETH === 0) {
|
for (const [symbol, tokenInfo] of Object.entries(TEST_TOKENS)) {
|
||||||
throw new Error('Failed to fetch valid prices from CoinGecko');
|
prices[symbol] = data[tokenInfo.coingeckoId]?.usd || 0;
|
||||||
|
if (prices[symbol] === 0) {
|
||||||
|
throw new Error(`Failed to fetch valid price for ${symbol}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[+] Prices fetched successfully:`);
|
console.log(`[+] Prices fetched successfully:`);
|
||||||
console.log(` USDC: $${prices.USDC}`);
|
for (const [symbol, price] of Object.entries(prices)) {
|
||||||
console.log(` BTC: $${prices.BTC.toLocaleString()}`);
|
console.log(` ${symbol.padEnd(6)}: $${price.toLocaleString()}`);
|
||||||
console.log(` WETH: $${prices.WETH.toLocaleString()}`);
|
}
|
||||||
|
|
||||||
return prices;
|
return prices;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -118,28 +165,25 @@ async function fetchCoinGeckoPrices() {
|
|||||||
* Calculate token amounts based on equal USD distribution
|
* Calculate token amounts based on equal USD distribution
|
||||||
*/
|
*/
|
||||||
function calculateTokenAmounts(prices, usdAmount) {
|
function calculateTokenAmounts(prices, usdAmount) {
|
||||||
const usdPerToken = usdAmount / 3; // Equally distribute among 3 tokens
|
const tokenCount = Object.keys(TEST_TOKENS).length;
|
||||||
|
const usdPerToken = usdAmount / tokenCount; // Equally distribute among all tokens
|
||||||
|
|
||||||
// Calculate raw amounts
|
const tokenAmounts = {};
|
||||||
const usdcAmount = usdPerToken / prices.USDC;
|
|
||||||
const btcAmount = usdPerToken / prices.BTC;
|
|
||||||
const wethAmount = usdPerToken / prices.WETH;
|
|
||||||
|
|
||||||
// Convert to BigNumber with proper decimals
|
|
||||||
const usdcAmountBN = ethers.utils.parseUnits(usdcAmount.toFixed(TEST_TOKENS.USDC.decimals), TEST_TOKENS.USDC.decimals);
|
|
||||||
const btcAmountBN = ethers.utils.parseUnits(btcAmount.toFixed(TEST_TOKENS.BTC.decimals), TEST_TOKENS.BTC.decimals);
|
|
||||||
const wethAmountBN = ethers.utils.parseUnits(wethAmount.toFixed(TEST_TOKENS.WETH.decimals), TEST_TOKENS.WETH.decimals);
|
|
||||||
|
|
||||||
console.log(`\n[~] Calculated token amounts for $${usdAmount} ($${usdPerToken.toFixed(2)} per token):`);
|
console.log(`\n[~] Calculated token amounts for $${usdAmount} ($${usdPerToken.toFixed(2)} per token):`);
|
||||||
console.log(` USDC: ${usdcAmount.toFixed(6)} USDC (${usdcAmountBN.toString()} wei)`);
|
|
||||||
console.log(` BTC: ${btcAmount.toFixed(8)} BTC (${btcAmountBN.toString()} wei)`);
|
|
||||||
console.log(` WETH: ${wethAmount.toFixed(8)} WETH (${wethAmountBN.toString()} wei)`);
|
|
||||||
|
|
||||||
return {
|
for (const [symbol, tokenInfo] of Object.entries(TEST_TOKENS)) {
|
||||||
USDC: usdcAmountBN,
|
// Calculate raw amount
|
||||||
BTC: btcAmountBN,
|
const rawAmount = usdPerToken / prices[symbol];
|
||||||
WETH: wethAmountBN
|
|
||||||
};
|
// Convert to BigNumber with proper decimals
|
||||||
|
const amountBN = ethers.utils.parseUnits(rawAmount.toFixed(tokenInfo.decimals), tokenInfo.decimals);
|
||||||
|
|
||||||
|
tokenAmounts[symbol] = amountBN;
|
||||||
|
console.log(` ${symbol.padEnd(6)}: ${rawAmount.toFixed(tokenInfo.decimals)} (${amountBN.toString()} wei)`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokenAmounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -194,6 +238,14 @@ async function approveTokens(wallet, tokenAmounts) {
|
|||||||
console.log(` [~] Approving ${symbol} (1% buffer)...`);
|
console.log(` [~] Approving ${symbol} (1% buffer)...`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// USDT and some tokens require setting allowance to 0 before setting a new value
|
||||||
|
// Skip for BNB as it has a broken approve function
|
||||||
|
if (symbol !== 'BNB') {
|
||||||
|
const resetTx = await tokenContract.approve(PARTY_PLANNER_ADDRESS, 0);
|
||||||
|
await resetTx.wait();
|
||||||
|
console.log(` [+] ${symbol} allowance reset to 0`);
|
||||||
|
}
|
||||||
|
|
||||||
const tx = await tokenContract.approve(PARTY_PLANNER_ADDRESS, approvalAmount);
|
const tx = await tokenContract.approve(PARTY_PLANNER_ADDRESS, approvalAmount);
|
||||||
await tx.wait();
|
await tx.wait();
|
||||||
console.log(` [+] ${symbol} approved (tx: ${tx.hash})`);
|
console.log(` [+] ${symbol} approved (tx: ${tx.hash})`);
|
||||||
@@ -213,17 +265,8 @@ async function createPool(wallet, tokenAmounts) {
|
|||||||
console.log(`\n[~] Creating new pool...`);
|
console.log(`\n[~] Creating new pool...`);
|
||||||
|
|
||||||
// Prepare parameters
|
// Prepare parameters
|
||||||
const tokenAddresses = [
|
const tokenAddresses = Object.values(TEST_TOKENS).map(t => t.address);
|
||||||
TEST_TOKENS.USDC.address,
|
const initialDeposits = Object.keys(TEST_TOKENS).map(symbol => tokenAmounts[symbol].toString());
|
||||||
TEST_TOKENS.BTC.address,
|
|
||||||
TEST_TOKENS.WETH.address
|
|
||||||
];
|
|
||||||
|
|
||||||
const initialDeposits = [
|
|
||||||
tokenAmounts.USDC.toString(),
|
|
||||||
tokenAmounts.BTC.toString(),
|
|
||||||
tokenAmounts.WETH.toString()
|
|
||||||
];
|
|
||||||
|
|
||||||
// Set deadline to 1 hour from now
|
// Set deadline to 1 hour from now
|
||||||
const deadline = Math.floor(Date.now() / 1000) + 3600;
|
const deadline = Math.floor(Date.now() / 1000) + 3600;
|
||||||
@@ -252,8 +295,10 @@ async function createPool(wallet, tokenAmounts) {
|
|||||||
"[${initialDeposits.join(',')}]" \
|
"[${initialDeposits.join(',')}]" \
|
||||||
${DEFAULT_POOL_PARAMS.initialLpAmount.toString()} \
|
${DEFAULT_POOL_PARAMS.initialLpAmount.toString()} \
|
||||||
${deadline} \
|
${deadline} \
|
||||||
--rpc-url ${RPC_URL} \
|
--rpc-url http://localhost:8545 \
|
||||||
--private-key ${PRIVATE_KEY}`;
|
--from 0x12db90820dafed100e40e21128e40dcd4ff6b331 \
|
||||||
|
--trezor --mnemonic-index 0`;
|
||||||
|
// --private-key ${PRIVATE_KEY};
|
||||||
|
|
||||||
console.log(`\n[~] Cast command:\n${castCommand}\n`);
|
console.log(`\n[~] Cast command:\n${castCommand}\n`);
|
||||||
|
|
||||||
@@ -338,13 +383,13 @@ async function main() {
|
|||||||
|
|
||||||
// Step 2: Calculate token amounts
|
// Step 2: Calculate token amounts
|
||||||
const tokenAmounts = calculateTokenAmounts(prices, usdAmount);
|
const tokenAmounts = calculateTokenAmounts(prices, usdAmount);
|
||||||
|
//
|
||||||
// Step 3: Connect to wallet
|
// // Step 3: Connect to wallet
|
||||||
console.log(`\n[~] Connecting to test wallet at ${RPC_URL}...`);
|
console.log(`\n[~] Connecting to test wallet at ${RPC_URL}...`);
|
||||||
const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
|
const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
|
||||||
const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
|
const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
|
||||||
console.log(`[+] Connected. Using wallet: ${wallet.address}`);
|
console.log(`[+] Connected. Using wallet: ${wallet.address}`);
|
||||||
|
//
|
||||||
// Step 4: Check balances
|
// Step 4: Check balances
|
||||||
await checkBalances(provider, wallet, tokenAmounts);
|
await checkBalances(provider, wallet, tokenAmounts);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user