single-pot no-refund payoff; bet selling

This commit is contained in:
mantikoros 2021-12-20 17:35:59 -06:00
parent 1b4dd90ec5
commit 3a43663b89
15 changed files with 150 additions and 137 deletions

View File

@ -2,7 +2,7 @@ import * as admin from 'firebase-admin'
admin.initializeApp() admin.initializeApp()
export * from './keep-awake' // export * from './keep-awake'
export * from './place-bet' export * from './place-bet'
export * from './resolve-market' export * from './resolve-market'
export * from './sell-bet' export * from './sell-bet'

View File

@ -43,7 +43,7 @@ export const placeBet = functions.runWith({ minInstances: 1 }).https.onCall(
.collection(`contracts/${contractId}/bets`) .collection(`contracts/${contractId}/bets`)
.doc() .doc()
const { newBet, newPool, newDpmWeights, newBalance } = getNewBetInfo( const { newBet, newPool, newTotalShares, newBalance } = getNewBetInfo(
user, user,
outcome, outcome,
amount, amount,
@ -54,7 +54,7 @@ export const placeBet = functions.runWith({ minInstances: 1 }).https.onCall(
transaction.create(newBetDoc, newBet) transaction.create(newBetDoc, newBet)
transaction.update(contractDoc, { transaction.update(contractDoc, {
pool: newPool, pool: newPool,
dpmWeights: newDpmWeights, totalShares: newTotalShares,
}) })
transaction.update(userDoc, { balance: newBalance }) transaction.update(userDoc, { balance: newBalance })
@ -79,29 +79,19 @@ const getNewBetInfo = (
? { YES: yesPool + amount, NO: noPool } ? { YES: yesPool + amount, NO: noPool }
: { YES: yesPool, NO: noPool + amount } : { YES: yesPool, NO: noPool + amount }
const dpmWeight = const shares =
outcome === 'YES' outcome === 'YES'
? (amount * noPool ** 2) / (yesPool ** 2 + amount * yesPool) ? amount + (amount * noPool ** 2) / (yesPool ** 2 + amount * yesPool)
: (amount * yesPool ** 2) / (noPool ** 2 + amount * noPool) : amount + (amount * yesPool ** 2) / (noPool ** 2 + amount * noPool)
const { YES: yesWeight, NO: noWeight } = contract.dpmWeights || { const { YES: yesShares, NO: noShares } = contract.totalShares
YES: 0,
NO: 0,
} // only nesc for old contracts
const newDpmWeights = const newTotalShares =
outcome === 'YES' outcome === 'YES'
? { YES: yesWeight + dpmWeight, NO: noWeight } ? { YES: yesShares + shares, NO: noShares }
: { YES: yesWeight, NO: noWeight + dpmWeight } : { YES: yesShares, NO: noShares + shares }
const probBefore = yesPool ** 2 / (yesPool ** 2 + noPool ** 2) const probBefore = yesPool ** 2 / (yesPool ** 2 + noPool ** 2)
const probAverage =
(amount +
noPool * Math.atan(yesPool / noPool) -
noPool * Math.atan((amount + yesPool) / noPool)) /
amount
const probAfter = newPool.YES ** 2 / (newPool.YES ** 2 + newPool.NO ** 2) const probAfter = newPool.YES ** 2 / (newPool.YES ** 2 + newPool.NO ** 2)
const newBet: Bet = { const newBet: Bet = {
@ -109,15 +99,14 @@ const getNewBetInfo = (
userId: user.id, userId: user.id,
contractId: contract.id, contractId: contract.id,
amount, amount,
dpmWeight, shares,
outcome, outcome,
probBefore, probBefore,
probAverage,
probAfter, probAfter,
createdTime: Date.now(), createdTime: Date.now(),
} }
const newBalance = user.balance - amount const newBalance = user.balance - amount
return { newBet, newPool, newDpmWeights, newBalance } return { newBet, newPool, newTotalShares, newBalance }
} }

View File

@ -78,22 +78,27 @@ export const resolveMarket = functions
const firestore = admin.firestore() const firestore = admin.firestore()
const getPayouts = (outcome: string, contract: Contract, bets: Bet[]) => { const getPayouts = (outcome: string, contract: Contract, bets: Bet[]) => {
const [yesBets, noBets] = _.partition(bets, (bet) => bet.outcome === 'YES') const openBets = bets.filter((b) => !b.isSold && !b.sale)
const [yesBets, noBets] = _.partition(
openBets,
(bet) => bet.outcome === 'YES'
)
const [pool, winningBets] = const startPool = contract.startPool.YES + contract.startPool.NO
const truePool = contract.pool.YES + contract.pool.NO - startPool
const [totalShares, winningBets] =
outcome === 'YES' outcome === 'YES'
? [contract.pool.NO - contract.startPool.NO, yesBets] ? [contract.totalShares.YES, yesBets]
: [contract.pool.YES - contract.startPool.YES, noBets] : [contract.totalShares.NO, noBets]
const finalPool = (1 - PLATFORM_FEE - CREATOR_FEE) * pool const finalPool = (1 - PLATFORM_FEE - CREATOR_FEE) * truePool
const creatorPayout = CREATOR_FEE * pool const creatorPayout = CREATOR_FEE * truePool
console.log('final pool:', finalPool, 'creator fee:', creatorPayout) console.log('final pool:', finalPool, 'creator fee:', creatorPayout)
const sumWeights = _.sumBy(winningBets, (bet) => bet.dpmWeight)
const winnerPayouts = winningBets.map((bet) => ({ const winnerPayouts = winningBets.map((bet) => ({
userId: bet.userId, userId: bet.userId,
payout: bet.amount + (bet.dpmWeight / sumWeights) * finalPool, payout: (bet.shares / totalShares) * finalPool,
})) }))
return winnerPayouts.concat([ return winnerPayouts.concat([

View File

@ -35,23 +35,17 @@ export const sellBet = functions.runWith({ minInstances: 1 }).https.onCall(
const betDoc = firestore.doc(`contracts/${contractId}/bets/${betId}`) const betDoc = firestore.doc(`contracts/${contractId}/bets/${betId}`)
const betSnap = await transaction.get(betDoc) const betSnap = await transaction.get(betDoc)
if (!betSnap.exists) if (!betSnap.exists) return { status: 'error', message: 'Invalid bet' }
return { status: 'error', message: 'Invalid bet' }
const bet = betSnap.data() as Bet const bet = betSnap.data() as Bet
if (bet.isSold) if (bet.isSold) return { status: 'error', message: 'Bet already sold' }
return { status: 'error', message: 'Bet already sold' }
const newBetDoc = firestore const newBetDoc = firestore
.collection(`contracts/${contractId}/bets`) .collection(`contracts/${contractId}/bets`)
.doc() .doc()
const { newBet, newPool, newDpmWeights, newBalance, creatorFee } = getSellBetInfo( const { newBet, newPool, newTotalShares, newBalance, creatorFee } =
user, getSellBetInfo(user, bet, contract, newBetDoc.id)
bet,
contract,
newBetDoc.id
)
const creatorDoc = firestore.doc(`users/${contract.creatorId}`) const creatorDoc = firestore.doc(`users/${contract.creatorId}`)
const creatorSnap = await transaction.get(creatorDoc) const creatorSnap = await transaction.get(creatorDoc)
@ -65,7 +59,7 @@ export const sellBet = functions.runWith({ minInstances: 1 }).https.onCall(
transaction.create(newBetDoc, newBet) transaction.create(newBetDoc, newBet)
transaction.update(contractDoc, { transaction.update(contractDoc, {
pool: newPool, pool: newPool,
dpmWeights: newDpmWeights, totalShares: newTotalShares,
}) })
transaction.update(userDoc, { balance: newBalance }) transaction.update(userDoc, { balance: newBalance })
@ -82,69 +76,86 @@ const getSellBetInfo = (
contract: Contract, contract: Contract,
newBetId: string newBetId: string
) => { ) => {
const { id: betId, amount, dpmWeight, outcome } = bet const { id: betId, amount, shares, outcome } = bet
const { YES: yesPool, NO: noPool } = contract.pool const { YES: yesPool, NO: noPool } = contract.pool
const { YES: yesWeights, NO: noWeights } = contract.dpmWeights const { YES: yesStart, NO: noStart } = contract.startPool
const { YES: yesShares, NO: noShares } = contract.totalShares
// average implied probability after selling bet position const [y, n, s] = [yesPool, noPool, shares]
const p = outcome === 'YES'
? (amount +
noPool * Math.atan((yesPool - amount) / noPool) -
noPool * Math.atan(yesPool / noPool)) /
amount
: yesPool * (Math.atan((amount - noPool) / yesPool) + Math.atan(noPool / yesPool)) / const shareValue =
amount
const [sellYesAmount, sellNoAmount] = outcome === 'YES'
? [
p * amount,
p * dpmWeight / yesWeights * noPool,
]
: [
p * dpmWeight / noWeights * yesPool,
p * amount,
]
const newPool = { YES: yesPool - sellYesAmount, NO: noPool - sellNoAmount }
const newDpmWeights =
outcome === 'YES' outcome === 'YES'
? { YES: yesWeights - dpmWeight, NO: noWeights } ? // https://www.wolframalpha.com/input/?i=b+%2B+%28b+n%5E2%29%2F%28y+%28-b+%2B+y%29%29+%3D+c+solve+b
: { YES: yesWeights, NO: noWeights - dpmWeight } (n ** 2 +
s * y +
y ** 2 -
Math.sqrt(
n ** 4 + (s - y) ** 2 * y ** 2 + 2 * n ** 2 * y * (s + y)
)) /
(2 * y)
: (y ** 2 +
s * n +
n ** 2 -
Math.sqrt(
y ** 4 + (s - n) ** 2 * n ** 2 + 2 * y ** 2 * n * (s + n)
)) /
(2 * n)
const startPool = yesStart + noStart
const pool = yesPool + noPool - startPool
const f = outcome === 'YES' ? pool / yesShares : pool / noShares
const myPool = outcome === 'YES' ? yesPool - yesStart : noPool - noStart
const adjShareValue = Math.min(Math.min(1, f) * shareValue, myPool)
const newPool =
outcome === 'YES'
? { YES: yesPool - adjShareValue, NO: noPool }
: { YES: yesPool, NO: noPool - adjShareValue }
const newTotalShares =
outcome === 'YES'
? { YES: yesShares - shares, NO: noShares }
: { YES: yesShares, NO: noShares - shares }
const probBefore = yesPool ** 2 / (yesPool ** 2 + noPool ** 2) const probBefore = yesPool ** 2 / (yesPool ** 2 + noPool ** 2)
const probAverage = p
const probAfter = newPool.YES ** 2 / (newPool.YES ** 2 + newPool.NO ** 2) const probAfter = newPool.YES ** 2 / (newPool.YES ** 2 + newPool.NO ** 2)
const keep = 1 - CREATOR_FEE - PLATFORM_FEE const creatorFee = CREATOR_FEE * adjShareValue
const saleAmount = (1 - CREATOR_FEE - PLATFORM_FEE) * adjShareValue
const [saleAmount, creatorFee] = outcome === 'YES' console.log(
? [{ YES: sellYesAmount, NO: keep * sellNoAmount }, CREATOR_FEE * sellNoAmount] 'SELL M$',
: [{ YES: keep * sellYesAmount, NO: sellNoAmount }, CREATOR_FEE * sellYesAmount] amount,
outcome,
console.log('SELL M$', amount, outcome, 'at', p, 'prob', 'for M$', saleAmount.YES + saleAmount.NO, 'creator fee: M$', creatorFee) 'for M$',
saleAmount,
'M$/share:',
f,
'creator fee: M$',
creatorFee
)
const newBet: Bet = { const newBet: Bet = {
id: newBetId, id: newBetId,
userId: user.id, userId: user.id,
contractId: contract.id, contractId: contract.id,
amount: -amount, amount: -adjShareValue,
dpmWeight: -dpmWeight, shares: -shares,
outcome, outcome,
probBefore, probBefore,
probAverage,
probAfter, probAfter,
createdTime: Date.now(), createdTime: Date.now(),
sale: { sale: {
amount: saleAmount, amount: saleAmount,
betId betId,
} },
} }
const newBalance = user.balance + sellYesAmount + sellNoAmount const newBalance = user.balance + saleAmount
return { newBet, newPool, newDpmWeights, newBalance, creatorFee } return { newBet, newPool, newTotalShares, newBalance, creatorFee }
} }

View File

@ -5,14 +5,13 @@ export type Bet = {
amount: number // bet size; negative if SELL bet amount: number // bet size; negative if SELL bet
outcome: 'YES' | 'NO' outcome: 'YES' | 'NO'
dpmWeight: number // dynamic parimutuel pool weight; negative if SELL bet shares: number // dynamic parimutuel pool weight; negative if SELL bet
probBefore: number probBefore: number
probAverage: number
probAfter: number probAfter: number
sale?: { sale?: {
amount: { YES: number, NO: number } // amount user makes from YES and NO pools from sale amount: number // amount user makes from sale
betId: string // id of bet being sold betId: string // id of bet being sold
} }

View File

@ -12,7 +12,7 @@ export type Contract = {
startPool: { YES: number; NO: number } startPool: { YES: number; NO: number }
pool: { YES: number; NO: number } pool: { YES: number; NO: number }
dpmWeights: { YES: number; NO: number } totalShares: { YES: number; NO: number }
createdTime: number // Milliseconds since epoch createdTime: number // Milliseconds since epoch
lastUpdatedTime: number // If the question or description was changed lastUpdatedTime: number // If the question or description was changed

View File

@ -12,7 +12,7 @@ import { formatMoney, formatPercent } from '../lib/util/format'
import { Title } from './title' import { Title } from './title'
import { import {
getProbability, getProbability,
getDpmWeight, calculateShares,
getProbabilityAfterBet, getProbabilityAfterBet,
} from '../lib/calculation/contract' } from '../lib/calculation/contract'
import { firebaseLogin } from '../lib/firebase/users' import { firebaseLogin } from '../lib/firebase/users'
@ -84,9 +84,9 @@ export function BetPanel(props: { contract: Contract; className?: string }) {
betChoice, betChoice,
betAmount ?? 0 betAmount ?? 0
) )
const dpmWeight = getDpmWeight(contract.pool, betAmount ?? 0, betChoice) const shares = calculateShares(contract.pool, betAmount ?? 0, betChoice)
const estimatedWinnings = Math.floor((betAmount ?? 0) + dpmWeight) const estimatedWinnings = Math.floor(shares)
const estimatedReturn = betAmount const estimatedReturn = betAmount
? (estimatedWinnings - betAmount) / betAmount ? (estimatedWinnings - betAmount) / betAmount
: 0 : 0

View File

@ -257,7 +257,16 @@ export function ContractBetsTable(props: {
function BetRow(props: { bet: Bet; contract: Contract }) { function BetRow(props: { bet: Bet; contract: Contract }) {
const { bet, contract } = props const { bet, contract } = props
const { amount, outcome, createdTime, probBefore, probAfter, dpmWeight, sale, isSold } = bet const {
amount,
outcome,
createdTime,
probBefore,
probAfter,
shares,
sale,
isSold,
} = bet
const { isResolved } = contract const { isResolved } = contract
return ( return (
@ -270,7 +279,7 @@ function BetRow(props: { bet: Bet; contract: Contract }) {
<td> <td>
{formatPercent(probBefore)} {formatPercent(probAfter)} {formatPercent(probBefore)} {formatPercent(probAfter)}
</td> </td>
{!isResolved && <td>{formatMoney(amount + dpmWeight)}</td>} {!isResolved && <td>{formatMoney(shares)}</td>}
<td> <td>
{formatMoney( {formatMoney(
isResolved isResolved
@ -279,14 +288,19 @@ function BetRow(props: { bet: Bet; contract: Contract }) {
)} )}
</td> </td>
{!isResolved && !sale && !isSold && {!isResolved && !sale && !isSold && (
<td> <td>
<button className='btn' onClick={async e => { <button
e.preventDefault() className="btn"
await sellBet({ contractId: contract.id, betId: bet.id }) onClick={async (e) => {
}}>Sell</button> e.preventDefault()
await sellBet({ contractId: contract.id, betId: bet.id })
}}
>
Sell
</button>
</td> </td>
} )}
</tr> </tr>
) )
} }

View File

@ -90,7 +90,7 @@ export const ContractOverview = (props: {
}) => { }) => {
const { contract, className } = props const { contract, className } = props
const { resolution, creatorId } = contract const { resolution, creatorId } = contract
const { probPercent, volume } = compute(contract) const { probPercent, truePool } = compute(contract)
const user = useUser() const user = useUser()
const isCreator = user?.id === creatorId const isCreator = user?.id === creatorId
@ -140,7 +140,7 @@ export const ContractOverview = (props: {
<ContractDescription contract={contract} isCreator={isCreator} /> <ContractDescription contract={contract} isCreator={isCreator} />
{/* Show a delete button for contracts without any trading */} {/* Show a delete button for contracts without any trading */}
{isCreator && volume === 0 && ( {isCreator && truePool === 0 && (
<> <>
<Spacer h={8} /> <Spacer h={8} />
<button <button

View File

@ -17,7 +17,7 @@ import { Linkify } from './linkify'
export function ContractDetails(props: { contract: Contract }) { export function ContractDetails(props: { contract: Contract }) {
const { contract } = props const { contract } = props
const { volume, createdDate, resolvedDate } = compute(contract) const { truePool, createdDate, resolvedDate } = compute(contract)
return ( return (
<Row className="flex-wrap text-sm text-gray-500"> <Row className="flex-wrap text-sm text-gray-500">
@ -29,7 +29,7 @@ export function ContractDetails(props: { contract: Contract }) {
{resolvedDate ? `${createdDate} - ${resolvedDate}` : createdDate} {resolvedDate ? `${createdDate} - ${resolvedDate}` : createdDate}
</div> </div>
<div className="mx-2"></div> <div className="mx-2"></div>
<div className="whitespace-nowrap">{formatMoney(volume)} volume</div> <div className="whitespace-nowrap">{formatMoney(truePool)} pool</div>
</Row> </Row>
) )
} }
@ -110,14 +110,14 @@ function ContractsGrid(props: { contracts: Contract[] }) {
) )
} }
type Sort = 'createdTime' | 'volume' | 'resolved' | 'all' type Sort = 'createdTime' | 'pool' | 'resolved' | 'all'
export function SearchableGrid(props: { export function SearchableGrid(props: {
contracts: Contract[] contracts: Contract[]
defaultSort?: Sort defaultSort?: Sort
}) { }) {
const { contracts, defaultSort } = props const { contracts, defaultSort } = props
const [query, setQuery] = useState('') const [query, setQuery] = useState('')
const [sort, setSort] = useState(defaultSort || 'volume') const [sort, setSort] = useState(defaultSort || 'pool')
function check(corpus: String) { function check(corpus: String) {
return corpus.toLowerCase().includes(query.toLowerCase()) return corpus.toLowerCase().includes(query.toLowerCase())
@ -132,8 +132,8 @@ export function SearchableGrid(props: {
if (sort === 'createdTime' || sort === 'resolved' || sort === 'all') { if (sort === 'createdTime' || sort === 'resolved' || sort === 'all') {
matches.sort((a, b) => b.createdTime - a.createdTime) matches.sort((a, b) => b.createdTime - a.createdTime)
} else if (sort === 'volume') { } else if (sort === 'pool') {
matches.sort((a, b) => compute(b).volume - compute(a).volume) matches.sort((a, b) => compute(b).truePool - compute(a).truePool)
} }
if (sort !== 'all') { if (sort !== 'all') {
@ -159,7 +159,7 @@ export function SearchableGrid(props: {
value={sort} value={sort}
onChange={(e) => setSort(e.target.value as Sort)} onChange={(e) => setSort(e.target.value as Sort)}
> >
<option value="volume">Most traded</option> <option value="pool">Most traded</option>
<option value="createdTime">Newest first</option> <option value="createdTime">Newest first</option>
<option value="resolved">Resolved</option> <option value="resolved">Resolved</option>
<option value="all">All markets</option> <option value="all">All markets</option>

View File

@ -22,7 +22,7 @@ export function getProbabilityAfterBet(
return getProbability({ YES, NO }) return getProbability({ YES, NO })
} }
export function getDpmWeight( export function calculateShares(
pool: { YES: number; NO: number }, pool: { YES: number; NO: number },
bet: number, bet: number,
betChoice: 'YES' | 'NO' betChoice: 'YES' | 'NO'
@ -30,8 +30,8 @@ export function getDpmWeight(
const [yesPool, noPool] = [pool.YES, pool.NO] const [yesPool, noPool] = [pool.YES, pool.NO]
return betChoice === 'YES' return betChoice === 'YES'
? (bet * Math.pow(noPool, 2)) / (Math.pow(yesPool, 2) + bet * yesPool) ? bet + (bet * noPool ** 2) / (yesPool ** 2 + bet * yesPool)
: (bet * Math.pow(yesPool, 2)) / (Math.pow(noPool, 2) + bet * noPool) : bet + (bet * yesPool ** 2) / (noPool ** 2 + bet * noPool)
} }
export function calculatePayout( export function calculatePayout(
@ -39,23 +39,20 @@ export function calculatePayout(
bet: Bet, bet: Bet,
outcome: 'YES' | 'NO' | 'CANCEL' outcome: 'YES' | 'NO' | 'CANCEL'
) { ) {
const { amount, outcome: betOutcome, dpmWeight } = bet const { amount, outcome: betOutcome, shares } = bet
if (outcome === 'CANCEL') return amount if (outcome === 'CANCEL') return amount
if (betOutcome !== outcome) return 0 if (betOutcome !== outcome) return 0
let { dpmWeights, pool, startPool } = contract let { totalShares } = contract
// Fake data if not set. // Fake data if not set.
if (!dpmWeights) dpmWeights = { YES: 100, NO: 100 } // if (!totalShares) totalShares = { YES: 100, NO: 100 }
// Fake data if not set. const startPool = contract.startPool.YES + contract.startPool.NO
if (!pool) pool = { YES: 100, NO: 100 } const pool = contract.pool.YES + contract.pool.NO - startPool
const otherOutcome = outcome === 'YES' ? 'NO' : 'YES' return (1 - fees) * (shares / totalShares[outcome]) * pool
const poolSize = pool[otherOutcome] - startPool[otherOutcome]
return (1 - fees) * (dpmWeight / dpmWeights[outcome]) * poolSize + amount
} }
export function resolvedPayout(contract: Contract, bet: Bet) { export function resolvedPayout(contract: Contract, bet: Bet) {
if (contract.resolution) if (contract.resolution)

View File

@ -14,14 +14,13 @@ export type Bet = {
amount: number // bet size; negative if SELL bet amount: number // bet size; negative if SELL bet
outcome: 'YES' | 'NO' outcome: 'YES' | 'NO'
dpmWeight: number // dynamic parimutuel pool weight; negative if SELL bet shares: number // dynamic parimutuel pool weight; negative if SELL bet
probBefore: number probBefore: number
probAverage: number
probAfter: number probAfter: number
sale?: { sale?: {
amount: { YES: number, NO: number } // amount user makes from YES and NO pools from sale amount: number // amount user makes from sale
betId: string // id of bet being sold betId: string // id of bet being sold
} }

View File

@ -30,7 +30,7 @@ export type Contract = {
startPool: { YES: number; NO: number } startPool: { YES: number; NO: number }
pool: { YES: number; NO: number } pool: { YES: number; NO: number }
dpmWeights: { YES: number; NO: number } totalShares: { YES: number; NO: number }
createdTime: number // Milliseconds since epoch createdTime: number // Milliseconds since epoch
lastUpdatedTime: number // If the question or description was changed lastUpdatedTime: number // If the question or description was changed
@ -48,14 +48,14 @@ export function path(contract: Contract) {
export function compute(contract: Contract) { export function compute(contract: Contract) {
const { pool, startPool, createdTime, resolutionTime, isResolved } = contract const { pool, startPool, createdTime, resolutionTime, isResolved } = contract
const volume = pool.YES + pool.NO - startPool.YES - startPool.NO const truePool = pool.YES + pool.NO - startPool.YES - startPool.NO
const prob = pool.YES ** 2 / (pool.YES ** 2 + pool.NO ** 2) const prob = pool.YES ** 2 / (pool.YES ** 2 + pool.NO ** 2)
const probPercent = Math.round(prob * 100) + '%' const probPercent = Math.round(prob * 100) + '%'
const createdDate = dayjs(createdTime).format('MMM D') const createdDate = dayjs(createdTime).format('MMM D')
const resolvedDate = isResolved const resolvedDate = isResolved
? dayjs(resolutionTime).format('MMM D') ? dayjs(resolutionTime).format('MMM D')
: undefined : undefined
return { volume, probPercent, createdDate, resolvedDate } return { truePool, probPercent, createdDate, resolvedDate }
} }
const db = getFirestore(app) const db = getFirestore(app)

View File

@ -2,7 +2,6 @@ import {
Contract, Contract,
getContractFromSlug, getContractFromSlug,
pushNewContract, pushNewContract,
setContract,
} from '../firebase/contracts' } from '../firebase/contracts'
import { User } from '../firebase/users' import { User } from '../firebase/users'
import { randomString } from '../util/random-string' import { randomString } from '../util/random-string'
@ -38,7 +37,7 @@ export async function createContract(
startPool: { YES: startYes, NO: startNo }, startPool: { YES: startYes, NO: startNo },
pool: { YES: startYes, NO: startNo }, pool: { YES: startYes, NO: startNo },
dpmWeights: { YES: 0, NO: 0 }, totalShares: { YES: 0, NO: 0 },
isResolved: false, isResolved: false,
// TODO: Set create time to Firestore timestamp // TODO: Set create time to Firestore timestamp
@ -49,8 +48,8 @@ export async function createContract(
return await pushNewContract(contract) return await pushNewContract(contract)
} }
export function calcStartPool(initialProb: number, initialCapital = 200) { export function calcStartPool(initialProbInt: number, initialCapital = 200) {
const p = initialProb / 100.0 const p = initialProbInt / 100.0
const startYes = const startYes =
p === 0.5 p === 0.5

View File

@ -162,8 +162,8 @@ function Contents() {
</p> </p>
<h3 id="how-are-markets-resolved-">How are markets resolved?</h3> <h3 id="how-are-markets-resolved-">How are markets resolved?</h3>
<p> <p>
The creator of the prediction market decides the outcome and earns 0.5% The creator of the prediction market decides the outcome and earns 1% of
of the trade volume for their effort. the betting pool for their effort.
</p> </p>
<p> <p>
This simple resolution mechanism has surprising benefits in allowing a This simple resolution mechanism has surprising benefits in allowing a