From a32bb57167f5e44510fb547df2ec3a42b72245e1 Mon Sep 17 00:00:00 2001
From: Austin Chen 
Date: Mon, 7 Mar 2022 10:40:53 -0800
Subject: [PATCH 1/3] Update about page
---
 web/pages/about.tsx | 117 +++++++++++++++++++++++++++-----------------
 1 file changed, 71 insertions(+), 46 deletions(-)
diff --git a/web/pages/about.tsx b/web/pages/about.tsx
index 85e3eaee..3f0fcead 100644
--- a/web/pages/about.tsx
+++ b/web/pages/about.tsx
@@ -118,6 +118,13 @@ function Contents() {
           
         
       
+      
+        More questions? Check out{' '}
+        
+          this community-driven FAQ
+        
+        !
+      
       
         Can prediction markets work without real money?
       
@@ -148,6 +155,40 @@ function Contents() {
         
         .
       
+
+      Why is this important?
+      
+        Prediction markets aggregate and reveal crucial information that would
+        not otherwise be known. They are a bottom-up mechanism that can
+        influence everything from politics, economics, and business, to
+        scientific research and education.
+      
+      
+        Prediction markets can predict{' '}
+        
+          which research papers will replicate
+        
+        ; which drug is the most effective; which policy would generate the most
+        tax revenue; which charity will be underfunded; or which startup idea is
+        the most promising. By surfacing and quantifying our collective
+        knowledge, we as a society become wiser.
+      
+
+      How does betting work?
+      
+        - Markets are structured around a question with a binary outcome.
 
+        - 
+          Traders can place a bet on either YES or NO. The trader receives some
+          shares of the betting pool. The number of shares depends on the
+          current probability.
+        
 
+        - 
+          When the market is resolved, the traders who bet on the correct
+          outcome are paid out of the final pool in proportion to the number of
+          shares they own.
+        
 
+      
+
       How are markets resolved?
       
         The creator of the prediction market decides the outcome and earns{' '}
@@ -166,29 +207,9 @@ function Contents() {
         or even personal. (E.g. "Will I enjoy participating in the
         Metaverse in 2023?")
       
-      Why is this important?
-      
-        Prediction markets aggregate and reveal crucial information that would
-        not otherwise be known. They are a bottom-up mechanism that can
-        influence everything from politics, economics, and business, to
-        scientific research and education.
-      
-      
-        Prediction markets can predict{' '}
-        
-          which research papers will replicate
-        
-        ; which drug is the most effective; which policy would generate the most
-        tax revenue; which charity will be underfunded; or, which startup idea
-        is the most promising.
-      
-      
-        By surfacing and quantifying our collective knowledge, we as a society
-        become wiser.
-      
-       */}
       {/* 
         We believe that in order to get the best results, you have to have skin
         in the game. We require that people use real money to buy the currency
@@ -199,28 +220,13 @@ function Contents() {
         carefully and can't rig the outcome by creating multiple accounts.
         The result is more accurate predictions.
       
 */}
-      
+      {/* 
         Manifold Markets is focused on accessibility and allowing anyone to
         quickly create and judge a prediction market. When we all have the power
         to create and share prediction markets in seconds and apply our own
         judgment on the outcome, it leads to a qualitative shift in the number,
         variety, and usefulness of prediction markets.
-      
-
-      How does betting work?
-      
-        - Markets are structured around a question with a binary outcome.
 
-        - 
-          Traders can place a bet on either YES or NO. The trader receives some
-          shares of the betting pool. The number of shares depends on the
-          current probability.
-        
 
-        - 
-          When the market is resolved, the traders who bet on the correct
-          outcome are paid out of the final pool in proportion to the number of
-          shares they own.
-        
 
-      
+       */}
 
       What kind of betting system do you use?
       
@@ -249,6 +255,20 @@ function Contents() {
         to find out more!
       
 
+      Can I create private markets?
+      
+        Soon! We're running a pilot version of Manifold for Teams - private
+        Manifold instances where you can discuss internal topics and predict on
+        outcomes for your organization.
+      
+      
+        If this sounds like something you’d want,{' '}
+        
+          join the waitlist here
+        
+        !
+      
+
       Who are we?
       Manifold Markets is currently a team of three:
       
@@ -296,19 +316,24 @@ function Contents() {
       Further Reading
 
       
From ff92338873ff63e072fbec2146eb925dcac2085b Mon Sep 17 00:00:00 2001
From: James Grugett 
Date: Mon, 7 Mar 2022 13:14:56 -0800
Subject: [PATCH 2/3] Fix multi payout calculation!
---
 common/payouts.ts | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/common/payouts.ts b/common/payouts.ts
index 446b75d7..ab7f00af 100644
--- a/common/payouts.ts
+++ b/common/payouts.ts
@@ -138,8 +138,7 @@ export const getPayoutsMultiOutcome = (
     const prob = resolutions[outcome] / probTotal
     const winnings = (shares / sharesByOutcome[outcome]) * prob * poolTotal
     const profit = winnings - amount
-
-    const payout = amount + (1 - FEES) * Math.max(0, profit)
+    const payout = deductFees(amount, winnings)
     return { userId, profit, payout }
   })
 
From fe98a61e435bc092e144e68b06ba57cb73da5617 Mon Sep 17 00:00:00 2001
From: James Grugett 
Date: Mon, 7 Mar 2022 13:45:56 -0800
Subject: [PATCH 3/3] Fix leaderboard out of memory error with batchedWaitAll
 instead of Promise.all
---
 common/util/promise.ts                   | 18 ++++++++++++++++++
 functions/src/update-contract-metrics.ts |  5 +++--
 functions/src/update-user-metrics.ts     |  5 +++--
 3 files changed, 24 insertions(+), 4 deletions(-)
 create mode 100644 common/util/promise.ts
diff --git a/common/util/promise.ts b/common/util/promise.ts
new file mode 100644
index 00000000..33db339c
--- /dev/null
+++ b/common/util/promise.ts
@@ -0,0 +1,18 @@
+export const batchedWaitAll = async (
+  createPromises: (() => Promise)[],
+  batchSize = 10
+) => {
+  const numBatches = Math.ceil(createPromises.length / batchSize)
+  const result: T[] = []
+  for (let batchIndex = 0; batchIndex < numBatches; batchIndex++) {
+    const from = batchIndex * batchSize
+    const to = from + batchSize
+
+    const promises = createPromises.slice(from, to).map((f) => f())
+
+    const batch = await Promise.all(promises)
+    result.push(...batch)
+  }
+
+  return result
+}
diff --git a/functions/src/update-contract-metrics.ts b/functions/src/update-contract-metrics.ts
index 3646e7ad..d203ee99 100644
--- a/functions/src/update-contract-metrics.ts
+++ b/functions/src/update-contract-metrics.ts
@@ -5,6 +5,7 @@ import * as _ from 'lodash'
 import { getValues } from './utils'
 import { Contract } from '../../common/contract'
 import { Bet } from '../../common/bet'
+import { batchedWaitAll } from '../../common/util/promise'
 
 const firestore = admin.firestore()
 
@@ -17,8 +18,8 @@ export const updateContractMetrics = functions.pubsub
       firestore.collection('contracts')
     )
 
-    await Promise.all(
-      contracts.map(async (contract) => {
+    await batchedWaitAll(
+      contracts.map((contract) => async () => {
         const volume24Hours = await computeVolumeFrom(contract, oneDay)
         const volume7Days = await computeVolumeFrom(contract, oneDay * 7)
 
diff --git a/functions/src/update-user-metrics.ts b/functions/src/update-user-metrics.ts
index d1d13727..358dd936 100644
--- a/functions/src/update-user-metrics.ts
+++ b/functions/src/update-user-metrics.ts
@@ -7,6 +7,7 @@ import { Contract } from '../../common/contract'
 import { Bet } from '../../common/bet'
 import { User } from '../../common/user'
 import { calculatePayout } from '../../common/calculate'
+import { batchedWaitAll } from '../../common/util/promise'
 
 const firestore = admin.firestore()
 
@@ -22,8 +23,8 @@ export const updateUserMetrics = functions.pubsub
       contracts.map((contract) => [contract.id, contract])
     )
 
-    await Promise.all(
-      users.map(async (user) => {
+    await batchedWaitAll(
+      users.map((user) => async () => {
         const [investmentValue, creatorVolume] = await Promise.all([
           computeInvestmentValue(user, contractsDict),
           computeTotalPool(user, contractsDict),