> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ponzu.app/llms.txt
> Use this file to discover all available pages before exploring further.

# ABI Reference

> Contract ABIs for presale, swap, farming, and factory deployment.

***

## PonzuV4Recipe (Factory)

```typescript theme={null}
const PONZU_RECIPE = '0xCF3c37C0aD2Fd94368921ff570d100119072E826' // mainnet

const RECIPE_ABI = parseAbi([
  'function craftPonzu((address owner, address keyContract, address transferKey, uint256 initialBuyAmount, uint256 vestingDuration, bytes32 pricingStrategyTemplate, bytes pricingStrategyData, bytes feeStrategyData, string tokenName, string tokenSymbol, string metadata, address teamAddress, uint16 paymentVaultBps, uint16 teamTokenBps, uint16 presaleBps, uint16 treasuryBps, address platformReferrer, address orderReferrer, uint128 activationRate, bool farmEnabled, bool futarchyEnabled, uint256 minRaise) params) payable',
  'function getCreationFee(bytes feeStrategyData) view returns (address feeToken, uint256 feeAmount)',
])
```

### Deploy a Token

The factory app encodes a Ponzu Auction by default. The SDK encodes a Ponzu Curve. Pick one.

```typescript theme={null}
import { parseEther, parseAbi, keccak256, toBytes, encodeAbiParameters } from 'viem'

// Ponzu Auction — factory default
const auctionDuration  = 36000n   // 3600 (1h) / 36000 (10h) / 864000 (10d)
const presaleStartTime = 0n       // 0 = start now
const requestedBonus   = 5n * 10n ** 18n

const pricingStrategyTemplate = keccak256(toBytes('HyperbolicPricingStrategy')) // Ponzu Auction
const pricingStrategyData = encodeAbiParameters(
  [{ type: 'uint256' }, { type: 'uint256' }, { type: 'uint256' }],
  [auctionDuration, presaleStartTime, requestedBonus],
)

// Ponzu Curve — SDK default
// const pricingStrategyTemplate = keccak256(toBytes('LinearPricingStrategy')) // Ponzu Curve
// const pricingStrategyData = encodeAbiParameters(
//   [{ type: 'uint256' }, { type: 'uint256' }, { type: 'uint256' }, { type: 'uint256' }],
//   [startPriceWei, endPriceWei, 0n, 0n],
// )
```

Read the live creation fee. Do not hardcode it.

```typescript theme={null}
const feeStrategyData = '0x' as `0x${string}`
const [, feeAmount] = await publicClient.readContract({
  address: PONZU_RECIPE,
  abi: RECIPE_ABI,
  functionName: 'getCreationFee',
  args: [feeStrategyData],
})

const params = {
  owner: account.address,
  keyContract: zeroAddress,
  transferKey: zeroAddress,
  initialBuyAmount: 0n,
  vestingDuration: 864000n,
  pricingStrategyTemplate,
  pricingStrategyData,
  feeStrategyData,
  tokenName: 'My Token',
  tokenSymbol: 'MYTKN',
  metadata: 'ipfs://Qm...',
  teamAddress: zeroAddress,
  paymentVaultBps: 0,
  teamTokenBps: 0,
  presaleBps: 6900,
  treasuryBps: 0,
  platformReferrer: zeroAddress,
  orderReferrer: zeroAddress,
  activationRate: 0n,
  farmEnabled: true,
  futarchyEnabled: false,
  minRaise: 3_990_000_000_000_000_000n,
}

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

### Parse Deployed Addresses

```typescript theme={null}
const PONZU_CRAFTED_ABI = parseAbi([
  'event PonzuCrafted(address indexed owner, string tokenName, string tokenSymbol, (address governor, address project, address operator, address lpVault, address memberCard, address membersVault, address token, address presale, address launcher, address distributor, address farm, address hook, address paymentVault, address teamVault, address workLock) addresses, (uint256 poolId, address pricingStrategy, address protocolFeeRecipient, address ethRewarder, bytes32 pricingStrategyTemplate, uint256 vestingDuration, uint256 presaleAllocation, uint256 midRaise, uint256 minRaise, uint256 maxBonusMultiplier, bytes pricingStrategyData) terms)',
])

