From d35ab87c43b4f777b175d4bfd19a9f92b9728459 Mon Sep 17 00:00:00 2001 From: krandder Date: Tue, 30 Jun 2026 11:47:42 +0100 Subject: [PATCH] Clarify liquidity manager copy --- auto-qa/tests/flm-config.test.mjs | 10 ++--- .../tests/market-creation-workflow.test.mjs | 8 ++-- .../futarchyFi/companyList/table/OrgRow.jsx | 6 +-- .../companyList/table/OrganizationsTable.jsx | 2 +- .../createMarket/CreateMarketFlow.jsx | 10 +++-- .../marketCreation/marketCreationWorkflow.js | 38 +++++++++---------- src/pages/flm/[org].jsx | 36 +++++++++++------- 7 files changed, 62 insertions(+), 48 deletions(-) diff --git a/auto-qa/tests/flm-config.test.mjs b/auto-qa/tests/flm-config.test.mjs index 0929ce4..4ea06e7 100644 --- a/auto-qa/tests/flm-config.test.mjs +++ b/auto-qa/tests/flm-config.test.mjs @@ -12,7 +12,7 @@ const ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/; const optionalAddress = (value) => value === '' || ADDRESS_RE.test(value); const bySlug = Object.fromEntries(flmConfig.map((config) => [config.slug, config])); -test('FLM config pins Kleros and Gnosis organization routes', () => { +test('liquidity manager config pins Kleros and Gnosis organization routes', () => { assert.deepEqual(Object.keys(bySlug).sort(), ['gnosis', 'kleros']); assert.equal(bySlug.kleros.path, '/flm/kleros'); @@ -24,7 +24,7 @@ test('FLM config pins Kleros and Gnosis organization routes', () => { assert.equal(bySlug.gnosis.companyId, 9); }); -test('FLM proposal metadata keeps the current official markets discoverable', () => { +test('liquidity manager proposal metadata keeps the current official markets discoverable', () => { assert.equal(bySlug.kleros.activeProposal.label, 'KIP-90'); assert.equal(bySlug.kleros.activeProposal.marketAddress, '0x84412Fe9D088C1D8Dd676a7be9a3d5d0291Ab1Cf'); assert.equal( @@ -42,7 +42,7 @@ test('FLM proposal metadata keeps the current official markets discoverable', () assert.equal(bySlug.gnosis.activeProposal.marketUrl, '/markets/0xeCe80208CB8376Be311cE0f5Ea4eF73850a0dcF0'); }); -test('FLM token and contract fields use valid address shapes', () => { +test('liquidity manager token and contract fields use valid address shapes', () => { for (const config of flmConfig) { assert.equal(config.chainId, 100); assert.match(config.token.address, ADDRESS_RE); @@ -53,7 +53,7 @@ test('FLM token and contract fields use valid address shapes', () => { } }); -test('FLM helpers pin Swapr adapter calldata and manager overloads', async () => { +test('liquidity manager helpers pin Swapr adapter calldata and manager overloads', async () => { const utilsSource = await readFile(resolve(root, 'src/utils/flm.js'), 'utf8'); const pageSource = await readFile(resolve(root, 'src/pages/flm/[org].jsx'), 'utf8'); @@ -69,7 +69,7 @@ test('FLM helpers pin Swapr adapter calldata and manager overloads', async () => assert.match(pageSource, /encodeDualExitParams\(yesExitData, noExitData\)/); }); -test('companies table links configured organizations to their FLM page', async () => { +test('companies table links configured organizations to their liquidity page', async () => { const hookSource = await readFile(resolve(root, 'src/hooks/useAggregatorCompanies.js'), 'utf8'); const rowSource = await readFile(resolve(root, 'src/components/futarchyFi/companyList/table/OrgRow.jsx'), 'utf8'); diff --git a/auto-qa/tests/market-creation-workflow.test.mjs b/auto-qa/tests/market-creation-workflow.test.mjs index aeb5375..dd218ec 100644 --- a/auto-qa/tests/market-creation-workflow.test.mjs +++ b/auto-qa/tests/market-creation-workflow.test.mjs @@ -23,7 +23,7 @@ const { const NOW = 1_782_777_600; -test('Kleros defaults use KIP, PNK, sDAI, and FLM liquidity', () => { +test('Kleros defaults use KIP, PNK, sDAI, and liquidity manager liquidity', () => { const defaults = createMarketWizardDefaults({ organizationId: 'kleros', nowSeconds: NOW }); assert.equal(defaults.organizationName, 'Kleros DAO'); @@ -81,7 +81,7 @@ test('metadata draft includes registry fields needed by market pages and proposa ); }); -test('permissionless stack plan includes org listing, owner proposals, and default FLM', () => { +test('permissionless stack plan includes org listing, owner proposals, and default liquidity manager', () => { const plan = buildPermissionlessStackPlan(); const stageIds = plan.stages.map((stage) => stage.id); @@ -94,7 +94,7 @@ test('permissionless stack plan includes org listing, owner proposals, and defau assert.equal(plan.values.chainId, 10200); }); -test('permissionless contract actions create FLM before default organization wiring', () => { +test('permissionless contract actions create liquidity manager before default organization wiring', () => { const plan = buildPermissionlessStackPlan(); const actions = plan.contractActions; const actionIds = actions.map((action) => action.id); @@ -110,7 +110,7 @@ test('permissionless contract actions create FLM before default organization wir assert.ok(actionIds.indexOf('create-default-flm-bundle') < actionIds.indexOf('create-and-list-organization')); }); -test('one-step market contract actions order market, FLM, official proposal, liquidity, and Snapshot', () => { +test('one-step market contract actions order market, liquidity manager, official proposal, liquidity, and Snapshot', () => { const plan = buildOneStepMarketPlan({ organizationId: 'kleros', nowSeconds: NOW }); const actions = plan.contractActions; const actionIds = actions.map((action) => action.id); diff --git a/src/components/futarchyFi/companyList/table/OrgRow.jsx b/src/components/futarchyFi/companyList/table/OrgRow.jsx index 1a0df2a..763d3f8 100644 --- a/src/components/futarchyFi/companyList/table/OrgRow.jsx +++ b/src/components/futarchyFi/companyList/table/OrgRow.jsx @@ -7,7 +7,7 @@ import ChainBadge from '../components/ChainBadge'; /** * Single row in the Organizations table - * Displays: Logo | Name + Active Badge | Active | Proposals | Chain + * Displays: Logo | Name + Active Badge | Active | Proposals | Chain | Liquidity */ const OrgRow = ({ companyID, @@ -76,7 +76,7 @@ const OrgRow = ({ - {/* FLM */} + {/* Liquidity */} {flmPath ? ( event.stopPropagation()} className="inline-flex h-9 items-center gap-1 rounded-lg border border-futarchyGray5 bg-white px-3 text-sm font-semibold text-futarchyGray12 hover:bg-futarchyGray3" > - FLM + Liquidity ) : ( diff --git a/src/components/futarchyFi/companyList/table/OrganizationsTable.jsx b/src/components/futarchyFi/companyList/table/OrganizationsTable.jsx index ec6a49a..a779677 100644 --- a/src/components/futarchyFi/companyList/table/OrganizationsTable.jsx +++ b/src/components/futarchyFi/companyList/table/OrganizationsTable.jsx @@ -136,7 +136,7 @@ const OrganizationsTable = ({ Chain - FLM + Liquidity diff --git a/src/components/futarchyFi/createMarket/CreateMarketFlow.jsx b/src/components/futarchyFi/createMarket/CreateMarketFlow.jsx index fd3bb04..4cca299 100644 --- a/src/components/futarchyFi/createMarket/CreateMarketFlow.jsx +++ b/src/components/futarchyFi/createMarket/CreateMarketFlow.jsx @@ -18,6 +18,10 @@ function formatDate(timestamp) { return new Date(Number(timestamp) * 1000).toISOString().replace('T', ' ').slice(0, 16) + ' UTC'; } +function formatLiquidityMode(mode) { + return mode === 'flm' ? 'Liquidity manager' : String(mode || '').toUpperCase(); +} + function StageList({ stages }) { return (
    @@ -120,7 +124,7 @@ export default function CreateMarketFlow() {

    Create Market

    A single operational flow for organization setup, proposal metadata, market creation, - FLM liquidity, Snapshot linking, candle readiness, arbitrage setup, and publishing. + liquidity manager setup, Snapshot linking, candle readiness, arbitrage setup, and publishing.

    Permissionless Chiado Stack

    This is the target testnet lifecycle: any wallet creates an organization, it is listed - automatically, and the organization receives a default FLM for proposal liquidity. + automatically, and the organization receives a default liquidity manager for proposal liquidity.

    @@ -248,7 +252,7 @@ export default function CreateMarketFlow() {
    Org: {marketPlan.values.organizationName} Close: {formatDate(marketPlan.values.closeTimestamp)} - Liquidity: {marketPlan.values.initialLiquidityMode.toUpperCase()} + Liquidity: {formatLiquidityMode(marketPlan.values.initialLiquidityMode)}
    diff --git a/src/features/marketCreation/marketCreationWorkflow.js b/src/features/marketCreation/marketCreationWorkflow.js index b33de98..d700176 100644 --- a/src/features/marketCreation/marketCreationWorkflow.js +++ b/src/features/marketCreation/marketCreationWorkflow.js @@ -86,9 +86,9 @@ export const MARKET_CREATION_STAGES = [ }, { id: 'liquidity', - title: 'Liquidity and FLM', - summary: 'Create or reuse the organization FLM, add initial liquidity, and set the official proposal.', - requiredEvidence: ['flmAddress', 'liquidityTxHash', 'officialProposalSet'], + title: 'Liquidity Manager', + summary: 'Create or reuse the organization liquidity manager, add initial liquidity, and set the official proposal.', + requiredEvidence: ['liquidityManagerAddress', 'liquidityTxHash', 'officialProposalSet'], }, { id: 'snapshot', @@ -114,8 +114,8 @@ export const MARKET_CREATION_STAGES = [ { id: 'publish', title: 'Publish', - summary: 'Expose the market and FLM links on the company page after all checks pass.', - requiredEvidence: ['companyPageLink', 'marketUrl', 'flmUrl'], + summary: 'Expose the market and liquidity manager links on the company page after all checks pass.', + requiredEvidence: ['companyPageLink', 'marketUrl', 'liquidityManagerUrl'], dependsOn: ['snapshot', 'indexing'], }, ]; @@ -124,18 +124,18 @@ export const PERMISSIONLESS_STACK_STAGES = [ { id: 'deploy-stack', title: 'Deploy permissionless stack', - summary: 'Deploy metadata implementations, public aggregator, market factory, Snapshot linker, indexer hooks, and FLM factory on Chiado.', + summary: 'Deploy metadata implementations, public aggregator, market factory, Snapshot linker, indexer hooks, and liquidity manager factory on Chiado.', }, { id: 'default-flm', - title: 'Create default FLM bundle', - summary: 'Create the proposal source, pool adapters, and default FLM bundle that will be attached to the organization.', + title: 'Create default liquidity manager', + summary: 'Create the proposal source, pool adapters, and default liquidity manager that will be attached to the organization.', dependsOn: ['deploy-stack'], }, { id: 'create-organization', title: 'Create organization', - summary: 'Any wallet can create organization metadata with default FLM wiring; the creator becomes organization owner.', + summary: 'Any wallet can create organization metadata with default liquidity manager wiring; the creator becomes organization owner.', dependsOn: ['default-flm'], }, { @@ -147,7 +147,7 @@ export const PERMISSIONLESS_STACK_STAGES = [ { id: 'owner-proposal', title: 'Owner creates proposal', - summary: 'The organization owner can create proposals and point the FLM at the official proposal.', + summary: 'The organization owner can create proposals and point the liquidity manager at the official proposal.', dependsOn: ['list-organization'], }, ]; @@ -190,7 +190,7 @@ export const PERMISSIONLESS_STACK_CONTRACT_ACTIONS = [ source: 'futarchy-liquidity-manager/src/factories/FutarchyLiquidityManagerFactory.sol', contract: 'FutarchyLiquidityManagerFactory', method: 'createLiquidityManager', - summary: 'Deploy proposal source, spot adapter, conditional adapter, and default organization FLM.', + summary: 'Deploy proposal source, spot adapter, conditional adapter, and default organization liquidity manager.', produces: ['proposalSource', 'spotAdapter', 'conditionalAdapter', 'manager'], inputs: ['CreateParams.owner', 'CreateParams.proposalManager', 'CreateParams.companyToken', 'CreateParams.officialProposer'], dependsOn: ['deploy-permissionless-registry'], @@ -202,7 +202,7 @@ export const PERMISSIONLESS_STACK_CONTRACT_ACTIONS = [ source: 'futarchy/src/registry/FutarchyAggregatorsMetadata.sol', contract: 'FutarchyAggregatorsMetadata', method: 'createAndAddOrganizationMetadataWithDefaultLiquidityManager', - summary: 'Create organization metadata, attach the FLM/proposal source, and add it to the aggregator in one call.', + summary: 'Create organization metadata, attach the liquidity manager/proposal source, and add it to the aggregator in one call.', produces: ['organizationMetadata'], inputs: ['companyName', 'description', 'metadata', 'metadataURI', 'manager', 'proposalSource', 'liquidityManagerMetadataURI'], dependsOn: ['create-default-flm-bundle'], @@ -237,7 +237,7 @@ export const PERMISSIONLESS_STACK_CONTRACT_ACTIONS = [ source: 'futarchy-liquidity-manager/src/sources/FutarchyOfficialProposalSource.sol', contract: 'FutarchyOfficialProposalSource', method: 'setOfficialProposal', - summary: 'Point the default FLM proposal source at the active proposal once the proposal address is known.', + summary: 'Point the default liquidity manager proposal source at the active proposal once the proposal address is known.', produces: ['officialProposal'], inputs: ['proposalId', 'proposalAddress', 'creator'], dependsOn: ['owner-create-proposal-metadata', 'create-default-flm-bundle'], @@ -286,7 +286,7 @@ export const ONE_STEP_MARKET_CONTRACT_ACTIONS = [ source: 'futarchy-liquidity-manager/src/factories/FutarchyLiquidityManagerFactory.sol', contract: 'FutarchyLiquidityManagerFactory', method: 'createLiquidityManager', - summary: 'Create or reuse the organization FLM bundle for this token pair.', + summary: 'Create or reuse the organization liquidity manager bundle for this token pair.', produces: ['proposalSource', 'spotAdapter', 'conditionalAdapter', 'manager'], inputs: ['CreateParams.organization', 'CreateParams.owner', 'CreateParams.companyToken', 'CreateParams.officialProposer'], dependsOn: ['create-futarchy-proposal'], @@ -298,7 +298,7 @@ export const ONE_STEP_MARKET_CONTRACT_ACTIONS = [ source: 'futarchy/src/registry/FutarchyOrganizationMetadata.sol', contract: 'FutarchyOrganizationMetadata', method: 'setDefaultLiquidityManager', - summary: 'Store the FLM and proposal source as the organization default used by market pages.', + summary: 'Store the liquidity manager and proposal source as the organization default used by market pages.', produces: ['defaultLiquidityManager'], inputs: ['manager', 'proposalSource', 'liquidityManagerMetadataURI'], dependsOn: ['create-flm-bundle'], @@ -310,7 +310,7 @@ export const ONE_STEP_MARKET_CONTRACT_ACTIONS = [ source: 'futarchy-liquidity-manager/src/sources/FutarchyOfficialProposalSource.sol', contract: 'FutarchyOfficialProposalSource', method: 'setOfficialProposal', - summary: 'Point the FLM proposal source at the newly created proposal before public Snapshot routing.', + summary: 'Point the liquidity manager proposal source at the newly created proposal before public Snapshot routing.', produces: ['officialProposal'], inputs: ['proposalId', 'proposalAddress', 'creator'], dependsOn: ['create-futarchy-proposal', 'create-flm-bundle'], @@ -322,8 +322,8 @@ export const ONE_STEP_MARKET_CONTRACT_ACTIONS = [ source: 'futarchy-liquidity-manager/src/core/FutarchyLiquidityManager.sol', contract: 'FutarchyLiquidityManager', method: 'initializeFromBootstrap', - summary: 'Seed spot liquidity through the FLM before Snapshot sends users to the market.', - produces: ['flmAddress', 'liquidityTxHash'], + summary: 'Seed spot liquidity through the liquidity manager before Snapshot sends users to the market.', + produces: ['liquidityManagerAddress', 'liquidityTxHash'], inputs: ['companyAmount', 'spotAddData'], dependsOn: ['store-default-flm', 'set-official-proposal'], }, @@ -369,7 +369,7 @@ export const ONE_STEP_MARKET_CONTRACT_ACTIONS = [ contract: 'CompanyMarketRegistry', method: 'publish', summary: 'Expose the market on the company page once Snapshot, candles, metadata, and liquidity are ready.', - produces: ['companyPageLink', 'marketUrl', 'flmUrl'], + produces: ['companyPageLink', 'marketUrl', 'liquidityManagerUrl'], dependsOn: ['link-snapshot-proposal', 'verify-registry-and-candles', 'configure-arbitrage'], }, ]; diff --git a/src/pages/flm/[org].jsx b/src/pages/flm/[org].jsx index 41dfde2..03641ac 100644 --- a/src/pages/flm/[org].jsx +++ b/src/pages/flm/[org].jsx @@ -44,6 +44,10 @@ function formatUtcTime(timestamp) { return `${new Date(timestamp * 1000).toISOString().slice(0, 16).replace('T', ' ')} UTC`; } +function formatLpShares(value, decimals) { + return `${formatTokenAmount(value, decimals)} LP shares`; +} + async function readOr(contractCall, fallback) { try { return await contractCall(); @@ -362,7 +366,7 @@ export default function FlmPage({ config }) { setReadState((current) => ({ ...current, loading: false, - error: error.message || 'Unable to read FLM position state.', + error: error.message || 'Unable to read liquidity manager position state.', })); } }, [address, config, managerConfigured]); @@ -423,7 +427,7 @@ export default function FlmPage({ config }) { const amount = kind === 'company' ? amountChecks.companyAmount : amountChecks.collateralAmount; return runWalletAction(`approve-${kind}`, async (signer) => { - if (!managerConfigured) throw new Error('FLM manager is not configured.'); + if (!managerConfigured) throw new Error('Liquidity manager is not configured.'); if (amount.lte(0)) throw new Error('Enter an approval amount first.'); const token = new ethers.Contract(tokenConfig.address, ERC20_ABI, signer); @@ -433,7 +437,7 @@ export default function FlmPage({ config }) { const depositToSpot = () => { return runWalletAction('deposit', async (signer) => { - if (!managerConfigured) throw new Error('FLM manager is not configured.'); + if (!managerConfigured) throw new Error('Liquidity manager is not configured.'); if (!amountChecks.hasDepositAmount) throw new Error('Enter a deposit amount first.'); if (amountChecks.needsCompanyApproval || amountChecks.needsCollateralApproval) { throw new Error('Approve the deposit tokens first.'); @@ -459,7 +463,7 @@ export default function FlmPage({ config }) { const redeemShares = () => { return runWalletAction('redeem', async (signer) => { - if (!managerConfigured) throw new Error('FLM manager is not configured.'); + if (!managerConfigured) throw new Error('Liquidity manager is not configured.'); if (!amountChecks.hasShares) throw new Error('Enter a share amount first.'); if (!isConfiguredAddress(redeem.recipient)) throw new Error('Enter a valid recipient address.'); @@ -496,10 +500,10 @@ export default function FlmPage({ config }) { return ( <> - {config.organizationName} FLM | Futarchy + {config.organizationName} Liquidity Manager | Futarchy @@ -511,11 +515,17 @@ export default function FlmPage({ config }) {

    - {config.organizationName} FLM + {config.organizationName} Liquidity Manager

    - {config.pair} + {config.pair} Liquidity

    +

    + FLM means Futarchy Liquidity Manager. It is the LP tool for this pair: + deposit liquidity, receive LP shares, and let the manager keep liquidity + available for the spot market or the YES/NO markets when an official + proposal is active. +

    Gnosis Chain @@ -604,16 +614,16 @@ export default function FlmPage({ config }) {
    -
    +