Skip to content

Commit 6e55b8e

Browse files
committed
Enhanced claim and reward processing logic:
- Added support for `rewardDistribution` to handle cases where `settlementResult` is undefined. - Introduced handling for mint, burn, and module-to-module transfers within settlement logic. - Updated `getDenomAndAmount` utility to account for parsing errors and ensure robust handling of string inputs.
1 parent 3c3384d commit 6e55b8e

File tree

2 files changed

+111
-26
lines changed

2 files changed

+111
-26
lines changed

src/mappings/pocket/relays.ts

Lines changed: 100 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
ClaimSettlementResultSDKType,
4242
settlementOpReasonFromJSON,
4343
SettlementOpReasonSDKType,
44+
SettlementOpReason as SettlementOpReasonSdk
4445
} from "../../types/proto-interfaces/pocket/tokenomics/types";
4546
import { optimizedBulkCreate } from "../utils/db";
4647
import { getBlockId, getEventId, messageId } from "../utils/ids";
@@ -163,7 +164,8 @@ function getAttributes(attributes: CosmosEvent["event"]["attributes"]) {
163164
settlementResult: ClaimSettlementResultSDKType | null = null,
164165
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
165166
// @ts-ignore
166-
proofMissingPenalty: CoinSDKType = {};
167+
proofMissingPenalty: CoinSDKType = {},
168+
rewardDistribution: Record<string, string> | undefined;
167169

168170
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
169171
// @ts-ignore
@@ -226,6 +228,10 @@ function getAttributes(attributes: CosmosEvent["event"]["attributes"]) {
226228
settlementResult = JSON.parse(attribute.value as string);
227229
}
228230

231+
if (attribute.key === "reward_distribution") {
232+
rewardDistribution = JSON.parse(attribute.value as string);
233+
}
234+
229235
if (attribute.key === "proof_missing_penalty") {
230236
proofMissingPenalty = getDenomAndAmount(attribute.value as string);
231237
}
@@ -294,6 +300,7 @@ function getAttributes(attributes: CosmosEvent["event"]["attributes"]) {
294300
failureReason,
295301
proofValidationStatus,
296302
settlementResult,
303+
rewardDistribution,
297304
};
298305
}
299306

@@ -365,6 +372,7 @@ function _handleEventClaimSettled(event: CosmosEvent): [EventClaimSettledProps,
365372
numEstimatedComputedUnits,
366373
numRelays,
367374
proofRequirement,
375+
rewardDistribution,
368376
settlementResult,
369377
} = getAttributes(event.event.attributes);
370378

