Skip to main content

Banger Developer Guide

Learn how to integrate with Banger. This guide covers smart contract interactions, token deployment, querying, and minting.

Note: On the Net website, Banger tokens are referred to as "Netr tokens". At the contract level, they are still called "Banger tokens". The original Banger contract was forked from the original Clanker contracts.

How Banger Works

Core Architecture

Banger uses a multi-contract architecture:

  1. BangerV4: Orchestrates token deployment, pool creation, liquidity locking, and NFT drop creation
  2. BangerV4Token: ERC-20 token implementation deployed via CREATE2
  3. LockerFactoryV3: Factory for deploying LP lockers
  4. LpLockerV3: LP position locker contract
  5. InscribedDropsDynamic: ERC1155 NFT contract (single NFT drop per token)

Deployment Flow

Banger orchestrates all deployment steps in a single transaction:

Deployment Phase (BangerV4):

  • User calls deployToken() with parameters
  • BangerV4 validates tick and deploys token via CREATE2
  • Creates Uniswap V3 pool and adds liquidity
  • Deploys locker and transfers LP NFT
  • Creates single ERC1155 NFT drop via InscribedDrops (always created, but only functional when enabled)
  • Stores deployment data in Net Storage and sends Net message

Key Point: BangerV4 orchestrates all steps in one transaction. The token address is deterministic, the pool is created automatically, liquidity is locked permanently, and all data is stored onchain.

Net Message Structure

When Banger stores a deployment, it creates a Net message with:

  • Topic: Token address (checksummed hex string)
  • Text: Human-readable format (e.g., "Deployed TokenName (SYMBOL) to 0x... (pool: 0x...)")
  • Data: ABI-encoded deployment data (message index, pool, token, locker, tokenId, deployer, fid, extra data)

Core Contracts

BangerV4

Purpose: Orchestrate token deployment, pool creation, liquidity locking, and NFT drop creation

Function:

function deployToken(
uint256 _supply,
int24 _initialTick,
bytes32 _salt,
address _deployer,
uint256 _fid,
uint256 mintPrice,
uint256 mintEndTimestamp,
uint256 maxMintSupply,
string calldata _name,
string calldata _symbol,
string calldata _image,
string calldata _animation,
address _metadataAddress,
string calldata _extraStringData
) external payable returns (BangerV4Token token, uint256 tokenId)

Validation Rules:

  • _initialTick must be valid for pool fee tier (10,000 = 1%)
  • _initialTick % tickSpacing == 0
  • Token address (from CREATE2) must be < WETH address

Net Message:

  • Topic: Token address (checksummed hex string)
  • Text: "Deployed <name> (<symbol>) to <tokenAddress> (pool: <poolAddress>)"
  • Data: abi.encode(msgIdx, pool, token, lockerAddress, tokenId, deployer, fid, extraStringData)

Events:

  • TokenCreated(address indexed tokenAddress, uint256 indexed lpNftId, address indexed deployer, uint256 fid, string name, string symbol, uint256 supply, address lockerAddress, string extraStringData, bool isMsgSenderOwner)

Errors:

  • Deprecated() - thrown if contract is deprecated

BangerV4Token

Purpose: ERC-20 token implementation deployed via CREATE2

Key: Deterministic address generation using keccak256(abi.encode(_deployer, _salt))

Constructor: Mints entire supply to BangerV4 contract

LockerFactoryV3

Purpose: Factory for deploying LP lockers

Function:

function deploy(
address token,
address beneficiary,
uint64 durationSeconds,
uint256 tokenId,
uint256 fees,
address nonfungiblePositionManager
) public payable returns (address)

Events:

  • deployed(address indexed lockerAddress, address indexed owner, uint256 tokenId, uint256 lockingPeriod)

LpLockerV3

Purpose: Lock Uniswap V3 LP positions

Functions:

  • release() - Release LP NFT when lock expires (effectively never, ~1000 years)
  • collectFees(address _recipient, uint256 _tokenId) - Collect LP fees, split between protocol and creator
  • vestingSchedule() - Returns time remaining until unlock

Lock duration: defaultLockingPeriod = 33275115461 seconds (~1000 years, effectively permanent)

Deploying Tokens

To deploy a token in Banger, you prepare deployment parameters, generate a salt for deterministic address, then call BangerV4.deployToken(). BangerV4 validates the parameters, deploys the token, creates the Uniswap pool, locks liquidity, creates the NFT drop, and stores everything in Net Protocol.

Default Values

Total Supply: 100000000000000000000000000000 (100 billion tokens, same across all chains)

Initial Tick (chain-dependent):

  • Base: -230400 (~$35,000 market cap)
  • Hyperliquid: -177400
  • Plasma: -147200

