From 8740de50bd475cbb1b3238ecd99259c979af355f Mon Sep 17 00:00:00 2001 From: James Grugett Date: Fri, 19 Aug 2022 16:21:45 -0500 Subject: [PATCH] Pay back loan on sell shares --- common/sell-bet.ts | 5 ++--- functions/src/sell-shares.ts | 30 ++++++++++++++++-------------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/common/sell-bet.ts b/common/sell-bet.ts index e1fd9c5d..79470d70 100644 --- a/common/sell-bet.ts +++ b/common/sell-bet.ts @@ -79,8 +79,8 @@ export const getCpmmSellBetInfo = ( shares: number, outcome: 'YES' | 'NO', contract: CPMMContract, - prevLoanAmount: number, - unfilledBets: LimitBet[] + unfilledBets: LimitBet[], + loanPaid: number ) => { const { pool, p } = contract @@ -91,7 +91,6 @@ export const getCpmmSellBetInfo = ( unfilledBets ) - const loanPaid = Math.min(prevLoanAmount, saleValue) const probBefore = getCpmmProbability(pool, p) const probAfter = getCpmmProbability(cpmmState.pool, cpmmState.p) diff --git a/functions/src/sell-shares.ts b/functions/src/sell-shares.ts index ec08ab86..d9f99de3 100644 --- a/functions/src/sell-shares.ts +++ b/functions/src/sell-shares.ts @@ -7,7 +7,7 @@ import { Contract, CPMM_MIN_POOL_QTY } from '../../common/contract' import { User } from '../../common/user' import { getCpmmSellBetInfo } from '../../common/sell-bet' import { addObjects, removeUndefinedProps } from '../../common/util/object' -import { getValues, log } from './utils' +import { log } from './utils' import { Bet } from '../../common/bet' import { floatingEqual, floatingLesserEqual } from '../../common/util/math' import { getUnfilledBetsQuery, updateMakers } from './place-bet' @@ -28,12 +28,16 @@ export const sellshares = newEndpoint({}, async (req, auth) => { const contractDoc = firestore.doc(`contracts/${contractId}`) const userDoc = firestore.doc(`users/${auth.uid}`) const betsQ = contractDoc.collection('bets').where('userId', '==', auth.uid) - const [[contractSnap, userSnap], userBets] = await Promise.all([ - transaction.getAll(contractDoc, userDoc), - getValues(betsQ), // TODO: why is this not in the transaction?? - ]) + const [[contractSnap, userSnap], userBetsSnap, unfilledBetsSnap] = + await Promise.all([ + transaction.getAll(contractDoc, userDoc), + transaction.get(betsQ), + transaction.get(getUnfilledBetsQuery(contractDoc)), + ]) if (!contractSnap.exists) throw new APIError(400, 'Contract not found.') if (!userSnap.exists) throw new APIError(400, 'User not found.') + const userBets = userBetsSnap.docs.map((doc) => doc.data() as Bet) + const unfilledBets = unfilledBetsSnap.docs.map((doc) => doc.data()) const contract = contractSnap.data() as Contract const user = userSnap.data() as User @@ -45,7 +49,7 @@ export const sellshares = newEndpoint({}, async (req, auth) => { if (closeTime && Date.now() > closeTime) throw new APIError(400, 'Trading is closed.') - const prevLoanAmount = sumBy(userBets, (bet) => bet.loanAmount ?? 0) + const loanAmount = sumBy(userBets, (bet) => bet.loanAmount ?? 0) const betsByOutcome = groupBy(userBets, (bet) => bet.outcome) const sharesByOutcome = mapValues(betsByOutcome, (bets) => sumBy(bets, (b) => b.shares) @@ -77,18 +81,16 @@ export const sellshares = newEndpoint({}, async (req, auth) => { throw new APIError(400, `You can only sell up to ${maxShares} shares.`) const soldShares = Math.min(sharesToSell, maxShares) - - const unfilledBetsSnap = await transaction.get( - getUnfilledBetsQuery(contractDoc) - ) - const unfilledBets = unfilledBetsSnap.docs.map((doc) => doc.data()) + const saleFrac = soldShares / maxShares + let loanPaid = saleFrac * loanAmount + if (!isFinite(loanPaid)) loanPaid = 0 const { newBet, newPool, newP, fees, makers } = getCpmmSellBetInfo( soldShares, chosenOutcome, contract, - prevLoanAmount, - unfilledBets + unfilledBets, + loanPaid ) if ( @@ -104,7 +106,7 @@ export const sellshares = newEndpoint({}, async (req, auth) => { updateMakers(makers, newBetDoc.id, contractDoc, transaction) transaction.update(userDoc, { - balance: FieldValue.increment(-newBet.amount), + balance: FieldValue.increment(-newBet.amount + (newBet.loanAmount ?? 0)), }) transaction.create(newBetDoc, { id: newBetDoc.id,