Priors lab

ERC-8463 · draft under review

Pool Liquidity Locks

One interface for any contract that locks pool liquidity (v2 pool tokens, v3 and v4 positions).

StatusTestnet only

Guided in the app: Launch a token, Create a pool and lock its liquidity.

Pull request
ethereum/ERCs #2107 (the text under review)
Text pinned at
ERCS/erc-8463.md at d9e55a3
d9e55a3349d4f001aff09e5911d71d2390406979
Discussion
Its thread on Ethereum Magicians
Reference
priors-agents/erc-liquidity-locks at 6db5a51
6db5a5171798d1069f08499a8160ea4e7d9beaf0
Markdown
/erc/8463.md

What it is

This proposal defines an interface for a contract that holds pool liquidity under locks: a locker. A lock is either a quantity of fungible pool tokens, an ERC-20 token whose balance is a share of a pool, or one position held as an ERC-721 token of a position manager. Each lock names its pool, the position, the liquidity locked, the time it unlocks or that it never does, the account that receives the liquidity at release, and the account paid the position's fees meanwhile. A locker lists its locks by pool and sums them per pool into permanent and timed liquidity with the earliest unlock time, so scanners, launchpads and lenders read any conforming locker with one integration. Which lockers to count stays the reader's choice; the interface makes that choice checkable against what the locker holds.

Specification headings

  1. Interface
  2. Locks
  3. Creating locks
  4. Holding
  5. Extending
  6. Releasing
  7. Fees
  8. Reading
  9. Detector inputs

The abstract and headings above are the text at d9e55a3, CC0. Read the full text at that commit.

Nothing at Priors runs this draft. Its reference contracts go on the testnet only.

Try it

On Robinhood Chain testnet (46630), with the reference contracts at their pinned commits and test tokens of no value. Each action shows the call it prepares before your wallet signs it, and each send is simulated first.

Set up

Four steps, once: your wallet on Robinhood Chain testnet, a little test ETH for its fees, test dollars of no value, and a testnet identity. The forms below fill from them.

  1. 1

    Wallet

    Not connected. Any browser wallet works: the lab switches it to Robinhood Chain testnet (46630) and sends nothing on another chain.

  2. 2

    Test ETH

    For the testnet's network fees. The lab's drip sends a little to a connected wallet once a day.

  3. 3

    Test dollars

    The Lab Test Dollar (no value) that lines lend and launches pair with.

  4. 4

    Testnet identity

    An ERC-8004 identity on the testnet registry, for the forms that take an agent id.

The testnet contracts

ContractAddress on testnet (46630)
The lab's liquidity locker (LiquidityLocker)0xf161B0d86746fAf7C88C4B3Cc560f7025e0423e9
The liquidity lock reference's mock position manager (MockPositionManager, over the lab's pool factory)0x94781fB93f69ed3cA208f294D1d0A25476367E6e
The lab's pool factory (LabPoolFactory: pools computed from their tokens and fee, pool tokens of your own)0x2B60aB8ABfD1661fcF86c803cff19Edbd694D708

Launch a token

One transaction through the lab's launchpad (LabLaunchpad): it creates a plain test token, seeds its pool against the Lab Test Dollar, locks that liquidity under ERC-8463 until the time you choose, declares the launch under ERC-8462 and registers its creator fee stream under ERC-8459, with you as its recipient. Each is then read back below, as on the ERC-8462 page.

Every token launched here is a visitor's test token, not verified: anyone can launch one on the lab, and the lab vouches for none.

Launch a test token in one transaction: token, pool, liquidity lock, declaration, fee stream

Who signsanyone (the creator)

ERC-8462: the launch, as the launchpad records it

A visitor's test token, not verified: anyone can launch one on the lab, and the lab vouches for none.

Read on the testnet once its fields are filled.

ERC-8462: the token's declarations

A visitor's test token, not verified: anyone can launch one on the lab, and the lab vouches for none.

Read on the testnet once its fields are filled.

ERC-8462: the declaration (creator, allocations, liquidity, fee recipient)

A visitor's test token, not verified: anyone can launch one on the lab, and the lab vouches for none.

Read on the testnet once its fields are filled.

ERC-8463: the liquidity lock

A visitor's test token, not verified: anyone can launch one on the lab, and the lab vouches for none.

Read on the testnet once its fields are filled.

ERC-8463: the pool's locked liquidity

A visitor's test token, not verified: anyone can launch one on the lab, and the lab vouches for none.

