From 7aa074a31a40ecf13e2f68020f24de78f5537ead Mon Sep 17 00:00:00 2001 From: James Grugett Date: Wed, 9 Mar 2022 17:02:57 -0600 Subject: [PATCH] Script for paying out contract again --- .../src/scripts/pay-out-contract-again.ts | 105 ++++++++++++++++++ functions/src/utils.ts | 5 - 2 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 functions/src/scripts/pay-out-contract-again.ts diff --git a/functions/src/scripts/pay-out-contract-again.ts b/functions/src/scripts/pay-out-contract-again.ts new file mode 100644 index 00000000..96671ed8 --- /dev/null +++ b/functions/src/scripts/pay-out-contract-again.ts @@ -0,0 +1,105 @@ +import * as admin from 'firebase-admin' +import * as _ from 'lodash' + +import { initAdmin } from './script-init' +initAdmin('james') + +import { Bet } from '../../../common/bet' +import { Contract } from '../../../common/contract' +import { + getLoanPayouts, + getPayouts, + getPayoutsMultiOutcome, +} from '../../../common/payouts' +import { filterDefined } from '../../../common/util/array' +import { payUser } from '../utils' + +type DocRef = admin.firestore.DocumentReference + +const firestore = admin.firestore() + +async function checkIfPayOutAgain(contractRef: DocRef, contract: Contract) { + const bets = await contractRef + .collection('bets') + .get() + .then((snap) => snap.docs.map((bet) => bet.data() as Bet)) + + const openBets = bets.filter((b) => !b.isSold && !b.sale) + const loanedBets = openBets.filter((bet) => bet.loanAmount) + + if (loanedBets.length && contract.resolution) { + const { resolution, outcomeType, resolutions, resolutionProbability } = + contract + const payouts = + outcomeType === 'FREE_RESPONSE' && resolutions + ? getPayoutsMultiOutcome(resolutions, contract, openBets) + : getPayouts(resolution, contract, openBets, resolutionProbability) + + const loanPayouts = getLoanPayouts(openBets) + const groups = _.groupBy( + [...payouts, ...loanPayouts], + (payout) => payout.userId + ) + const userPayouts = _.mapValues(groups, (group) => + _.sumBy(group, (g) => g.payout) + ) + + const entries = Object.entries(userPayouts) + const firstNegative = entries.findIndex(([_, payout]) => payout < 0) + const toBePaidOut = firstNegative === -1 ? [] : entries.slice(firstNegative) + + if (toBePaidOut.length) { + console.log( + 'to be paid out', + toBePaidOut.length, + 'already paid out', + entries.length - toBePaidOut.length + ) + const positivePayouts = toBePaidOut.filter(([_, payout]) => payout > 0) + if (positivePayouts.length) + return { contract, toBePaidOut: positivePayouts } + } + } + return undefined +} + +async function payOutContractAgain() { + console.log('Recalculating contract info') + + const snapshot = await firestore.collection('contracts').get() + + const [startTime, endTime] = [ + new Date('2022-03-02'), + new Date('2022-03-07'), + ].map((date) => date.getTime()) + + const contracts = snapshot.docs + .map((doc) => doc.data() as Contract) + .filter((contract) => { + const { resolutionTime } = contract + return ( + resolutionTime && resolutionTime > startTime && resolutionTime < endTime + ) + }) + + console.log('Loaded', contracts.length, 'contracts') + + const toPayOutAgain = filterDefined( + await Promise.all( + contracts.map(async (contract) => { + const contractRef = firestore.doc(`contracts/${contract.id}`) + + return await checkIfPayOutAgain(contractRef, contract) + }) + ) + ) + + const flattened = _.flatten(toPayOutAgain.map((d) => d.toBePaidOut)) + + for (const [userId, payout] of flattened) { + console.log('Paying out', userId, payout) + // await payUser(userId, payout) + } +} + +if (require.main === module) payOutContractAgain().then(() => process.exit()) diff --git a/functions/src/utils.ts b/functions/src/utils.ts index f34db1c8..a5d5640f 100644 --- a/functions/src/utils.ts +++ b/functions/src/utils.ts @@ -53,11 +53,6 @@ const updateUserBalance = ( const newUserBalance = user.balance + delta - if (newUserBalance < 0) - throw new Error( - `User (${userId}) balance cannot be negative: ${newUserBalance}` - ) - if (isDeposit) { const newTotalDeposits = (user.totalDeposits || 0) + delta transaction.update(userDoc, { totalDeposits: newTotalDeposits })