Ponzu Launchpad

TotalClaw 作者 yuzukyouma v1.0.1

部署 Ponzu 代币启动板并与之交互 - 以太坊上的预售、DEX 交换和 LP 挖矿

源码 ↗

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install totalclaw:yuzukyouma~ponzu-ethereum
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Ayuzukyouma~ponzu-ethereum/file -o ponzu-ethereum.md
Git 仓库获取源码
git clone https://github.com/openclaw/skills/commit/b7be8150fe6c1073231936f0c37e5c7c9cb238dd
## 概述(中文)

部署 Ponzu 代币启动板并与之交互 - 以太坊上的预售、DEX 交换和 LP 挖矿

## 原文

```

⠀⠀⢻⣽⣿⣿⣿⣿⢿⣿⣿⣿⣶⡀⠀⢰⣻⣿⣿⣿⣿⡿⣿⣿⣿⣦⠀⣿⣿⣿⣿⡇⠀⠀⢻⣿⣿⣻⠿⠈⠿⠿⠿⠿⢿⣿⣿⣿⡏⢿⣭⣿⣿⠃⠀⠀⢿⣿⣿⣾⡟
⠀⠀ ⣿⣿⣿⣿⠀⠀⠈⣿⣿⣿⣿⢸⣿⣿⣿⣿⠿⠿⢶⣿⣿⣿⣿⠀⡉⣿⣿⢿⣻⡀⠀⠈⣿⣿⣹⡇⠀⠀⠀⠀⣸⣿⣿⢹⢳⠀⣿⣿⣿⣿⠀⠀⠀⣿⣿⡿⣿⡇
⠀ ⢀⣿⣿⣿⣏⠀⠀⠀⣻⣿⡿⠿⠸⢸⣿⣿⡗⠀⠀⠀⣿⡟⣿⡿⠀⣇⣿⣿⣾⣿⡟⠀⡄⣿⣿⣿⡏⠀⠀⠀⠀⣷⢿⣿⣿⡏⠀⡿⣿⣿⣿⠀⠀⠀⣟⣿⣿⣏⡇
⠀⠀⢸⣾⣿⣿⡏⠀⠀⠀⣾⣿⡿⣿⠈⣻⣿⣿⠇⠀⠀⠀⣸⣷⣿⣷⠀⣿⣿⣿⣿⣿⣿⣷⡇⣿⣿⣇⡇⠀⠀⠀⢸⣿⣿⣿⢫⠀⠀⣹⣿⣿⣿⠀⠀⠀⣿⣿⡿⣿⡇
⠀⠀⢸⣿⣿⣿⡇⠀⠀⠀⣿⣿⣿⣿⠀⣿⣿⣿⡇⠀⠀⠀⣿⣿⣿⡇⠀⣿⣿⣽⣿⣻⣿⣿⣿⣷⣿⣿⡇⠀⠀⠀⣿⣿⣿⣿⡏⠀⠀⣻⣿⣽⣿⠀⠀⠀⣿⣿⣿⣟⡇
⠀⠀⢸⣗⣿⣿⡇⠀⠀⠀⣿⣿⣿⣿⢨⣿⣿⣿⡇⠀⠀⠀⣿⣽⣿⡿⠀⣾⡇⣿⣻⢿⣯⣿⣿⣿⣿⣿⠃⠀⠀⢀⣿⣿⣿⣷⠀⠀⠀⣾⣿⣿⣿⠀⠀⠀⣿⣿⣏⣿⡇
⠀⠀⢸⣷⡿⣷⣵⣶⣾⣿⣿⣿⡿⠋⢸⣿⣿⣿⡇⠀⠀⢸⢿⣿⣶⣇⠀⣿⣿⣿⣿⡎⣿⣿⣿⣿⣿⣿⠀⠀⠀⣷⣧⣿⣿⡗⠀⠀⠀⣽⣿⣿⣿⠀⠀⠀⣿⣿⢿⣿⡇
⠀⠀⢸⣿⣿⣿⡏⠉⠉⠀⠀⠀⠀⠀⢠⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⢀⣿⣿⣿⣾⣿⡟⡟⣿⣿⣿⣿⠀⠀⢀⣾⣿⣿⣿⠀⠀⠀⠀⠹⣿⡏⣿⠀⠀⠀⡭⣿⢾⣷⡇
⠀⠀⢸⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⡇⠀⠀⢸⣿⣿⣿⣿⢰⣿⣿⣇⣿⠹⣿⣿⢹⣿⣿⠏⠀⠀⣾⣿⣿⣿⡟⠀⠀⠀⠀⢸⣿⣷⣿⠀⠀⠀⣣⣿⣿⣷⡇
⠀⠀⢨⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣧⣀⣀⣠⣿⣿⣧⣯⢸⣿⣿⣿⣼⠀⠹⣿⣿⣿⣺⣿⠀⠀⣿⣿⣿⣿⠀⠀⠀⠀⠀⢸⣿⣻⣿⣄⣀⣀⣿⣿⣾⣿⠃
⠀⠀⢸⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⣿⣿⣟⣿⣿⣿⣿⣾⢸⣿⣿⣿⣿⠀⠀⢹⣿⣿⣿⣿⠀⢰⣿⣿⣿⣿⣶⣶⣦⣶⡄⣿⣿⣿⣭⣿⣭⣟⣿⣿⣿⣻⠀
⠀⠀⠚⠛⠛⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠚⠿⠿⠿⠿⠛⠛⠉⠀⠉⠓⠛⠛⠃⠀⠀⠈⠉⠛⠛⠛⠀⠛⠉⠉⠉⠉⠙⠉⠉⠉⠁⠀⠈⠛⠿⠿⠿⠿⠟⠛⠉⠀⠀

                     https://ponzu.app/SKILL.md
```

