106 lines
3.1 KiB
TypeScript
106 lines
3.1 KiB
TypeScript
|
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())
|