Skip to content

Commit

Permalink
Have client calculate dependencies and pass to API (#2756)
Browse files Browse the repository at this point in the history
* Have client calculate dependencies and pass to API

* Include cancelled limit orders

* Include cancelled limit orders
  • Loading branch information
IanPhilips authored Aug 1, 2024
1 parent 78d7a91 commit 9f5a7e8
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 39 deletions.
3 changes: 1 addition & 2 deletions backend/api/src/on-create-bet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
getBettingStreakResetTimeBeforeNow,
getUser,
} from 'shared/utils'
import { Bet, LimitBet } from 'common/bet'
import { Bet, LimitBet, maker } from 'common/bet'
import {
CPMMContract,
CPMMMultiContract,
Expand All @@ -31,7 +31,6 @@ import {
SupabaseDirectClient,
} from 'shared/supabase/init'
import { convertBet } from 'common/supabase/bets'
import { maker } from 'api/place-bet'
import { BOT_USERNAMES } from 'common/envs/constants'
import { addUserToContractFollowers } from 'shared/follow-market'
import { updateUserInterestEmbedding } from 'shared/helpers/embeddings'
Expand Down
53 changes: 27 additions & 26 deletions backend/api/src/place-bet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
uniqBy,
} from 'lodash'
import { APIError, type APIHandler } from './helpers/endpoint'
import { CPMM_MIN_POOL_QTY, Contract, MarketContract } from 'common/contract'
import { Contract, CPMM_MIN_POOL_QTY, MarketContract } from 'common/contract'
import { User } from 'common/user'
import {
BetInfo,
Expand All @@ -17,7 +17,7 @@ import {
getNewMultiCpmmBetInfo,
} from 'common/new-bet'
import { removeUndefinedProps } from 'common/util/object'
import { Bet, LimitBet } from 'common/bet'
import { Bet, LimitBet, maker } from 'common/bet'
import { floatingEqual } from 'common/util/math'
import { getContract, getUser, log, metrics } from 'shared/utils'
import { Answer } from 'common/answer'
Expand All @@ -28,9 +28,9 @@ import { BLESSED_BANNED_USER_IDS } from 'common/envs/constants'
import * as crypto from 'crypto'
import { formatMoneyWithDecimals } from 'common/util/format'
import {
createSupabaseDirectClient,
SupabaseDirectClient,
SupabaseTransaction,
createSupabaseDirectClient,
} from 'shared/supabase/init'
import { bulkIncrementBalances, incrementBalance } from 'shared/supabase/users'
import { runShortTrans } from 'shared/short-transaction'
Expand All @@ -55,24 +55,32 @@ import { filterDefined } from 'common/util/array'
export const placeBet: APIHandler<'bet'> = async (props, auth) => {
const isApi = auth.creds.kind === 'key'

const { user, contract, answers, unfilledBets, balanceByUserId } =
await fetchContractBetDataAndValidate(
createSupabaseDirectClient(),
let simulatedMakerIds: string[] = []
if (props.deps === undefined) {
const { user, contract, answers, unfilledBets, balanceByUserId } =
await fetchContractBetDataAndValidate(
createSupabaseDirectClient(),
props,
auth.uid,
isApi
)
// Simulate bet to see whose limit orders you match.
const simulatedResult = calculateBetResult(
props,
auth.uid,
isApi
user,
contract,
answers,
unfilledBets,
balanceByUserId
)
// Simulate bet to see whose limit orders you match.
const simulatedResult = calculateBetResult(
props,
user,
contract,
answers,
unfilledBets,
balanceByUserId
)
const simulatedMakerIds = getMakerIdsFromBetResult(simulatedResult)
const deps = [auth.uid, contract.id, ...simulatedMakerIds]
simulatedMakerIds = getMakerIdsFromBetResult(simulatedResult)
}

const deps = [
auth.uid,
props.contractId,
...(props.deps ?? simulatedMakerIds),
]

return await betsQueue.enqueueFn(
() => placeBetMain(props, auth.uid, isApi),
Expand Down Expand Up @@ -665,13 +673,6 @@ export const validateBet = async (
return user
}

export type maker = {
bet: LimitBet
amount: number
shares: number
timestamp: number
}

export async function bulkUpdateLimitOrders(
db: SupabaseDirectClient,
updates: Array<{
Expand Down
4 changes: 2 additions & 2 deletions backend/shared/src/short-transaction.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {
SupabaseTransaction,
createSupabaseDirectClient,
SERIAL_MODE,
} from './supabase/init'
import { DEFAULT_QUEUE_TIME_LIMIT } from 'shared/helpers/fn-queue'

export const runShortTrans = async <T>(
callback: (trans: SupabaseTransaction) => Promise<T>
) => {
const pg = createSupabaseDirectClient()
return await pg.timeout(DEFAULT_QUEUE_TIME_LIMIT / 2, callback, false)
return await pg.tx({ mode: SERIAL_MODE }, callback)
}
1 change: 1 addition & 0 deletions common/src/api/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ export const API = (_apiTypeCheck = {
//Multi
answerId: z.string().optional(),
dryRun: z.boolean().optional(),
deps: z.array(z.string()).optional(),
})
.strict(),
},
Expand Down
6 changes: 6 additions & 0 deletions common/src/bet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,9 @@ export const calculateMultiBets = (
)
)
}
export type maker = {
bet: LimitBet
amount: number
shares: number
timestamp: number
}
6 changes: 3 additions & 3 deletions common/src/calculate-cpmm-arbitrage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Dictionary, first, groupBy, mapValues, sum, sumBy } from 'lodash'
import { Answer } from './answer'
import { Bet, LimitBet } from './bet'
import { Bet, LimitBet, maker } from './bet'
import {
calculateAmountToBuySharesFixedP,
getCpmmProbability,
Expand All @@ -23,8 +23,8 @@ const noFillsReturn = (
outcome,
answer,
takers: [],
makers: [],
ordersToCancel: [],
makers: [] as maker[],
ordersToCancel: [] as LimitBet[],
cpmmState: {
pool: { YES: answer.poolYes, NO: answer.poolNo },
p: 0.5,
Expand Down
13 changes: 12 additions & 1 deletion web/components/bet/bet-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import clsx from 'clsx'
import { useEffect, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import { sumBy } from 'lodash'
import toast from 'react-hot-toast'
import { CheckIcon } from '@heroicons/react/solid'
Expand Down Expand Up @@ -55,6 +55,7 @@ import { FeeDisplay } from './fees'
import { floatingEqual } from 'common/util/math'
import { getTierFromLiquidity } from 'common/tier'
import { getAnswerColor } from '../charts/contract/choice'
import { LimitBet } from 'common/bet'

export type BinaryOutcomes = 'YES' | 'NO' | undefined

Expand Down Expand Up @@ -234,6 +235,7 @@ export const BuyPanelBody = (props: {

const [error, setError] = useState<string | undefined>()
const [isSubmitting, setIsSubmitting] = useState(false)
const betDeps = useRef<LimitBet[]>()

const [inputRef, focusAmountInput] = useFocus()

Expand Down Expand Up @@ -285,6 +287,7 @@ export const BuyPanelBody = (props: {
contractId: contract.id,
answerId: multiProps?.answerToBuy.id,
replyToCommentId,
deps: betDeps.current?.map((b) => b.userId),
})
)
.then((r) => {
Expand Down Expand Up @@ -373,6 +376,11 @@ export const BuyPanelBody = (props: {
fees =
getFeeTotal(newBetResult.totalFees) +
sumBy(otherBetResults, (result) => getFeeTotal(result.totalFees))
betDeps.current = newBetResult.makers
.map((m) => m.bet)
.concat(otherBetResults.flatMap((r) => r.makers.map((m) => m.bet)))
.concat(newBetResult.ordersToCancel)
.concat(otherBetResults.flatMap((r) => r.ordersToCancel))
} else {
const cpmmState = isCpmmMulti
? {
Expand Down Expand Up @@ -403,6 +411,9 @@ export const BuyPanelBody = (props: {
probBefore = result.probBefore
probAfter = result.probAfter
fees = getFeeTotal(result.fees)
betDeps.current = result.makers
.map((m) => m.bet)
.concat(result.ordersToCancel)
}
} catch (err: any) {
console.error('Error in calculateCpmmMultiArbitrageBet:', err)
Expand Down
30 changes: 25 additions & 5 deletions web/components/bet/limit-order-panel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import dayjs from 'dayjs'
import { clamp, sumBy } from 'lodash'
import { useState } from 'react'
import { useRef, useState } from 'react'

import { Answer } from 'common/answer'
import { LimitBet } from 'common/bet'
Expand Down Expand Up @@ -91,7 +91,7 @@ export default function LimitOrderPanel(props: {
const [error, setError] = useState<string | undefined>()
const [inputError, setInputError] = useState<boolean>(false)
const [isSubmitting, setIsSubmitting] = useState(false)

const betDeps = useRef<LimitBet[]>()
// Expiring orders
const [addExpiration, setAddExpiration] = usePersistentInMemoryState(
false,
Expand Down Expand Up @@ -185,6 +185,7 @@ export default function LimitOrderPanel(props: {
answerId,
limitProb: limitProb,
expiresAt,
deps: betDeps.current?.map((b) => b.userId),
})
)
.then((r) => {
Expand Down Expand Up @@ -238,6 +239,7 @@ export default function LimitOrderPanel(props: {
orderAmount = result.orderAmount
filledAmount = result.amount
fees = result.fees
betDeps.current = result.betDeps
} catch (err: any) {
console.error('Error in calculateCpmmMultiArbitrageBet:', err)
setError(
Expand Down Expand Up @@ -467,6 +469,7 @@ const getBetReturns = (
let amount: number
let shares: number
let fees: Fees
let betDeps: LimitBet[]
if (arbitrageProps) {
const { answers, answerToBuy } = arbitrageProps
const { newBetResult, otherBetResults } = calculateCpmmMultiArbitrageBet(
Expand All @@ -481,6 +484,11 @@ const getBetReturns = (
)
amount = sumBy(newBetResult.takers, 'amount')
shares = sumBy(newBetResult.takers, 'shares')
betDeps = newBetResult.makers
.map((m) => m.bet)
.concat(otherBetResults.flatMap((r) => r.makers.map((m) => m.bet)))
.concat(newBetResult.ordersToCancel)
.concat(otherBetResults.flatMap((r) => r.ordersToCancel))
fees = addObjects(
newBetResult.totalFees,
otherBetResults.reduce(
Expand All @@ -489,15 +497,19 @@ const getBetReturns = (
)
)
} else {
;({ amount, shares, fees } = computeCpmmBet(
const result = computeCpmmBet(
cpmmState,
outcome,
betAmount,
limitProb,
unfilledBets,
balanceByUserId,
!arbitrageProps && { max: MAX_CPMM_PROB, min: MIN_CPMM_PROB }
))
)
amount = result.amount
shares = result.shares
fees = result.fees
betDeps = result.makers.map((m) => m.bet).concat(result.ordersToCancel)
}

const remainingMatched = limitProb
Expand All @@ -507,5 +519,13 @@ const getBetReturns = (
const currentPayout = shares + remainingMatched
const currentReturn = betAmount ? (currentPayout - betAmount) / betAmount : 0

return { orderAmount, amount, shares, currentPayout, currentReturn, fees }
return {
orderAmount,
amount,
shares,
currentPayout,
currentReturn,
fees,
betDeps,
}
}

0 comments on commit 9f5a7e8

Please sign in to comment.