Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have client calculate dependencies and pass to API #2756

Merged
merged 3 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
}
}
Loading