diff --git a/common/notification.ts b/common/notification.ts
index d6615514..845a859e 100644
--- a/common/notification.ts
+++ b/common/notification.ts
@@ -18,6 +18,7 @@ export type Notification = {
   sourceContractTitle?: string
   sourceContractCreatorUsername?: string
   sourceContractSlug?: string
+  sourceContractTags?: string[]
 }
 export type notification_source_types =
   | 'contract'
diff --git a/functions/src/create-notification.ts b/functions/src/create-notification.ts
index 892b42eb..83ba9f24 100644
--- a/functions/src/create-notification.ts
+++ b/functions/src/create-notification.ts
@@ -66,12 +66,31 @@ export const createNotification = async (
           sourceContractTitle: sourceContract?.question,
           sourceContractCreatorUsername: sourceContract?.creatorUsername,
           sourceContractSlug: sourceContract?.slug,
+          sourceContractTags: sourceContract?.tags,
         }
         await notificationRef.set(removeUndefinedProps(notification))
       })
     )
   }
 
+  const notifyLiquidityProviders = async (
+    userToReasonTexts: user_to_reason_texts,
+    contract: Contract
+  ) => {
+    const liquidityProviders = await firestore
+      .collection(`contracts/${contract.id}/liquidity`)
+      .get()
+    const liquidityProvidersIds = uniq(
+      liquidityProviders.docs.map((doc) => doc.data().userId)
+    )
+    liquidityProvidersIds.forEach((userId) => {
+      if (!shouldGetNotification(userId, userToReasonTexts)) return
+      userToReasonTexts[userId] = {
+        reason: 'on_contract_with_users_shares_in',
+      }
+    })
+  }
+
   const notifyUsersFollowers = async (
     userToReasonTexts: user_to_reason_texts
   ) => {
@@ -94,14 +113,11 @@ export const createNotification = async (
   }
 
   const notifyRepliedUsers = async (
-    userToReasonTexts: user_to_reason_texts
+    userToReasonTexts: user_to_reason_texts,
+    relatedUserId: string,
+    relatedSourceType: notification_source_types
   ) => {
-    if (
-      !relatedSourceType ||
-      !relatedUserId ||
-      !shouldGetNotification(relatedUserId, userToReasonTexts)
-    )
-      return
+    if (!shouldGetNotification(relatedUserId, userToReasonTexts)) return
     if (relatedSourceType === 'comment') {
       userToReasonTexts[relatedUserId] = {
         reason: 'reply_to_users_comment',
@@ -123,8 +139,10 @@ export const createNotification = async (
       }
   }
 
-  const notifyTaggedUsers = async (userToReasonTexts: user_to_reason_texts) => {
-    if (!sourceText) return
+  const notifyTaggedUsers = async (
+    userToReasonTexts: user_to_reason_texts,
+    sourceText: string
+  ) => {
     const taggedUsers = sourceText.match(/@\w+/g)
     if (!taggedUsers) return
     // await all get tagged users:
@@ -143,9 +161,13 @@ export const createNotification = async (
 
   const notifyContractCreator = async (
     userToReasonTexts: user_to_reason_texts,
-    sourceContract: Contract
+    sourceContract: Contract,
+    options?: { force: boolean }
   ) => {
-    if (shouldGetNotification(sourceContract.creatorId, userToReasonTexts))
+    if (
+      options?.force ||
+      shouldGetNotification(sourceContract.creatorId, userToReasonTexts)
+    )
       userToReasonTexts[sourceContract.creatorId] = {
         reason: 'on_users_contract',
       }
@@ -189,7 +211,7 @@ export const createNotification = async (
     })
   }
 
-  const notifyOtherBettorsOnContract = async (
+  const notifyBettorsOnContract = async (
     userToReasonTexts: user_to_reason_texts,
     sourceContract: Contract
   ) => {
@@ -216,30 +238,41 @@ export const createNotification = async (
     })
   }
 
-  // TODO: Update for liquidity.
-  // TODO: Notify users of their own closed but not resolved contracts.
   const getUsersToNotify = async () => {
     const userToReasonTexts: user_to_reason_texts = {}
     // The following functions modify the userToReasonTexts object in place.
-    if (
-      sourceContract &&
-      (sourceType === 'comment' ||
+    if (sourceContract) {
+      if (
+        sourceType === 'comment' ||
         sourceType === 'answer' ||
         (sourceType === 'contract' &&
-          (sourceUpdateType === 'updated' || sourceUpdateType === 'resolved')))
-    ) {
-      if (sourceType === 'comment') {
-        await notifyRepliedUsers(userToReasonTexts)
-        await notifyTaggedUsers(userToReasonTexts)
+          (sourceUpdateType === 'updated' || sourceUpdateType === 'resolved'))
+      ) {
+        if (sourceType === 'comment') {
+          if (relatedUserId && relatedSourceType)
+            await notifyRepliedUsers(
+              userToReasonTexts,
+              relatedUserId,
+              relatedSourceType
+            )
+          if (sourceText) await notifyTaggedUsers(userToReasonTexts, sourceText)
+        }
+        await notifyContractCreator(userToReasonTexts, sourceContract)
+        await notifyOtherAnswerersOnContract(userToReasonTexts, sourceContract)
+        await notifyLiquidityProviders(userToReasonTexts, sourceContract)
+        await notifyBettorsOnContract(userToReasonTexts, sourceContract)
+        await notifyOtherCommentersOnContract(userToReasonTexts, sourceContract)
+      } else if (sourceType === 'contract' && sourceUpdateType === 'created') {
+        await notifyUsersFollowers(userToReasonTexts)
+      } else if (sourceType === 'contract' && sourceUpdateType === 'closed') {
+        await notifyContractCreator(userToReasonTexts, sourceContract, {
+          force: true,
+        })
+      } else if (sourceType === 'liquidity' && sourceUpdateType === 'created') {
+        await notifyContractCreator(userToReasonTexts, sourceContract)
       }
-      await notifyContractCreator(userToReasonTexts, sourceContract)
-      await notifyOtherAnswerersOnContract(userToReasonTexts, sourceContract)
-      await notifyOtherBettorsOnContract(userToReasonTexts, sourceContract)
-      await notifyOtherCommentersOnContract(userToReasonTexts, sourceContract)
     } else if (sourceType === 'follow' && relatedUserId) {
       await notifyFollowedUser(userToReasonTexts, relatedUserId)
-    } else if (sourceType === 'contract' && sourceUpdateType === 'created') {
-      await notifyUsersFollowers(userToReasonTexts)
     }
     return userToReasonTexts
   }
diff --git a/functions/src/index.ts b/functions/src/index.ts
index ecc17133..88a13759 100644
--- a/functions/src/index.ts
+++ b/functions/src/index.ts
@@ -22,12 +22,13 @@ export * from './update-recommendations'
 export * from './update-feed'
 export * from './backup-db'
 export * from './change-user-info'
-export * from './market-close-emails'
+export * from './market-close-notifications'
 export * from './add-liquidity'
 export * from './on-create-answer'
 export * from './on-update-contract'
 export * from './on-create-contract'
 export * from './on-follow-user'
+export * from './on-create-liquidity-provision'
 
 // v2
 export * from './health'
@@ -35,4 +36,4 @@ export * from './place-bet'
 export * from './sell-bet'
 export * from './sell-shares'
 export * from './create-contract'
-export * from './withdraw-liquidity'
\ No newline at end of file
+export * from './withdraw-liquidity'
diff --git a/functions/src/market-close-emails.ts b/functions/src/market-close-notifications.ts
similarity index 81%
rename from functions/src/market-close-emails.ts
rename to functions/src/market-close-notifications.ts
index 17700613..ee9952bf 100644
--- a/functions/src/market-close-emails.ts
+++ b/functions/src/market-close-notifications.ts
@@ -4,8 +4,9 @@ import * as admin from 'firebase-admin'
 import { Contract } from '../../common/contract'
 import { getPrivateUser, getUserByUsername } from './utils'
 import { sendMarketCloseEmail } from './emails'
+import { createNotification } from './create-notification'
 
-export const marketCloseEmails = functions
+export const marketCloseNotifications = functions
   .runWith({ secrets: ['MAILGUN_KEY'] })
   .pubsub.schedule('every 1 hours')
   .onRun(async () => {
@@ -56,5 +57,14 @@ async function sendMarketCloseEmails() {
     if (!privateUser) continue
 
     await sendMarketCloseEmail(user, privateUser, contract)
+    await createNotification(
+      contract.id,
+      'contract',
+      'closed',
+      user,
+      'closed' + contract.id.slice(6, contract.id.length),
+      contract.closeTime?.toString() ?? new Date().toString(),
+      contract
+    )
   }
 }
diff --git a/functions/src/on-create-contract.ts b/functions/src/on-create-contract.ts
index 040ba378..20c7ceba 100644
--- a/functions/src/on-create-contract.ts
+++ b/functions/src/on-create-contract.ts
@@ -18,7 +18,7 @@ export const onCreateContract = functions.firestore
       'created',
       contractCreator,
       eventId,
-      contract.question,
+      contract.description,
       contract
     )
   })
diff --git a/functions/src/on-create-liquidity-provision.ts b/functions/src/on-create-liquidity-provision.ts
new file mode 100644
index 00000000..189b4693
--- /dev/null
+++ b/functions/src/on-create-liquidity-provision.ts
@@ -0,0 +1,28 @@
+import * as functions from 'firebase-functions'
+import { getContract, getUser } from './utils'
+import { createNotification } from './create-notification'
+import { LiquidityProvision } from 'common/liquidity-provision'
+
+export const onCreateLiquidityProvision = functions.firestore
+  .document('contracts/{contractId}/liquidity/{liquidityId}')
+  .onCreate(async (change, context) => {
+    const liquidity = change.data() as LiquidityProvision
+    const { eventId } = context
+    const contract = await getContract(liquidity.contractId)
+
+    if (!contract)
+      throw new Error('Could not find contract corresponding with liquidity')
+
+    const liquidityProvider = await getUser(liquidity.userId)
+    if (!liquidityProvider) throw new Error('Could not find liquidity provider')
+
+    await createNotification(
+      contract.id,
+      'liquidity',
+      'created',
+      liquidityProvider,
+      eventId,
+      liquidity.amount.toString(),
+      contract
+    )
+  })
diff --git a/functions/src/on-update-contract.ts b/functions/src/on-update-contract.ts
index 8b16b3d6..f47c019c 100644
--- a/functions/src/on-update-contract.ts
+++ b/functions/src/on-update-contract.ts
@@ -39,13 +39,26 @@ export const onUpdateContract = functions.firestore
       previousValue.closeTime !== contract.closeTime ||
       previousValue.description !== contract.description
     ) {
+      let sourceText = ''
+      if (previousValue.closeTime !== contract.closeTime && contract.closeTime)
+        sourceText = contract.closeTime.toString()
+      else {
+        const oldTrimmedDescription = previousValue.description.trim()
+        const newTrimmedDescription = contract.description.trim()
+        if (oldTrimmedDescription === '') sourceText = newTrimmedDescription
+        else
+          sourceText = newTrimmedDescription
+            .split(oldTrimmedDescription)[1]
+            .trim()
+      }
+
       await createNotification(
         contract.id,
         'contract',
         'updated',
         contractUpdater,
         eventId,
-        contract.question,
+        sourceText,
         contract
       )
     }
diff --git a/web/pages/notifications.tsx b/web/pages/notifications.tsx
index e4a118e4..8130ed22 100644
--- a/web/pages/notifications.tsx
+++ b/web/pages/notifications.tsx
@@ -44,6 +44,7 @@ import {
 import { getContractFromId } from 'web/lib/firebase/contracts'
 import { CheckIcon, XIcon } from '@heroicons/react/outline'
 import toast from 'react-hot-toast'
+import { formatMoney, formatPercent } from 'common/util/format'
 
 export default function Notifications() {
   const user = useUser()
@@ -565,7 +566,7 @@ function NotificationItem(props: {
       sourceType === 'contract'
     ) {
       try {
-        parseNotificationText(
+        parseOldStyleNotificationText(
           sourceId,
           sourceContractId,
           sourceType,
@@ -619,7 +620,7 @@ function NotificationItem(props: {
     }
   }
 
-  async function parseNotificationText(
+  async function parseOldStyleNotificationText(
     sourceId: string,
     sourceContractId: string,
     sourceType: 'answer' | 'comment' | 'contract',
@@ -772,61 +773,54 @@ function NotificationTextLabel(props: {
   const { contract, className, defaultText, notification, justSummary } = props
   const { sourceUpdateType, sourceType, sourceText, sourceContractTitle } =
     notification
-  if (!contract && !sourceText && sourceType !== 'follow')
-    return