Deploying a Token

To deploy a token, call BangerV4.deployToken() with the required parameters. The contract address can be found in the "Contract Addresses" section below.

Process:

  1. Generate salt: Call BangerV4.generateSalt() or BangerV4.predictToken() to get a deterministic token address
  2. Validate address: Ensure the predicted address is less than the WETH address (required by BangerV4)
  3. Deploy: Call deployToken() with all parameters, optionally including ETH for an initial token purchase

What happens: BangerV4 validates the tick, deploys the token via CREATE2, creates the Uniswap pool, adds liquidity, locks the LP position, creates the NFT drop, and stores all deployment data in Net Protocol. All in one transaction.

The token address is deterministic based on the deployer address and salt. All deployment data is stored in Net Protocol for onchain querying.

Querying Token Data

Banger uses Net Protocol for onchain token discovery. When you deploy a token via Banger, it's stored as a Net message with the token address as the topic. This enables querying all deployments directly from the blockchain.

Querying Deployments

To find deployment data for a token, query Net Storage using the token address as the key and the BangerV4 contract address as the operator.

Process:

  1. Convert token address to storage key: Convert the token address to a bytes32 key (e.g., bytes32(uint256(uint160(tokenAddress))))
  2. Query Net Storage: Call Storage.get(key, operator) where:
    • key is the token address converted to bytes32
    • operator is the BangerV4 contract address
  3. Decode deployment data: The returned data contains abi.encode(msgIdx, dropIdx, inscribedDropsAddress, pool, lockerAddress, tokenId)
  4. Get full Net message: Use the msgIdx from the decoded data to query the full Net message via Net.getMessage(msgIdx)

What this returns: The deployment data includes the message index, drop index, InscribedDrops contract address, Uniswap pool address, locker address, and LP NFT token ID. The full Net message contains human-readable deployment details.

Querying Mint Events

You can query Net messages by app (BangerV4 contract address) and topic (token address) to get mint messages for a specific token. Filter the results of that query by msg.text === "mint" to get only mint messages. The message data contains abi.encode(quantity, dropIdx, token, pool).

Minting NFTs

Call BangerV4.mint(tokenAddress, quantity) with ETH. The contract retrieves the drop index from Net Storage, mints NFTs from InscribedDropsDynamic, and optionally swaps ETH for tokens. A Net message is sent to track the mint activity.

What happens: BangerV4 retrieves the drop index from Net Storage, mints NFTs from InscribedDropsDynamic, transfers NFTs to the minter, and if ETH is sent, swaps it for tokens after deducting the InscribedDrops fee. A Net message is sent to track the mint activity.

Fee Structure

LP Fees:

  • Collected via LpLockerV3.collectFees()
  • Split between protocol and creator based on lpFeesCut (percentage 0-100, set during locker deployment)
  • Formula: protocolFee = (amount * lpFeesCut) / 100
  • Remaining goes to recipient (creator)

InscribedDrops Fee:

  • Applied during minting (deducted from msg.value before token swap)
  • Fee rate determined by InscribedDropsDynamic.feeBps()

Net Protocol Integration

Net Messages

  1. Deployment Message:

    • App: BangerV4 contract address
    • Sender: msg.sender (may be different from deployer if bot deploys)
    • Text: "Deployed <name> (<symbol>) to <tokenAddress> (pool: <poolAddress>)"
    • Topic: Token address (checksummed hex string)
    • Data: abi.encode(msgIdx, pool, token, lockerAddress, tokenId, deployer, fid, extraStringData)
  2. Mint Message:

    • App: BangerV4 contract address
    • Sender: Minter address
    • Text: "mint"
    • Topic: Token address (checksummed hex string)
    • Data: abi.encode(quantity, dropIdx, token, pool)

Net Storage

  1. Token Address → Deployment Data:

    • Key: bytes32(uint256(uint160(tokenAddress)))
    • Operator: BangerV4 contract address
    • Value: abi.encode(msgIdx, dropIdx, inscribedDropsAddress, pool, lockerAddress, tokenId)
  2. Drop Index → Token/Pool:

    • Key: bytes32(dropIdx)
    • Operator: BangerV4 contract address
    • Value: abi.encode(dropIdx, token, pool)

Contract Addresses

Banger Contracts

Base:

  • BangerV4: 0x000000C91A20BE8342B6D4dfc0947f1Ec5333BF6

Plasma:

  • BangerV4: 0x00000000CDaB5161815cD4005fAc11AC3a796F63

LockerFactoryV3

Base:

  • LockerFactoryV3: 0x00000000a4944d1E707f869356fF4B48e527370f