Skip to content

Commit

Permalink
Cap distributor maxWeight and run every hour
Browse files Browse the repository at this point in the history
  • Loading branch information
youngkidwarrior committed Nov 27, 2024
1 parent d80fe64 commit 56f6fa3
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
31 changes: 26 additions & 5 deletions apps/distributor/src/distributorv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,12 @@ export class DistributorV2Worker {
const sendCeilingVerifications = verifications.filter((v) => v.type === 'send_ceiling')
const sendCeilingByUserId = sendCeilingVerifications.reduce(
(acc, v) => {
const previousReward =
previousSharesByUserId[v.user_id] || BigInt(distribution.hodler_min_balance)
const maxWeight = previousReward / BigInt(sendSlash.scaling_divisor)
acc[v.user_id] = {
weight: BigInt(v.weight || 0),
// Cap the weight to maxWeight
weight: BigInt(v.weight || 0) > maxWeight ? maxWeight : BigInt(v.weight || 0),
// @ts-expect-error @todo metadata is untyped but value is the convention
ceiling: BigInt(v.metadata?.value || 0),
}
Expand Down Expand Up @@ -454,7 +458,10 @@ export class DistributorV2Worker {

// Calculate time adjustment for slashed amounts
const hourlyHodlerAmount = (hodlerPoolAvailableAmount * PERC_DENOM) / BigInt(hoursInMonth)
const timeAdjustedAmount = (hourlyHodlerAmount * BigInt(currentHour + 1)) / PERC_DENOM
const timeAdjustedAmount =
(hourlyHodlerAmount * BigInt(currentHour + 1)) / PERC_DENOM > hodlerPoolAvailableAmount
? hodlerPoolAvailableAmount
: (hourlyHodlerAmount * BigInt(currentHour + 1)) / PERC_DENOM

// First calculate slashed balances for everyone
const balances = minBalanceAddresses.map((balance) => {
Expand All @@ -465,7 +472,12 @@ export class DistributorV2Worker {
if (sendCeilingData && sendCeilingData.weight > 0n) {
const previousReward =
previousSharesByUserId[userId] || BigInt(distribution.hodler_min_balance)
slashPercentage = (sendCeilingData.weight * PERC_DENOM) / previousReward
const scaledPreviousReward = previousReward / BigInt(sendSlash.scaling_divisor)
const cappedWeight =
sendCeilingData.weight > scaledPreviousReward
? scaledPreviousReward
: sendCeilingData.weight
slashPercentage = (cappedWeight * PERC_DENOM) / scaledPreviousReward
}

const balanceAfterSlash = (
Expand Down Expand Up @@ -529,7 +541,10 @@ export class DistributorV2Worker {
// Non-slashed amounts
const hodlerPoolAmount = share.amount
const fixedPoolAmount = fixedPoolAmountsByAddress[share.address]?.amount || 0n
const amount = hodlerPoolAmount + fixedPoolAmount > distAmt ? distAmt : hodlerPoolAmount
const amount =
hodlerPoolAmount + fixedPoolAmount > distAmt
? distAmt
: hodlerPoolAmount + fixedPoolAmount

// Slashed amounts - ensure we always have a value
const hodlerPoolAmountAfterSlash = share.amountAfterSlash || 0n
Expand Down Expand Up @@ -616,11 +631,17 @@ export class DistributorV2Worker {

while (this.running) {
try {
const now = new Date()
const nextHour = new Date(now)
nextHour.setHours(nextHour.getHours() + 1, 0, 0, 0)
const targetTime = new Date(nextHour.getTime() - 60000) // 1 minute before next hour
const waitTime = targetTime.getTime() - now.getTime()

process.env.NODE_ENV === 'development' ? await sleep(10_000) : await sleep(waitTime)
await this.calculateDistributions()
} catch (error) {
this.log.error(error, `Error processing block. ${(error as Error).message}`)
}
await sleep(process.env.NODE_ENV !== 'production' ? 10_000 : 21_600_000)
}

this.log.info('Distributor stopped.')
Expand Down
16 changes: 6 additions & 10 deletions apps/distributor/src/weights.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,6 @@ export function calculatePercentageWithBips(value: bigint, bips: bigint) {
return percentage / PERC_DENOM
}

const calculateSlashPercentage = (
weight: bigint,
scaledPreviousReward: bigint,
percDenom: bigint = PERC_DENOM
): bigint => {
return (weight * percDenom) / scaledPreviousReward > percDenom
? percDenom
: (weight * percDenom) / scaledPreviousReward
}

/**
* Given a list of balances and a distribution amount, calculate the distribution weights and share amounts.
*/
Expand Down Expand Up @@ -99,6 +89,12 @@ export function calculateWeights(
const poolWeight = poolWeights[address] ?? 0n
const poolWeightAfterSlash = poolWeightsAfterSlash[address] ?? 0n
const totalWeight = totalWeightAfterSlash - poolWeightAfterSlash + poolWeight

// with capped slashed balances:
// totalWeightAfterSlash = sum of all capped slashed balances
// -poolWeightAfterSlash = remove this user's capped slashed balance
// +poolWeight = add their full unslashed balance

const potentialAmount = (poolWeight * amount) / totalWeight
const slashedAmount = (poolWeightAfterSlash * timeAdjustedAmount) / totalWeightAfterSlash

Expand Down

0 comments on commit 56f6fa3

Please sign in to comment.