const receipt = await publicClient.waitForTransactionReceipt({ hash })
for (const log of receipt.logs) {
  try {
    const decoded = decodeEventLog({ abi: PONZU_CRAFTED_ABI, data: log.data, topics: log.topics })
    if (decoded.eventName === 'PonzuCrafted') {
      const { token, presale, farm, hook, launcher } = decoded.args.addresses
    }
  } catch { /* not PonzuCrafted */ }
}
```

`presale` is also the bottle NFT collection. `hook` is the chain-wide Ponzuki. Full deployment guide with pricing math: [Ponzu Factory](/protocol/recipe).

***

## Presale

```typescript theme={null}
const PRESALE_ABI = parseAbi([
  'function presale(uint256 minTokenAmount, address platformReferrer, address orderReferrer) payable',
  'function refund(uint256 ethAmount)',
  'function refundBottle(uint256 ethAmount, uint256 tokenId)',
  'function claim()',
  'function claimTokens(uint256 tokenId)',
  'function claimETH(uint256 tokenId)',
  'function triggerLaunch()',
  'function tokensAvailable() view returns (uint256)',
  'function launchTime() view returns (uint256)',
  'function totalEthRaised() view returns (uint256)',
  'function getUserBottle(address user) view returns (uint256)',
  'function claimWeight(uint256 tokenId) view returns (uint256)',
  'function ethContributions(uint256 tokenId) view returns (uint256)',
  'function calculateCost(uint256 tokenAmount) view returns (uint256)',
])
```

There is no `launched()` getter — `launchTime() > 0` means graduated. `refund` takes **ETH in**, not tokens.

### Buy Tokens

```typescript theme={null}
const ZERO = '0x0000000000000000000000000000000000000000'
await wallet.writeContract({
  address: presaleAddress,
  abi: PRESALE_ABI,
  functionName: 'presale',
  args: [0n, ZERO, ZERO], // minTokenAmount, platformReferrer, orderReferrer
  value: parseEther('0.1'),
})
```

On a curve, `minTokenAmount` is a slippage floor on tokens received. Auctions are ETH-denominated — pass `0`.

### Read Presale State

```typescript theme={null}
const tokensAvailable = await publicClient.readContract({
  address: presaleAddress, abi: PRESALE_ABI, functionName: 'tokensAvailable',
})
const launchTime = await publicClient.readContract({
  address: presaleAddress, abi: PRESALE_ABI, functionName: 'launchTime',
})
const bottleTokenId = await publicClient.readContract({
  address: presaleAddress, abi: PRESALE_ABI, functionName: 'getUserBottle', args: [account.address],
})
```

`tokensAvailable == 0` is a Ponzu Curve sellout signal. A Ponzu Auction launches when demand catches the target. Prefer `launchTime`.

### Refund (Before Launch)

```typescript theme={null}
await wallet.writeContract({
  address: presaleAddress,
  abi: PRESALE_ABI,
  functionName: 'refund',
  args: [parseEther('0.05')],
})
```

### Trigger Launch

Permissionless once the pricing strategy reports ready. The launcher still enforces `minRaise`.

```typescript theme={null}
await wallet.writeContract({
  address: presaleAddress, abi: PRESALE_ABI, functionName: 'triggerLaunch', args: [],
})
```

### Claim Vested Tokens (One-Time)

```typescript theme={null}
await wallet.writeContract({
  address: presaleAddress, abi: PRESALE_ABI, functionName: 'claimTokens', args: [bottleTokenId],
})
```

`claim()` claims the caller's first bottle.

### Claim ETH Rewards (Repeatable)

```typescript theme={null}
await wallet.writeContract({
  address: presaleAddress, abi: PRESALE_ABI, functionName: 'claimETH', args: [bottleTokenId],
})
```

***

## Ponzuki (DEX)

Swaps go through the chain-wide Ponzuki. There is no per-project hook clone. Look up the pool with the **project token**. Fee is charged on **input**.

```typescript theme={null}
const PONZUKI = '0x95da0e56e6aaAD05BAce06743cB6Fd2f7862A8c0' // mainnet