# Ponzu Launchpad

Ponzu is a permissionless ERC-20 token launchpad on Ethereum with diamond-hand vesting.
One transaction deploys a complete DeFi stack — presale, launcher, DEX, and LP yield farming — all atomically from a single factory call.

No admin keys. No upgrade proxies. No external APIs. No migration steps.

Every token launched through Ponzu follows the same lifecycle:

1. **Presale** — users buy tokens at a rising price curve; each position is a transferable NFT
2. **Launch** — when sold out, anyone triggers the DEX pool creation (permissionless)
3. **Vesting** — tokens vest linearly over 10 days; early claims route unvested tokens to the reward pool
4. **Farming** — LPs stake to earn trading fees + redistributed unvested tokens

---

## Security & Privacy

All logic runs locally. No data is sent to Ponzu servers.

- Signed transactions are broadcast to your configured Ethereum RPC endpoint (`PONZU_RPC_URL`). Find public RPCs at [chainlist.org/chain/1](https://chainlist.org/chain/1) for mainnet or [chainlist.org/chain/11155111](https://chainlist.org/chain/11155111) for Sepolia
- No telemetry, analytics, or external API calls
- `PONZU_PRIVATE_KEY` is used locally by viem's `privateKeyToAccount()` to sign transactions — it is never transmitted
- **Use a dedicated wallet** with only the funds needed. Never use your main wallet.
- **Test on Sepolia first** (`PONZU_NETWORK=sepolia`) before using mainnet
- **Omit `PONZU_PRIVATE_KEY`** for read-only access (query contract state without signing)
- Smart contracts are immutable (no proxy, no admin keys, no upgrade path)
- All contract addresses are listed in [Contract Addresses](#contract-addresses) below

---

## Quick Start

```bash
npm install @ponzu_app/sdk viem
```

```typescript
import { createWalletClient, createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
import { privateKeyToAccount } from 'viem/accounts'
import { deploy, getAddresses } from '@ponzu_app/sdk'

// Use a dedicated wallet — never your main wallet
const account = privateKeyToAccount(process.env.PONZU_PRIVATE_KEY as `0x${string}`)
const wallet  = createWalletClient({ account, chain: mainnet, transport: http() })
const client  = createPublicClient({ chain: mainnet, transport: http() })
```

<details>
<summary>Using raw viem (no SDK)</summary>

```bash
npm install viem
```

```typescript
import {
  createWalletClient,
  createPublicClient,
  http,
  parseEther,
  encodeAbiParameters,
  decodeAbiParameters,
  keccak256,
  toBytes,
  parseAbi,
  type Address,
} from 'viem'
import { mainnet } from 'viem/chains'
import { privateKeyToAccount } from 'viem/accounts'

// Use a dedicated wallet — never your main wallet
const account = privateKeyToAccount(process.env.PONZU_PRIVATE_KEY as `0x${string}`)
const wallet = createWalletClient({ account, chain: mainnet, transport: http() })
const publicClient = createPublicClient({ chain: mainnet, transport: http() })
```

</details>

---

## Deploy a Token

Deploying a token creates a complete system in one transaction: presale contract, DEX pair, farm, and NFTs. The whole system goes live atomically.

**Cost:** 0.005 ETH creation fee + optional dev buy amount.

### With SDK

```typescript
import { deploy } from '@ponzu_app/sdk'
import { parseEther } from 'viem'

const result = await deploy(
  {
    owner:          account.address,
    tokenName:      'My Token',
    tokenSymbol:    'MYTKN',
    metadata:       'ipfs://Qm...',   // JSON: { image, description, socials }
    imageURI:       'ipfs://Qm...',   // token logo
    targetEthRaise: parseEther('5'),  // optional — defaults to 3 ETH minimum
  },
  wallet,
  client,
  'mainnet',
)

const tokenAddress   = result.addresses.token     // ERC-20
const presaleAddress = result.addresses.presale   // presale contract
const farmAddress    = result.addresses.farm      // LP staking farm
// + project, operator, launcher, distributor, ponzuBottle, liquidityCard

// pairAddress is created at triggerLaunch() — query after launch:
// const { ponzuSwap, weth } = getAddresses('mainnet')
// const pairAddress = await client.readContract({
//   address: ponzuSwap, abi: FACTORY_ABI,
//   functionName: 'getPair', args: [tokenAddress, weth],
// })
```

The SDK handles pricing math, ABI encoding, transaction signing, and event decoding automatically.

### Without SDK

<details>
<summary>Expand for raw viem approach</summary>

```typescript
const PONZU_RECIPE = '0x1155484c5fE614538d83c444f9a6dB662E6a7153'
const WETH         = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'

const RECIPE_ABI = parseAbi([
  'function craftPonzu((address owner, address keyContract, uint256 initialBuyAmount, uint256 vestingDuration, bytes32 pricingStrategyTemplate, bytes pricingStrategyData, bytes feeStrategyData, string tokenName, string tokenSymbol, string metadata, string imageURI) params) payable',
])
```

**Pricing (Linear Strategy):**

```typescript
// Token supply: 1,000,000 total
//   690,000 (69%) sold in presale → must raise ≥ minEthRaise
//   310,000 (31%) seeded into DEX liquidity
//
// From LinearPricingStrategy._calculateCostForTokens:
//   totalCost = (startPrice + endPrice) × 690_000 / 2
//   With startPrice = endPrice / 10:
//   totalCost = endPrice × 11 × 690_000 / 20
//
// Solving for endPrice:
//   endPrice = targetRaise × 20 / (11 × 690_000)
//
// Mainnet minimum (3 ETH):  endPrice ≈ 7,905 Gwei
// Testnet minimum (0.1 ETH): endPrice ≈ 263.5 Gwei

// Mainnet — minimum viable pricing (raises exactly ~3 ETH):
const targetRaise   = parseEther('3')
const endPriceWei   = (targetRaise * 20n) / (11n * 690_000n)  // ≈ 7,905 Gwei
const startPriceWei = endPriceWei / 10n

const pricingStrategyTemplate = keccak256(toBytes('LinearPricingStrategy'))
const pricingStrategyData = encodeAbiParameters(
  [{ type: 'uint256' }, { type: 'uint256' }],
  [startPriceWei, endPriceWei],
)
```

**Deploy:**

```typescript
const devBuyEth = parseEther('0.1')  // optional dev buy (0n to skip)

const params = {
  owner:                   account.address,
  keyContract:             '0x0000000000000000000000000000000000000000',
  initialBuyAmount:        devBuyEth,
  vestingDuration:         864000n,               // 10 days
  pricingStrategyTemplate,
  pricingStrategyData,
  feeStrategyData:         '0x',
  tokenName:               'My Token',
  tokenSymbol:             'MYTKN',
  metadata:                'ipfs://Qm...',
  imageURI:                'ipfs://Qm...',
}

const value = parseEther('0.005') + devBuyEth

const hash = await wallet.writeContract({
  address: PONZU_RECIPE,
  abi: RECIPE_ABI,
  functionName: 'craftPonzu',
  args: [params],
  value,
})

const receipt = await publicClient.waitForTransactionReceipt({ hash })
```

**Parse Deployed Addresses:**

```typescript
const ponzuCraftedTopic = keccak256(toBytes(
  'PonzuCrafted(address,string,(address,address,address,address,address,address,address,address,address))'
))

const log = receipt.logs.find(l => l.topics[0] === ponzuCraftedTopic)!
const [, , addresses] = decodeAbiParameters(
  [
    { type: 'string' },
    {
      type: 'tuple',
      components: [
        {