Fill in more of placebet
This commit is contained in:
parent
53e2ff7327
commit
fe0b26669a
|
@ -37,17 +37,19 @@ export type BetInfo = {
|
|||
const computeFill = (
|
||||
betAmount: number,
|
||||
outcome: 'YES' | 'NO',
|
||||
limitProb: number,
|
||||
limitProb: number | undefined,
|
||||
cpmmState: CpmmState,
|
||||
matchedBet: LimitBet
|
||||
) => {
|
||||
const prob = getCpmmProbability(cpmmState.pool, cpmmState.p)
|
||||
|
||||
if (
|
||||
outcome === 'YES'
|
||||
limitProb !== undefined &&
|
||||
(outcome === 'YES'
|
||||
? Math.min(prob, matchedBet.limitProb) > limitProb
|
||||
: Math.max(prob, matchedBet.limitProb) < limitProb
|
||||
: Math.max(prob, matchedBet.limitProb) < limitProb)
|
||||
) {
|
||||
// No fill.
|
||||
return undefined
|
||||
}
|
||||
|
||||
|
@ -59,20 +61,19 @@ const computeFill = (
|
|||
// Fill from pool.
|
||||
const limit =
|
||||
outcome === 'YES'
|
||||
? Math.min(matchedBet.limitProb, limitProb)
|
||||
: Math.max(matchedBet.limitProb, limitProb)
|
||||
const amount = calculateCpmmAmount(cpmmState, limit, 'YES')
|
||||
? Math.min(matchedBet.limitProb, limitProb ?? Infinity)
|
||||
: Math.max(matchedBet.limitProb, limitProb ?? -Infinity)
|
||||
const amount = calculateCpmmAmount(cpmmState, limit, outcome)
|
||||
|
||||
const { shares, newPool, newP, fees } = calculateCpmmPurchase(
|
||||
cpmmState,
|
||||
amount,
|
||||
'YES'
|
||||
outcome
|
||||
)
|
||||
const newState = { pool: newPool, p: newP }
|
||||
|
||||
return {
|
||||
maker: {
|
||||
betId: 'bet',
|
||||
matchedBetId: null,
|
||||
shares,
|
||||
amount,
|
||||
|
@ -80,7 +81,6 @@ const computeFill = (
|
|||
fees,
|
||||
},
|
||||
taker: {
|
||||
betId: 'bet',
|
||||
matchedBetId: null,
|
||||
shares,
|
||||
amount,
|
||||
|
@ -88,17 +88,16 @@ const computeFill = (
|
|||
}
|
||||
}
|
||||
|
||||
// Fill from bet.
|
||||
// Fill from matchedBet.
|
||||
const amount = Math.min(betAmount, matchedBet.amount)
|
||||
const shares = matchedBet.shares * (amount / matchedBet.amount)
|
||||
const maker = {
|
||||
betId: matchedBet.id,
|
||||
matchedBetId: 'bet',
|
||||
bet: matchedBet,
|
||||
matchedBetId: 'taker',
|
||||
amount,
|
||||
shares,
|
||||
}
|
||||
const taker = {
|
||||
betId: 'bet',
|
||||
matchedBetId: matchedBet.id,
|
||||
amount,
|
||||
shares,
|
||||
|
@ -106,20 +105,33 @@ const computeFill = (
|
|||
return { maker, taker }
|
||||
}
|
||||
|
||||
export const getBinaryCpmmLimitBetInfo = (
|
||||
export const getBinaryCpmmBetInfo = (
|
||||
outcome: 'YES' | 'NO',
|
||||
betAmount: number,
|
||||
contract: CPMMBinaryContract,
|
||||
limitProb: number,
|
||||
limitProb: number | undefined,
|
||||
unfilledBets: LimitBet[] // Sorted by limitProb, createdTime
|
||||
) => {
|
||||
const fills: LimitBet['fills'] = []
|
||||
const takers: {
|
||||
matchedBetId: string | null
|
||||
amount: number
|
||||
shares: number
|
||||
}[] = []
|
||||
const makers: { bet: LimitBet; amount: number; shares: number }[] = []
|
||||
|
||||
let cpmmState = { pool: contract.pool, p: contract.p }
|
||||
let totalFees = noFees
|
||||
|
||||
for (const bet of unfilledBets) {
|
||||
const fill = computeFill(betAmount, outcome, limitProb, cpmmState, bet)
|
||||
let i = 0
|
||||
while (i < unfilledBets.length) {
|
||||
const matchedBet = unfilledBets[i]
|
||||
const fill = computeFill(
|
||||
betAmount,
|
||||
outcome,
|
||||
limitProb,
|
||||
cpmmState,
|
||||
matchedBet
|
||||
)
|
||||
if (!fill) break
|
||||
|
||||
const { maker, taker } = fill
|
||||
|
@ -130,12 +142,43 @@ export const getBinaryCpmmLimitBetInfo = (
|
|||
cpmmState = maker.state
|
||||
totalFees = addObjects(totalFees, maker.fees)
|
||||
} else {
|
||||
fills.push(maker)
|
||||
makers.push(maker)
|
||||
i++
|
||||
}
|
||||
fills.push(taker)
|
||||
takers.push(taker)
|
||||
}
|
||||
|
||||
return { fills, cpmmState, totalFees }
|
||||
const probBefore = getCpmmProbability(contract.pool, contract.p)
|
||||
const probAfter = getCpmmProbability(cpmmState.pool, cpmmState.p)
|
||||
|
||||
const takerAmount = sumBy(takers, 'amount')
|
||||
const takerShares = sumBy(takers, 'shares')
|
||||
const isFilled = Math.abs(betAmount - takerAmount) < 0.000000001
|
||||
|
||||
const newBet = {
|
||||
amount: betAmount,
|
||||
isFilled,
|
||||
fills: takers,
|
||||
contractId: contract.id,
|
||||
shares: takerShares,
|
||||
outcome,
|
||||
probBefore,
|
||||
probAfter,
|
||||
loanAmount: 0,
|
||||
createdTime: Date.now(),
|
||||
fees: totalFees,
|
||||
}
|
||||
|
||||
const { liquidityFee } = totalFees
|
||||
const newTotalLiquidity = (contract.totalLiquidity ?? 0) + liquidityFee
|
||||
|
||||
return {
|
||||
newBet,
|
||||
newPool: cpmmState.pool,
|
||||
newP: cpmmState.p,
|
||||
newTotalLiquidity,
|
||||
makers,
|
||||
}
|
||||
}
|
||||
|
||||
export const getNewBinaryCpmmBetInfo = (
|
||||
|
|
|
@ -6,8 +6,7 @@ import { Contract, CPMM_MIN_POOL_QTY } from '../../common/contract'
|
|||
import { User } from '../../common/user'
|
||||
import {
|
||||
BetInfo,
|
||||
getBinaryCpmmLimitBetInfo,
|
||||
getNewBinaryCpmmBetInfo,
|
||||
getBinaryCpmmBetInfo,
|
||||
getNewBinaryDpmBetInfo,
|
||||
getNewMultiBetInfo,
|
||||
getNumericBetsInfo,
|
||||
|
@ -17,6 +16,7 @@ import { redeemShares } from './redeem-shares'
|
|||
import { log } from './utils'
|
||||
import { LimitBet } from 'common/bet'
|
||||
import { Query } from 'firebase-admin/firestore'
|
||||
import { sumBy } from 'lodash'
|
||||
|
||||
const bodySchema = z.object({
|
||||
contractId: z.string(),
|
||||
|
@ -70,18 +70,28 @@ export const placebet = newEndpoint(['POST'], async (req, auth) => {
|
|||
newTotalBets,
|
||||
newTotalLiquidity,
|
||||
newP,
|
||||
} = await (async (): Promise<BetInfo> => {
|
||||
makers,
|
||||
} = await (async (): Promise<
|
||||
BetInfo & {
|
||||
makers?: {
|
||||
bet: LimitBet
|
||||
amount: number
|
||||
shares: number
|
||||
}[]
|
||||
}
|
||||
> => {
|
||||
if (outcomeType == 'BINARY' && mechanism == 'dpm-2') {
|
||||
const { outcome } = validate(binarySchema, req.body)
|
||||
return getNewBinaryDpmBetInfo(outcome, amount, contract, loanAmount)
|
||||
} else if (outcomeType == 'BINARY' && mechanism == 'cpmm-1') {
|
||||
const { outcome, limitProb } = validate(binarySchema, req.body)
|
||||
const boundedLimitProb = limitProb ?? (outcome === 'YES' ? 1 : 0)
|
||||
const unfilledBetsQuery = contractDoc
|
||||
.collection('bets')
|
||||
.where('outcome', '==', outcome === 'YES' ? 'NO' : 'YES')
|
||||
.where('isFilled', '==', false)
|
||||
.where('isCancelled', '==', false)
|
||||
.where('limitProb', outcome === 'YES' ? '<=' : '>=', limitProb)
|
||||
.where('limitProb', outcome === 'YES' ? '<=' : '>=', boundedLimitProb)
|
||||
.orderBy('createdTime', 'desc')
|
||||
.orderBy(
|
||||
'limitProb',
|
||||
|
@ -91,16 +101,13 @@ export const placebet = newEndpoint(['POST'], async (req, auth) => {
|
|||
const unfilledBetsSnap = await trans.get(unfilledBetsQuery)
|
||||
const unfilledBets = unfilledBetsSnap.docs.map((doc) => doc.data())
|
||||
|
||||
if (limitProb !== undefined) {
|
||||
getBinaryCpmmLimitBetInfo(
|
||||
outcome,
|
||||
amount,
|
||||
contract,
|
||||
limitProb,
|
||||
unfilledBets,
|
||||
)
|
||||
}
|
||||
return getNewBinaryCpmmBetInfo(outcome, amount, contract, loanAmount)
|
||||
return getBinaryCpmmBetInfo(
|
||||
outcome,
|
||||
amount,
|
||||
contract,
|
||||
limitProb,
|
||||
unfilledBets
|
||||
)
|
||||
} else if (outcomeType == 'FREE_RESPONSE' && mechanism == 'dpm-2') {
|
||||
const { outcome } = validate(freeResponseSchema, req.body)
|
||||
const answerDoc = contractDoc.collection('answers').doc(outcome)
|
||||
|
@ -129,6 +136,25 @@ export const placebet = newEndpoint(['POST'], async (req, auth) => {
|
|||
const betDoc = contractDoc.collection('bets').doc()
|
||||
trans.create(betDoc, { id: betDoc.id, userId: user.id, ...newBet })
|
||||
log('Created new bet document.')
|
||||
|
||||
if (makers) {
|
||||
for (const maker of makers) {
|
||||
const { bet, amount, shares } = maker
|
||||
const newFill = { amount, shares, matchedBetId: betDoc.id }
|
||||
const fills = [...bet.fills, newFill]
|
||||
const totalShares = sumBy(fills, 'shares')
|
||||
const isFilled =
|
||||
Math.abs(sumBy(fills, 'amount') - bet.amount) < 0.0000001
|
||||
|
||||
log('Updated a matched limit bet.')
|
||||
trans.update(contractDoc.collection('bets').doc(bet.id), {
|
||||
fills,
|
||||
isFilled,
|
||||
shares: totalShares,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
trans.update(userDoc, { balance: newBalance })
|
||||
log('Updated user balance.')
|
||||
trans.update(
|
||||
|
|
Loading…
Reference in New Issue
Block a user