const PONZUKI_ABI = parseAbi([
  'function swapExactIn((uint256 id0, uint256 id1, address token0, address token1, uint256 feeOrHook) poolKey, uint256 amountIn, uint256 amountOutMin, bool zeroForOne, address to, uint256 deadline) payable returns (uint256 amountOut)',
  'function ponzuPoolKey(address token) view returns ((uint256 id0, uint256 id1, address token0, address token1, uint256 feeOrHook))',
  'function ponzuPoolId(address token) view returns (uint256)',
  'function getReserves(uint256 poolId) view returns (uint112 reserve0, uint112 reserve1)',
  'function getTotalFee(uint256 poolId) view returns (uint256)',
])
```

### Buy (ETH → Token)

`zeroForOne = true`. Send `msg.value = amountIn`. Approve is not required.

```typescript theme={null}
const poolKey = await publicClient.readContract({
  address: PONZUKI, abi: PONZUKI_ABI, functionName: 'ponzuPoolKey', args: [tokenAddress],
})
const deadline = BigInt(Math.floor(Date.now() / 1000) + 300)

await wallet.writeContract({
  address: PONZUKI,
  abi: PONZUKI_ABI,
  functionName: 'swapExactIn',
  args: [poolKey, ethIn, minOut, true, account.address, deadline],
  value: ethIn,
})
```

### Sell (Token → ETH)

Approve **Ponzuki**. `zeroForOne = false`. No `msg.value`.

```typescript theme={null}
await wallet.writeContract({
  address: tokenAddress,
  abi: parseAbi(['function approve(address spender, uint256 amount) returns (bool)']),
  functionName: 'approve',
  args: [PONZUKI, tokenAmountIn],
})

await wallet.writeContract({
  address: PONZUKI,
  abi: PONZUKI_ABI,
  functionName: 'swapExactIn',
  args: [poolKey, tokenAmountIn, minEthOut, false, account.address, deadline],
})
```

***

## Farm (LP Staking)

Available after graduation when the craft set `farmEnabled`. LP is an ERC-6909 balance on Ponzuki (`poolId`). Liquidity cards are embedded in the Farm.

```typescript theme={null}
const FARM_ABI = parseAbi([
  'function zapEth(uint256 amountOutMin, uint256 amount0Min, uint256 amount1Min, uint256 deadline) payable returns (uint256 cardId, uint256 liquidity)',
  'function zapEthFor(address recipient, uint256 lockDuration, uint256 amountOutMin, uint256 amount0Min, uint256 amount1Min, uint256 deadline) payable returns (uint256 cardId, uint256 liquidity)',
  'function stake(uint256 amount)',
  'function stake(uint256 amount, uint256 lockDuration)',
  'function unstake(uint256 cardId)',
  'function claim(uint256 cardId)',
  'function claimETH(uint256 cardId)',
  'function cardStakes(uint256 cardId) view returns (uint256)',
  'function earned(uint256 cardId) view returns (uint256)',
])
```

### Zap ETH → staked LP

```typescript theme={null}
const deadline = BigInt(Math.floor(Date.now() / 1000) + 300)
await wallet.writeContract({
  address: farmAddress,
  abi: FARM_ABI,
  functionName: 'zapEth',
  args: [0n, 0n, 0n, deadline],
  value: parseEther('0.1'),
})
```

Default lock is 7 days. `stake(amount)` pulls ERC-6909 LP from the caller and mints a new card.

### Claim Rewards

```typescript theme={null}
await wallet.writeContract({ address: farmAddress, abi: FARM_ABI, functionName: 'claim', args: [cardId] })
await wallet.writeContract({ address: farmAddress, abi: FARM_ABI, functionName: 'claimETH', args: [cardId] })
```

### Unstake

One-shot; burns the card. Early exit forfeits a time-proportional slice of LP.

```typescript theme={null}
await wallet.writeContract({ address: farmAddress, abi: FARM_ABI, functionName: 'unstake', args: [cardId] })
```

***

## Full Reference

Complete unabridged ABI: [ponzu.app/SKILL.md](https://ponzu.app/SKILL.md).

***

<Card title="Contract Addresses" icon="map-pin" href="/protocol/contract-addresses">
  Deployed addresses for Ethereum mainnet, Robinhood Chain, and Sepolia.
</Card>
