create pool from prices script update to use a cast command

This commit is contained in:
2025-11-17 14:12:34 -04:00
parent d5c40b9667
commit bd430411bd

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env node
/**
* Create Pool from Real-Time Prices Script
* Fetches real-time prices from CoinGecko and creates a new pool on Anvil
* Fetches real-time prices from CoinGecko and creates a new pool on the chain specified (could be mockchain, sepolia or prod)
*/
import { ethers } from 'ethers';
@@ -12,28 +12,27 @@ import IPartyPlannerABI from "../src/contracts/IPartyPlannerABI.ts";
// CONFIGURATION
// ============================================================================
const ANVIL_RPC_URL = 'http://127.0.0.1:8545';
const RPC_URL = "https://eth-sepolia.g.alchemy.com/v2/sJ7rLYKJzdRqXUs9cOiLVvHN8aTI30dn"
// Hardcoded private key for Anvil testing (default Anvil account #4 - payer)
const PRIVATE_KEY = '0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a';
// sepolia dev wallet
const PRIVATE_KEY = '89c8f2542b5ff7f3cf0b73255e0a8d79d89c2be598e7f272a275a380ff56a212';
// Receiver address (Anvil account #7)
const RECEIVER_ADDRESS = '0x14dC79964da2C08b23698B3D3cc7Ca32193d9955';
const RECEIVER_ADDRESS = '0xd3b310bd32d782f89eea49cb79656bcaccde7213';
// Test token addresses (mapping to real coins)
const TEST_TOKENS = {
USDC: {
address: '0xbdEd0D2bf404bdcBa897a74E6657f1f12e5C6fb6', // USXD (mock) = USDC (real)
address: '0xCb2F4B07eFe0F06264AD28590aC7f03D5cdb0729', // USXD (mock) = USDC (real)
coingeckoId: 'usd-coin',
decimals: 6
},
BTC: {
address: '0x93C7a6D00849c44Ef3E92E95DCEFfccd447909Ae', // BUTC (mock) = BTC (real)
address: '0x19Ba3A189dc3DEbC07ADF7757dc8170702E91696', // BUTC (mock) = BTC (real)
coingeckoId: 'bitcoin',
decimals: 8
},
WETH: {
address: '0x71a9d115E322467147391c4a71D85F8e1cA623EF', // WTETH (mock) = WETH (real)
address: '0xd406e1a6b028D17b72f826E45bF36BB8Ad4077dB', // WTETH (mock) = WETH (real)
coingeckoId: 'weth',
decimals: 18
}
@@ -44,7 +43,11 @@ const DEFAULT_POOL_PARAMS = {
name: 'Balanced Portfolio Pool',
symbol: 'BPP',
kappa: ethers.BigNumber.from('100000000000000000'), // 0.1 * 1e18 = 1e17
swapFeePpm: 3000, // 0.3%
swapFeesPpm: [
50, // 0.0050%
2450, // 0.2450%
2950, // 0.2950%
],
flashFeePpm: 5, // 0.0005%
stable: false,
initialLpAmount: ethers.BigNumber.from('1000000000000000000') // 1e18
@@ -58,9 +61,8 @@ const INPUT_USD_AMOUNT = 100;
// LOAD ABIs AND CONFIG
// ============================================================================
// Load chain info and get PartyPlanner address (chain ID 31337 = Anvil)
const chainInfoData = JSON.parse(await readFile(new URL('../src/contracts/liqp-deployments.json', import.meta.url), 'utf-8'));
const PARTY_PLANNER_ADDRESS = chainInfoData['31337'].v1.PartyPlanner;
const PARTY_PLANNER_ADDRESS = chainInfoData['11155111'].v1.PartyPlanner;
const ERC20ABI = [
{ "type": "function", "name": "balanceOf", "stateMutability": "view", "inputs": [{ "name": "account", "type": "address" }], "outputs": [{ "name": "", "type": "uint256" }] },
@@ -205,13 +207,11 @@ async function approveTokens(wallet, tokenAmounts) {
}
/**
* Create a new pool
* Create a new pool using cast send
*/
async function createPool(wallet, tokenAmounts) {
console.log(`\n[~] Creating new pool...`);
const partyPlanner = new ethers.Contract(PARTY_PLANNER_ADDRESS, IPartyPlannerABI, wallet);
// Prepare parameters
const tokenAddresses = [
TEST_TOKENS.USDC.address,
@@ -220,9 +220,9 @@ async function createPool(wallet, tokenAmounts) {
];
const initialDeposits = [
tokenAmounts.USDC,
tokenAmounts.BTC,
tokenAmounts.WETH
tokenAmounts.USDC.toString(),
tokenAmounts.BTC.toString(),
tokenAmounts.WETH.toString()
];
// Set deadline to 1 hour from now
@@ -232,53 +232,45 @@ async function createPool(wallet, tokenAmounts) {
console.log(` Name: ${DEFAULT_POOL_PARAMS.name}`);
console.log(` Symbol: ${DEFAULT_POOL_PARAMS.symbol}`);
console.log(` Tokens: ${tokenAddresses.join(', ')}`);
console.log(` Swap Fees PPM: [${DEFAULT_POOL_PARAMS.swapFeesPpm.join(', ')}]`);
console.log(` Payer: ${wallet.address}`);
console.log(` Receiver: ${RECEIVER_ADDRESS}`);
console.log(` Deadline: ${new Date(deadline * 1000).toISOString()}`);
// Build cast send command
const castCommand = `cast send ${PARTY_PLANNER_ADDRESS} \
"newPool(string,string,address[],int128,uint256[],uint256,bool,address,address,uint256[],uint256,uint256)" \
"${DEFAULT_POOL_PARAMS.name}" \
"${DEFAULT_POOL_PARAMS.symbol}" \
"[${tokenAddresses.join(',')}]" \
${DEFAULT_POOL_PARAMS.kappa.toString()} \
"[${DEFAULT_POOL_PARAMS.swapFeesPpm.join(',')}]" \
${DEFAULT_POOL_PARAMS.flashFeePpm} \
${DEFAULT_POOL_PARAMS.stable} \
${wallet.address} \
${RECEIVER_ADDRESS} \
"[${initialDeposits.join(',')}]" \
${DEFAULT_POOL_PARAMS.initialLpAmount.toString()} \
${deadline} \
--rpc-url ${RPC_URL} \
--private-key ${PRIVATE_KEY}`;
console.log(`\n[~] Cast command:\n${castCommand}\n`);
try {
const tx = await partyPlanner.newPool(
DEFAULT_POOL_PARAMS.name,
DEFAULT_POOL_PARAMS.symbol,
tokenAddresses,
DEFAULT_POOL_PARAMS.kappa,
DEFAULT_POOL_PARAMS.swapFeePpm,
DEFAULT_POOL_PARAMS.flashFeePpm,
DEFAULT_POOL_PARAMS.stable,
wallet.address, // payer (account #4)
RECEIVER_ADDRESS, // receiver (account #7)
initialDeposits,
DEFAULT_POOL_PARAMS.initialLpAmount,
deadline,
);
console.log(`[~] Transaction submitted: ${tx.hash}`);
console.log(`[~] Waiting for confirmation...`);
const receipt = await tx.wait();
// Execute cast command
const { execSync } = await import('child_process');
const output = execSync(castCommand, { encoding: 'utf-8' });
console.log(`[+] Pool created successfully!`);
console.log(` Transaction: ${receipt.transactionHash}`);
console.log(` Block: ${receipt.blockNumber}`);
console.log(` Gas used: ${receipt.gasUsed.toString()}`);
console.log(output);
// Try to extract pool address from events
if (receipt.events && receipt.events.length > 0) {
const partyStartedEvent = receipt.events.find(e => e.event === 'PartyStarted');
if (partyStartedEvent && partyStartedEvent.args) {
console.log(` Pool address: ${partyStartedEvent.args.pool}`);
}
}
return receipt;
return output;
} catch (error) {
console.error(`[!] Failed to create pool:`, error.message);
// Try to extract revert reason if available
if (error.error && error.error.message) {
console.error(` Revert reason: ${error.error.message}`);
if (error.stderr) {
console.error(` Error output: ${error.stderr.toString()}`);
}
throw error;
}
}
@@ -347,9 +339,9 @@ async function main() {
// Step 2: Calculate token amounts
const tokenAmounts = calculateTokenAmounts(prices, usdAmount);
// Step 3: Connect to Anvil
console.log(`\n[~] Connecting to Anvil at ${ANVIL_RPC_URL}...`);
const provider = new ethers.providers.JsonRpcProvider(ANVIL_RPC_URL);
// 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}`);