@@ -373,10 +381,14 @@ function _handleEventClaimSettled(event: CosmosEvent): [EventClaimSettledProps,
373381
const eventId = getEventId(event)
374382
const blockId = getBlockId(event.block)
375383

376-
let modToAcctTransfers: Array<ModToAcctTransferProps> = []
384+
let
385+
modToAcctTransfers: Array<ModToAcctTransferProps> = [],
386+
mints: EventClaimSettledProps['mints'] = [],
387+
burns: EventClaimSettledProps['burns'] = [],
388+
modToModTransfers: EventClaimSettledProps['modToModTransfers'] = [];
377389

378-
if (settlementResult?.mod_to_acct_transfers) {
379-
modToAcctTransfers = settlementResult.mod_to_acct_transfers.map((item, index) => ({
390+
if (settlementResult) {
391+
modToAcctTransfers = settlementResult.mod_to_acct_transfers?.map((item, index) => ({
380392
id: `${eventId}-${index}`,
381393
blockId,
382394
eventClaimSettledId: eventId,
@@ -387,6 +399,87 @@ function _handleEventClaimSettled(event: CosmosEvent): [EventClaimSettledProps,
387399
opReason: getSettlementOpReasonFromSDK(item.op_reason),
388400
relayId: '',
389401
})) || []
402+
403+
mints = settlementResult.mints?.map(mint => ({
404+
opReason: settlementOpReasonFromJSON(mint.op_reason),
405+
destinationModule: mint.DestinationModule,
406+
amount: BigInt(mint.coin.amount),
407+
denom: mint.coin.denom,
408+
})) || []
409+
410+
burns = settlementResult.burns?.map(burn => ({
411+
opReason: settlementOpReasonFromJSON(burn.op_reason),
412+
destinationModule: burn.DestinationModule,
413+
amount: BigInt(burn.coin.amount),
414+
denom: burn.coin.denom,
415+
})) || []
416+
417+
modToModTransfers = settlementResult.mod_to_mod_transfers?.map((item) => ({
418+
opReason: settlementOpReasonFromJSON(item.op_reason),
419+
senderModule: item.SenderModule,
420+
recipientModule: item.RecipientModule,
421+
amount: BigInt(item.coin.amount),
422+
denom: item.coin.denom,
423+
})) || []
424+
} else if (rewardDistribution) {
425+
let totalFromRewardDistribution = BigInt(0);
426+
427+
modToAcctTransfers = Object.entries(rewardDistribution).map(([address, coinString], index) => {
428+
const coin = getDenomAndAmount(coinString)
429+
const coinAmount = BigInt(coin.amount)
430+
totalFromRewardDistribution = totalFromRewardDistribution + coinAmount;
431+
432+
return {
433+
id: `${eventId}-${index}`,
434+
blockId,
435+
eventClaimSettledId: eventId,
436+
senderModule: '',
437+
recipientId: address,
438+
opReason: SettlementOpReason.UNSPECIFIED,
439+
relayId: '',
440+
denom: coin.denom,
441+
amount: coinAmount,
442+
}
443+
})
444+
445+
burns = [
446+
{
447+
opReason: settlementOpReasonFromJSON(SettlementOpReasonSdk.TLM_RELAY_BURN_EQUALS_MINT_APPLICATION_STAKE_BURN),
448+
destinationModule: '',
449+
// we are assuming here that mint = burn is always true, if this changes in the future, then we need to update this
450+
amount: BigInt(claimed.amount),
451+
denom: claimed.denom,
452+
}
453+
]
454+
455+
// it seems that global mint is being minted twice, one due to inflation and the other due to application reimbursement
456+
// see: https://github.com/pokt-network/poktroll/blob/main/x/tokenomics/token_logic_module/tlm_reimbursement_requests.go#L57
457+
// so in order to get the inflation mint we need to divide the difference between the total of the reward_distribution
458+
// and the claimed upokt
459+
const totalMint = totalFromRewardDistribution - BigInt(claimed.amount);
460+
const globalMint = totalMint / BigInt(2)
461+
462+
mints = [
463+
{
464+
opReason: settlementOpReasonFromJSON(SettlementOpReasonSdk.TLM_GLOBAL_MINT_INFLATION),
465+
destinationModule: '',
466+
amount: globalMint,
467+
denom: claimed.denom,
468+
},
469+
{
470+
opReason: settlementOpReasonFromJSON(SettlementOpReasonSdk.TLM_GLOBAL_MINT_REIMBURSEMENT_REQUEST_ESCROW_DAO_TRANSFER),
471+
destinationModule: '',
472+
amount: globalMint,
473+
denom: claimed.denom,
474+
},
475+
{
476+
opReason: settlementOpReasonFromJSON(SettlementOpReasonSdk.TLM_RELAY_BURN_EQUALS_MINT_SUPPLIER_STAKE_MINT),
477+
destinationModule: '',
478+
// we are assuming here that mint = burn is always true, if this changes in the future, then we need to update this
479+
amount: BigInt(claimed.amount),
480+
denom: claimed.denom,
481+
}
482+
]
390483
}
391484

392485
return [
@@ -407,25 +500,9 @@ function _handleEventClaimSettled(event: CosmosEvent): [EventClaimSettledProps,
407500
blockId: blockId,
408501
id: eventId,
409502
proofRequirement,
410-
mints: settlementResult?.mints?.map(mint => ({
411-
opReason: settlementOpReasonFromJSON(mint.op_reason),
412-
destinationModule: mint.DestinationModule,
413-
amount: BigInt(mint.coin.amount),
414-
denom: mint.coin.denom,
415-
})) || [],
416-
burns: settlementResult?.burns?.map(burn => ({
417-
opReason: settlementOpReasonFromJSON(burn.op_reason),
418-
destinationModule: burn.DestinationModule,
419-
amount: BigInt(burn.coin.amount),
420-
denom: burn.coin.denom,
421-
})) || [],
422-
modToModTransfers: settlementResult?.mod_to_mod_transfers?.map((item) => ({
423-
opReason: settlementOpReasonFromJSON(item.op_reason),
424-
senderModule: item.SenderModule,
425-
recipientModule: item.RecipientModule,
426-
amount: BigInt(item.coin.amount),
427-
denom: item.coin.denom,
428-
})) || [],
503+
mints,
504+
burns,
505+
modToModTransfers,
429506
rootHash: undefined,
430507
},
431508
modToAcctTransfers,

src/mappings/utils/primitives.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,25 @@ export function filterMsgByTxStatus(messages: Array<CosmosMessage>): {
131131

132132
// This receives a string like `121upokt` and return { denom: "upokt", amount: "121" }
133133
export function getDenomAndAmount(coinAndDenom: string): CoinSDKType {
134-
const parsed: string | CoinSDKType = JSON.parse(coinAndDenom);
134+
let parsed: string | CoinSDKType
135+
136+
try {
137+
parsed = JSON.parse(coinAndDenom);
138+
} catch (e) {
139+
parsed = coinAndDenom;
140+
}
135141

136142
if (typeof parsed === 'object') {
137143
return parsed
138144
} else {
139-
const [amount, denom] = coinAndDenom.split(/^(\d+)([a-zA-Z]+)$/);
145+
const match = parsed.match(/^(\d+)([a-zA-Z]+)$/);
140146

141-
if (!amount || !denom) {
147+
if (!match) {
142148
throw new Error(`Invalid coinAndDenom=${coinAndDenom}`);
143149
}
144150

151+
const [, amount, denom] = match;
152+
145153
return {
146154
amount,
147155
denom,

0 commit comments

Comments
 (0)