adding secret variables and tresure code
This commit is contained in:
@@ -6,55 +6,103 @@
|
||||
|
||||
import { ethers } from 'ethers';
|
||||
import { readFile } from 'fs/promises';
|
||||
import { config } from 'dotenv';
|
||||
import IPartyPlannerABI from "../src/contracts/IPartyPlannerABI.ts";
|
||||
|
||||
// Load environment variables from .env-secret
|
||||
config({ path: new URL('../.env-secret', import.meta.url).pathname });
|
||||
|
||||
// ============================================================================
|
||||
// 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
|
||||
const PRIVATE_KEY = '89c8f2542b5ff7f3cf0b73255e0a8d79d89c2be598e7f272a275a380ff56a212';
|
||||
if (!RPC_URL || !PRIVATE_KEY || !RECEIVER_ADDRESS) {
|
||||
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';
|
||||
|
||||
// Test token addresses (mapping to real coins)
|
||||
// Curated token list with real addresses (Ethereum Mainnet)
|
||||
const TEST_TOKENS = {
|
||||
USDC: {
|
||||
address: '0xCb2F4B07eFe0F06264AD28590aC7f03D5cdb0729', // USXD (mock) = USDC (real)
|
||||
coingeckoId: 'usd-coin',
|
||||
decimals: 6
|
||||
USDT: {
|
||||
address: '0xdAC17F958D2ee523a2206206994597C13D831ec7', // Mainnet USDT
|
||||
coingeckoId: 'tether',
|
||||
decimals: 6,
|
||||
feePpm: 400 // 0.00004 = 0.004% = 40 ppm
|
||||
},
|
||||
BTC: {
|
||||
address: '0x19Ba3A189dc3DEbC07ADF7757dc8170702E91696', // BUTC (mock) = BTC (real)
|
||||
coingeckoId: 'bitcoin',
|
||||
decimals: 8
|
||||
USDC: {
|
||||
address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // Mainnet USDC
|
||||
coingeckoId: 'usd-coin',
|
||||
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: {
|
||||
address: '0xd406e1a6b028D17b72f826E45bF36BB8Ad4077dB', // WTETH (mock) = WETH (real)
|
||||
address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // Mainnet 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
|
||||
const DEFAULT_POOL_PARAMS = {
|
||||
name: 'Balanced Portfolio Pool',
|
||||
symbol: 'BPP',
|
||||
kappa: ethers.BigNumber.from('100000000000000000'), // 0.1 * 1e18 = 1e17
|
||||
swapFeesPpm: [
|
||||
50, // 0.0050%
|
||||
2450, // 0.2450%
|
||||
2950, // 0.2950%
|
||||
],
|
||||
name: 'Staging LP Pool',
|
||||
symbol: 'SLP',
|
||||
kappa: ethers.BigNumber.from('10000000000000000'), // 0.01 * 1e18
|
||||
swapFeesPpm: Object.values(TEST_TOKENS).map(t => t.feePpm),
|
||||
flashFeePpm: 5, // 0.0005%
|
||||
stable: false,
|
||||
initialLpAmount: ethers.BigNumber.from('1000000000000000000') // 1e18
|
||||
initialLpAmount: ethers.utils.parseUnits('100', 18) // 100 USD in 18 decimals
|
||||
};
|
||||
|
||||
// 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 PARTY_PLANNER_ADDRESS = chainInfoData['11155111'].v1.PartyPlanner;
|
||||
const PARTY_PLANNER_ADDRESS = chainInfoData['1'].v1.PartyPlanner;
|
||||
|
||||
const ERC20ABI = [
|
||||
{ "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 prices = {
|
||||
USDC: data['usd-coin']?.usd || 1,
|
||||
BTC: data['bitcoin']?.usd || 0,
|
||||
WETH: data['weth']?.usd || 0
|
||||
};
|
||||
const prices = {};
|
||||
|
||||
if (prices.BTC === 0 || prices.WETH === 0) {
|
||||
throw new Error('Failed to fetch valid prices from CoinGecko');
|
||||
for (const [symbol, tokenInfo] of Object.entries(TEST_TOKENS)) {
|
||||
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(` USDC: $${prices.USDC}`);
|
||||
console.log(` BTC: $${prices.BTC.toLocaleString()}`);
|
||||
console.log(` WETH: $${prices.WETH.toLocaleString()}`);
|
||||
for (const [symbol, price] of Object.entries(prices)) {
|
||||
console.log(` ${symbol.padEnd(6)}: $${price.toLocaleString()}`);
|
||||
}
|
||||
|
||||
return prices;
|
||||
} catch (error) {
|
||||
@@ -118,28 +165,25 @@ async function fetchCoinGeckoPrices() {
|
||||
* Calculate token amounts based on equal USD distribution
|
||||
*/
|
||||
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 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);
|
||||
const tokenAmounts = {};
|
||||
|
||||
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 {
|
||||
USDC: usdcAmountBN,
|
||||
BTC: btcAmountBN,
|
||||
WETH: wethAmountBN
|
||||
};
|
||||
for (const [symbol, tokenInfo] of Object.entries(TEST_TOKENS)) {
|
||||
// Calculate raw amount
|
||||
const rawAmount = usdPerToken / prices[symbol];
|
||||
|
||||
// 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)...`);
|
||||
|
||||
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);
|
||||
await tx.wait();
|
||||
console.log(` [+] ${symbol} approved (tx: ${tx.hash})`);
|
||||
@@ -213,17 +265,8 @@ async function createPool(wallet, tokenAmounts) {
|
||||
console.log(`\n[~] Creating new pool...`);
|
||||
|
||||
// Prepare parameters
|
||||
const tokenAddresses = [
|
||||
TEST_TOKENS.USDC.address,
|
||||
TEST_TOKENS.BTC.address,
|
||||
TEST_TOKENS.WETH.address
|
||||
];
|
||||
|
||||
const initialDeposits = [
|
||||
tokenAmounts.USDC.toString(),
|
||||
tokenAmounts.BTC.toString(),
|
||||
tokenAmounts.WETH.toString()
|
||||
];
|
||||
const tokenAddresses = Object.values(TEST_TOKENS).map(t => t.address);
|
||||
const initialDeposits = Object.keys(TEST_TOKENS).map(symbol => tokenAmounts[symbol].toString());
|
||||
|
||||
// Set deadline to 1 hour from now
|
||||
const deadline = Math.floor(Date.now() / 1000) + 3600;
|
||||
@@ -252,8 +295,10 @@ async function createPool(wallet, tokenAmounts) {
|
||||
"[${initialDeposits.join(',')}]" \
|
||||
${DEFAULT_POOL_PARAMS.initialLpAmount.toString()} \
|
||||
${deadline} \
|
||||
--rpc-url ${RPC_URL} \
|
||||
--private-key ${PRIVATE_KEY}`;
|
||||
--rpc-url http://localhost:8545 \
|
||||
--from 0x12db90820dafed100e40e21128e40dcd4ff6b331 \
|
||||
--trezor --mnemonic-index 0`;
|
||||
// --private-key ${PRIVATE_KEY};
|
||||
|
||||
console.log(`\n[~] Cast command:\n${castCommand}\n`);
|
||||
|
||||
@@ -338,13 +383,13 @@ async function main() {
|
||||
|
||||
// Step 2: Calculate token amounts
|
||||
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}...`);
|
||||
const provider = new ethers.providers.JsonRpcProvider(RPC_URL);
|
||||
const wallet = new ethers.Wallet(PRIVATE_KEY, provider);
|
||||
console.log(`[+] Connected. Using wallet: ${wallet.address}`);
|
||||
|
||||
//
|
||||
// Step 4: Check balances
|
||||
await checkBalances(provider, wallet, tokenAmounts);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user