Read on the testnet once its fields are filled.

ERC-8459: the creator fee stream

A visitor's test token, not verified: anyone can launch one on the lab, and the lab vouches for none.

Read on the testnet once its fields are filled.

Actions

Create a pool token of your own (LabPoolToken: its whole supply minted once to you, no fee, no setting)

Who signsanyone (its first holder)

Let the locker take pool tokens

Who signsthe holder

Lock pool tokens

Who signsthe holder

Mint a mock position (the reference's MockPositionManager; its pool follows from its tokens and fee)

Who signsanyone

Let the locker take a position

Who signsthe position's owner

Lock a position

Who signsthe position's owner

Extend a lock

Who signsthe lock's beneficiary

Release a lock that has lapsed

Who signsanyone, at or after its unlock time

Collect a locked position's fees

Who signsanyone (they go to the fee recipient)

Credit fees to a mock position

Who signsanyone (a mock)

Reads

The pool of two tokens and a fee, as the lab's pool factory computes it (no one can set or move it)

Read on the testnet once its fields are filled.

A mock position: its owner, tokens, fee, liquidity and pool; and the id the next mint gets

Read on the testnet once its fields are filled.

A pool's locks

A visitor's test token, not verified: anyone can launch one on the lab, and the lab vouches for none.

Read on the testnet once its fields are filled.

Deploy your own

Deploy the reference contract from its pinned commit with your own wallet, on the testnet: you become its lender, launchpad or backer. Its address shows once the receipt is in, and Check a contract below reads it.

Your own LiquidityLocker over a position manager

Who signsanyone

With an agent

Your agent gets the same lab through the MCP server at https://lab.priors.trade/mcp or the HTTP API described by /openapi.json. It reads, and gets back unsigned testnet transactions to sign with its own testnet key. The lab holds no key of its own for you and never asks for one.

MCP tools for ERC-8463

lab_erc(8463)
What the draft does on the lab, its contracts and an agent's next calls.
lab_setup(address)
Test ETH, test dollars and the testnet identities of an address, with the calls to register one and mint test dollars.
lab_read(8463, "lock", { lock_id, contract })
One lock.
lab_read(8463, "locked_liquidity", { pool, pool_id, contract })
A pool's locked liquidity, and for a pool token how much of its supply that is.
lab_read(8463, "pool_of", { token0, token1, fee })
The pool of two tokens and a fee, as the lab's pool factory computes it (no one can set or move it).
lab_read(8463, "position", { token_id })
A mock position: its owner, tokens, fee, liquidity and pool; and the id the next mint gets.
lab_read(8463, "locks_of_pool", { pool, pool_id, start, limit, contract })
A pool's locks.
lab_prepare(8463, "create_pool_token", { token_b, token_a, supply })
Create a pool token of your own (LabPoolToken: its whole supply minted once to you, no fee, no setting). Who signs: anyone (its first holder)
lab_prepare(8463, "approve_pool_tokens", { pool_token, amount, contract })
Let the locker take pool tokens. Who signs: the holder
lab_prepare(8463, "lock_pool_tokens", { pool_token, amount, unlock_at, beneficiary, contract })
Lock pool tokens. Who signs: the holder
lab_prepare(8463, "mint_position", { to, token0, token1, fee, liquidity })
Mint a mock position (the reference's MockPositionManager; its pool follows from its tokens and fee). Who signs: anyone
lab_prepare(8463, "approve_position", { token_id, contract })
Let the locker take a position. Who signs: the position's owner
lab_prepare(8463, "lock_position", { token_id, unlock_at, beneficiary, fee_recipient, contract })
Lock a position. Who signs: the position's owner
lab_prepare(8463, "extend_lock", { lock_id, unlock_at, contract })
Extend a lock. Who signs: the lock's beneficiary
lab_prepare(8463, "release_lock", { lock_id, contract })
Release a lock that has lapsed. Who signs: anyone, at or after its unlock time
lab_prepare(8463, "collect_fees", { lock_id, contract })
Collect a locked position's fees. Who signs: anyone (they go to the fee recipient)
lab_prepare(8463, "accrue_fees", { token_id, owed0, owed1 })
Credit fees to a mock position. Who signs: anyone (a mock)
lab_deploy_prepare(8463, "locker", { position_manager })
Your own LiquidityLocker over a position manager.
lab_check_contract(8463, chain, address)
The conformance read of any contract, on testnet or mainnet: supportsInterface and the views.
lab_feedback_draft(8463, note, txHash?)
The report text and the thread and issue links. It posts nothing.

HTTP

  • GET https://lab.priors.trade/api/lab/erc/8463
  • GET https://lab.priors.trade/api/lab/read/8463/lock?lock_id=<lock_id>&contract=<contract>
  • GET https://lab.priors.trade/api/lab/read/8463/locked_liquidity?pool=<pool>&pool_id=<pool_id>&contract=<contract>
  • GET https://lab.priors.trade/api/lab/read/8463/pool_of?token0=<token0>&token1=<token1>&fee=<fee>
  • GET https://lab.priors.trade/api/lab/read/8463/position?token_id=<token_id>
  • GET https://lab.priors.trade/api/lab/read/8463/locks_of_pool?pool=<pool>&pool_id=<pool_id>&start=<start>&limit=<limit>&contract=<contract>
  • GET https://lab.priors.trade/api/lab/prepare/8463/create_pool_token?token_b=<token_b>&token_a=<token_a>&supply=<supply>
  • GET https://lab.priors.trade/api/lab/prepare/8463/approve_pool_tokens?pool_token=<pool_token>&amount=<amount>&contract=<contract>
  • GET https://lab.priors.trade/api/lab/prepare/8463/lock_pool_tokens?pool_token=<pool_token>&amount=<amount>&unlock_at=<unlock_at>&beneficiary=<beneficiary>&contract=<contract>
  • GET https://lab.priors.trade/api/lab/prepare/8463/mint_position?to=<to>&token0=<token0>&token1=<token1>&fee=<fee>&liquidity=<liquidity>
  • GET https://lab.priors.trade/api/lab/prepare/8463/approve_position?token_id=<token_id>&contract=<contract>
  • GET https://lab.priors.trade/api/lab/prepare/8463/lock_position?token_id=<token_id>&unlock_at=<unlock_at>&beneficiary=<beneficiary>&fee_recipient=<fee_recipient>&contract=<contract>
  • GET https://lab.priors.trade/api/lab/prepare/8463/extend_lock?lock_id=<lock_id>&unlock_at=<unlock_at>&contract=<contract>
  • GET https://lab.priors.trade/api/lab/prepare/8463/release_lock?lock_id=<lock_id>&contract=<contract>
  • GET https://lab.priors.trade/api/lab/prepare/8463/collect_fees?lock_id=<lock_id>&contract=<contract>
  • GET https://lab.priors.trade/api/lab/prepare/8463/accrue_fees?token_id=<token_id>&owed0=<owed0>&owed1=<owed1>
  • GET https://lab.priors.trade/api/lab/deploy/8463/locker?position_manager=<position_manager>
  • GET https://lab.priors.trade/api/lab/check/8463/<chain>/<address>
  • GET https://lab.priors.trade/api/lab/setup/<address>

Connect it, for example in Claude Code: claude mcp add --transport http priors-lab https://lab.priors.trade/mcp

A prompt to copy

Use the Priors lab on Robinhood Chain testnet (chain id 46630), where every token is a test token of no value. Its MCP server is https://lab.priors.trade/mcp and this draft's page is https://lab.priors.trade/erc/8463.md. Try ERC-8463, Pool Liquidity Locks (a draft under review). Start with lab_setup for my testnet address to see my test ETH, test dollars and identities, then create a pool token of your own (labpooltoken: its whole supply minted once to you, no fee, no setting), then let the locker take pool tokens, then lock pool tokens, then mint a mock position (the reference's mockpositionmanager; its pool follows from its tokens and fee), then let the locker take a position, then lock a position with lab_prepare(8463, <action>, params). Each prepare returns an unsigned transaction { chainId: 46630, to, data, value }: sign and send it yourself with a testnet key, and refuse any other chain. Never ask me for a key. After each transaction, read the result back with lab_read and tell me what changed. If the draft or its reference code looks wrong, draft a report with lab_feedback_draft.

Check a contract

Paste any contract on either chain: the lab reads supportsInterface for ILiquidityLocks 0x15d36c4a (computed from the pinned interface) and ERC-165's own, then calls each view. It only reads, so another implementer can test conformance with nothing signed.

Feedback

What you found goes where the draft is worked on: the discussion of the text in its thread on Ethereum Magicians, a bug in the reference code in its repository's issues. You post it under your own account. The lab posts nothing for anyone.