Skip to content

Commit

Permalink
Merge pull request #1505 from multiversx/SERVICES-2651-add-extra-fiel…
Browse files Browse the repository at this point in the history
…ds-to-staking-model

[SERVICES-2651] Add extra fields to staking model
  • Loading branch information
mad2sm0key authored Oct 11, 2024
2 parents f5e9383 + 56755c6 commit d578d92
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 18 deletions.
4 changes: 4 additions & 0 deletions src/modules/staking/models/staking.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export class StakingModel {
@Field()
apr: string;
@Field()
aprUncapped: string;
@Field()
boostedApr: string;
@Field(() => Int)
minUnboundEpochs: number;
Expand All @@ -44,6 +46,8 @@ export class StakingModel {
@Field()
rewardsRemainingDays: number;
@Field()
rewardsRemainingDaysUncapped: number;
@Field()
divisionSafetyConstant: string;
@Field()
produceRewardsEnabled: boolean;
Expand Down
95 changes: 77 additions & 18 deletions src/modules/staking/services/staking.compute.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,17 +209,9 @@ export class StakingComputeService {
}

async computeStakeFarmAPR(stakeAddress: string): Promise<string> {
const [accumulatedRewards, rewardsCapacity, produceRewardsEnabled] =
await Promise.all([
this.stakingAbi.accumulatedRewards(stakeAddress),
this.stakingAbi.rewardCapacity(stakeAddress),
this.stakingAbi.produceRewardsEnabled(stakeAddress),
]);
const isProducingRewards = await this.isProducingRewards(stakeAddress);

if (
!produceRewardsEnabled ||
new BigNumber(accumulatedRewards).isEqualTo(rewardsCapacity)
) {
if (isProducingRewards) {
return '0';
}

Expand Down Expand Up @@ -252,6 +244,37 @@ export class StakingComputeService {
.toFixed();
}

@ErrorLoggerAsync({
logArgs: true,
})
@GetOrSetCache({
baseKey: 'stake',
remoteTtl: CacheTtlInfo.ContractState.remoteTtl,
localTtl: CacheTtlInfo.ContractState.localTtl,
})
async stakeFarmUncappedAPR(stakeAddress: string): Promise<string> {
return await this.computeStakeFarmUncappedAPR(stakeAddress);
}

async computeStakeFarmUncappedAPR(stakeAddress: string): Promise<string> {
const isProducingRewards = await this.isProducingRewards(stakeAddress);

if (isProducingRewards) {
return '0';
}

const [perBlockRewardAmount, farmTokenSupply] = await Promise.all([
this.stakingAbi.perBlockRewardsAmount(stakeAddress),
this.stakingAbi.farmTokenSupply(stakeAddress),
]);

const rewardsUnboundedBig = new BigNumber(
perBlockRewardAmount,
).multipliedBy(constantsConfig.BLOCKS_IN_YEAR);

return rewardsUnboundedBig.dividedBy(farmTokenSupply).toFixed();
}

@ErrorLoggerAsync({
logArgs: true,
})
Expand Down Expand Up @@ -322,24 +345,42 @@ export class StakingComputeService {
}

async computeRewardsRemainingDays(stakeAddress: string): Promise<number> {
const extraRewardsAPRBoundedPerBlock =
await this.computeExtraRewardsAPRBoundedPerBlock(stakeAddress);

return await this.computeRewardsRemainingDaysBase(
stakeAddress,
extraRewardsAPRBoundedPerBlock,
);
}

async computeRewardsRemainingDaysUncapped(
stakeAddress: string,
): Promise<number> {
return await this.computeRewardsRemainingDaysBase(stakeAddress);
}

async computeRewardsRemainingDaysBase(
stakeAddress: string,
extraRewardsAPRBoundedPerBlock?: BigNumber,
): Promise<number> {
const [perBlockRewardAmount, accumulatedRewards, rewardsCapacity] =
await Promise.all([
this.stakingAbi.perBlockRewardsAmount(stakeAddress),
this.stakingAbi.accumulatedRewards(stakeAddress),
this.stakingAbi.rewardCapacity(stakeAddress),
]);

const perBlockRewards = extraRewardsAPRBoundedPerBlock
? BigNumber.min(
extraRewardsAPRBoundedPerBlock,
perBlockRewardAmount,
)
: new BigNumber(perBlockRewardAmount);

// 10 blocks per minute * 60 minutes per hour * 24 hours per day
const blocksInDay = 10 * 60 * 24;

const extraRewardsAPRBoundedPerBlock =
await this.computeExtraRewardsAPRBoundedPerBlock(stakeAddress);

const perBlockRewards = BigNumber.min(
extraRewardsAPRBoundedPerBlock,
perBlockRewardAmount,
);

return parseFloat(
new BigNumber(rewardsCapacity)
.minus(accumulatedRewards)
Expand Down Expand Up @@ -920,4 +961,22 @@ export class StakingComputeService {
);
return deployedAt ?? undefined;
}

private async isProducingRewards(stakeAddress: string): Promise<boolean> {
const [accumulatedRewards, rewardsCapacity, produceRewardsEnabled] =
await Promise.all([
this.stakingAbi.accumulatedRewards(stakeAddress),
this.stakingAbi.rewardCapacity(stakeAddress),
this.stakingAbi.produceRewardsEnabled(stakeAddress),
]);

if (
!produceRewardsEnabled ||
new BigNumber(accumulatedRewards).isEqualTo(rewardsCapacity)
) {
return true;
}

return false;
}
}
12 changes: 12 additions & 0 deletions src/modules/staking/staking.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ export class StakingResolver {
return this.stakingCompute.stakeFarmAPR(parent.address);
}

@ResolveField()
async aprUncapped(@Parent() parent: StakingModel) {
return this.stakingCompute.stakeFarmUncappedAPR(parent.address);
}

@ResolveField()
async boostedApr(@Parent() parent: StakingModel) {
return this.stakingCompute.boostedAPR(parent.address);
Expand All @@ -169,6 +174,13 @@ export class StakingResolver {
return this.stakingCompute.computeRewardsRemainingDays(parent.address);
}

@ResolveField()
async rewardsRemainingDaysUncapped(@Parent() parent: StakingModel) {
return this.stakingCompute.computeRewardsRemainingDaysUncapped(
parent.address,
);
}

@ResolveField()
async divisionSafetyConstant(@Parent() parent: StakingModel) {
return this.stakingAbi.divisionSafetyConstant(parent.address);
Expand Down

0 comments on commit d578d92

Please sign in to comment.