(undefined)
-  const [isSuccess, setIsSuccess] = useState(false)
-  const [isLoading, setIsLoading] = useState(false)
-
-  const onAmountChange = (amount: number | undefined) => {
-    setIsSuccess(false)
-    setAmount(amount)
-
-    // Check for errors.
-    if (amount !== undefined) {
-      if (user && user.balance < amount) {
-        setError('Insufficient balance')
-      } else if (amount < 1) {
-        setError('Minimum amount: ' + formatMoney(1))
-      } else {
-        setError(undefined)
-      }
-    }
-  }
-
-  const submit = () => {
-    if (!amount) return
-
-    setIsLoading(true)
-    setIsSuccess(false)
-
-    addSubsidy({ amount, contractId })
-      .then((_) => {
-        setIsSuccess(true)
-        setError(undefined)
-        setIsLoading(false)
-      })
-      .catch((_) => setError('Server error'))
-
-    track('add liquidity', { amount, contractId, slug })
-  }
-
-  return (
-    <>
-      
-        Contribute your M$ to make this market more accurate.{' '}
-        
-      
-
-      
-        
-        
-      
-
-      {isSuccess && amount && (
-        Success! Added {formatMoney(amount)} in liquidity.
-      )}
-
-      {isLoading && Processing...
}
-    >
-  )
-}
-
-function ViewLiquidityPanel(props: { contract: CPMMContract }) {
-  const { contract } = props
-  const { pool } = contract
-  const { YES: yesShares, NO: noShares } = pool
-
-  return (
-    
-      
-        The liquidity pool for this market currently contains:
-      
-      
-        {yesShares.toFixed(2)}  shares
-      
-
-      
-        {noShares.toFixed(2)}  shares
-      
-    
-  )
-}
-
-function WithdrawLiquidityPanel(props: {
-  contract: CPMMContract
-  lpShares: { YES: number; NO: number }
-}) {
-  const { contract, lpShares } = props
-  const { YES: yesShares, NO: noShares } = lpShares
-
-  const [_error, setError] = useState(undefined)
-  const [isSuccess, setIsSuccess] = useState(false)
-  const [isLoading, setIsLoading] = useState(false)
-
-  const submit = () => {
-    setIsLoading(true)
-    setIsSuccess(false)
-
-    withdrawLiquidity({ contractId: contract.id })
-      .then((_) => {
-        setIsSuccess(true)
-        setError(undefined)
-        setIsLoading(false)
-      })
-      .catch((_) => setError('Server error'))
-
-    track('withdraw liquidity')
-  }
-
-  if (isSuccess)
-    return (
-      
-        Success! Your liquidity was withdrawn.
-      
-    )
-
-  if (!yesShares && !noShares)
-    return (
-      
-        You do not have any liquidity positions to withdraw.
-      
-    )
-
-  return (
-    
-      
-        Your liquidity position is currently:
-      
-
-      
-        {yesShares.toFixed(2)}  shares
-      
-
-      
-        {noShares.toFixed(2)}  shares
-      
-
-      
-        
-      
-
-      {isLoading && Processing...
}
-    
-  )
-}
diff --git a/web/components/contract/liquidity-button.tsx b/web/components/contract/liquidity-button.tsx
new file mode 100644
index 00000000..f99f175a
--- /dev/null
+++ b/web/components/contract/liquidity-button.tsx
@@ -0,0 +1,88 @@
+import { useState } from 'react'
+import clsx from 'clsx'
+
+import { Button } from 'web/components/button'
+import { formatMoney, shortFormatNumber } from 'common/util/format'
+import { Col } from 'web/components/layout/col'
+import { Tooltip } from '../tooltip'
+import { CPMMContract } from 'common/contract'
+import { User } from 'common/user'
+import { useLiquidity } from 'web/hooks/use-liquidity'
+import { LiquidityModal } from './liquidity-modal'
+
+export function LiquidityButton(props: {
+  contract: CPMMContract
+  user: User | undefined | null
+}) {
+  const { contract, user } = props
+  const { totalLiquidity: total } = contract
+
+  const lp = useLiquidity(contract.id)
+  const userActive = lp?.find((l) => l.userId === user?.id) !== undefined
+
+  const [open, setOpen] = useState(false)
+
+  return (
+    
+       setOpen(true)}
+      />
+      
+    
+  )
+}
+
+function LiquidityIconButton(props: {
+  total: number
+  onClick: () => void
+  userActive: boolean
+  isCompact?: boolean
+  disabled?: boolean
+}) {
+  const { total, userActive, isCompact, onClick, disabled } = props
+
+  return (
+    
+  )
+}
diff --git a/web/components/contract/liquidity-modal.tsx b/web/components/contract/liquidity-modal.tsx
new file mode 100644
index 00000000..9780c0a8
--- /dev/null
+++ b/web/components/contract/liquidity-modal.tsx
@@ -0,0 +1,107 @@
+import { CPMMContract } from 'common/contract'
+import { formatMoney } from 'common/util/format'
+import { useState } from 'react'
+import { useUser } from 'web/hooks/use-user'
+import { addSubsidy } from 'web/lib/firebase/api'
+import { track } from 'web/lib/service/analytics'
+import { AmountInput } from '../amount-input'
+import { Button } from '../button'
+import { InfoTooltip } from '../info-tooltip'
+import { Col } from '../layout/col'
+import { Modal } from '../layout/modal'
+import { Row } from '../layout/row'
+import { Title } from '../title'
+
+export function LiquidityModal(props: {
+  contract: CPMMContract
+  isOpen: boolean
+  setOpen: (open: boolean) => void
+}) {
+  const { contract, isOpen, setOpen } = props
+  const { totalLiquidity } = contract
+
+  return (
+    
+      
+        
+
+        Total liquidity subsidies: {formatMoney(totalLiquidity)}
+        
+      
+    
+  )
+}
+
+function AddLiquidityPanel(props: { contract: CPMMContract }) {
+  const { contract } = props
+  const { id: contractId, slug } = contract
+
+  const user = useUser()
+
+  const [amount, setAmount] = useState(undefined)
+  const [error, setError] = useState(undefined)
+  const [isSuccess, setIsSuccess] = useState(false)
+  const [isLoading, setIsLoading] = useState(false)
+
+  const onAmountChange = (amount: number | undefined) => {
+    setIsSuccess(false)
+    setAmount(amount)
+
+    // Check for errors.
+    if (amount !== undefined) {
+      if (user && user.balance < amount) {
+        setError('Insufficient balance')
+      } else if (amount < 1) {
+        setError('Minimum amount: ' + formatMoney(1))
+      } else {
+        setError(undefined)
+      }
+    }
+  }
+
+  const submit = () => {
+    if (!amount) return
+
+    setIsLoading(true)
+    setIsSuccess(false)
+
+    addSubsidy({ amount, contractId })
+      .then((_) => {
+        setIsSuccess(true)
+        setError(undefined)
+        setIsLoading(false)
+      })
+      .catch((_) => setError('Server error'))
+
+    track('add liquidity', { amount, contractId, slug })
+  }
+
+  return (
+    <>
+      
+        Contribute your M$ to make this market more accurate by subsidizing
+        trader participation. 
+      
+
+      
+        
+        
+      
+
+      {isSuccess && amount && (
+        Success! Added {formatMoney(amount)} in liquidity.
+      )}
+
+      {isLoading && Processing...
}
+    >
+  )
+}