Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SERVICES-1379: compute undistributedBoostedRewards #982

Closed
wants to merge 11 commits into from
Closed
54 changes: 54 additions & 0 deletions src/modules/farm/mocks/farm.v2.abi.service.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { FarmAbiServiceV2 } from '../v2/services/farm.v2.abi.service';
import { FarmAbiServiceMock } from './farm.abi.service.mock';
import { IFarmAbiServiceV2 } from '../v2/services/interfaces';
import { BoostedYieldsFactors } from '../models/farm.v2.model';

export class FarmAbiServiceMockV2
extends FarmAbiServiceMock
implements IFarmAbiServiceV2
{
async lastUndistributedBoostedRewardsCollectWeek(
farmAddress: string,
): Promise<number> {
return 1;

Check warning on line 13 in src/modules/farm/mocks/farm.v2.abi.service.mock.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/mocks/farm.v2.abi.service.mock.ts#L13

Added line #L13 was not covered by tests
}
async undistributedBoostedRewards(farmAddress: string): Promise<string> {
return '5000';

Check warning on line 16 in src/modules/farm/mocks/farm.v2.abi.service.mock.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/mocks/farm.v2.abi.service.mock.ts#L16

Added line #L16 was not covered by tests
}
async remainingBoostedRewardsToDistribute(
farmAddress: string,
week: number,
): Promise<string> {
return '1000';

Check warning on line 22 in src/modules/farm/mocks/farm.v2.abi.service.mock.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/mocks/farm.v2.abi.service.mock.ts#L22

Added line #L22 was not covered by tests
}

accumulatedRewardsForWeek(scAddress: string, week: number): Promise<string> {
throw new Error('Method not implemented.');

Check warning on line 26 in src/modules/farm/mocks/farm.v2.abi.service.mock.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/mocks/farm.v2.abi.service.mock.ts#L26

Added line #L26 was not covered by tests
}

boostedYieldsFactors(farmAddress: string): Promise<BoostedYieldsFactors> {
throw new Error('Method not implemented.');

Check warning on line 30 in src/modules/farm/mocks/farm.v2.abi.service.mock.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/mocks/farm.v2.abi.service.mock.ts#L30

Added line #L30 was not covered by tests
}

boostedYieldsRewardsPercenatage(farmAddress: string): Promise<number> {
throw new Error('Method not implemented.');

Check warning on line 34 in src/modules/farm/mocks/farm.v2.abi.service.mock.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/mocks/farm.v2.abi.service.mock.ts#L34

Added line #L34 was not covered by tests
}

energyFactoryAddress(farmAddress: string): Promise<string> {
throw new Error('Method not implemented.');

Check warning on line 38 in src/modules/farm/mocks/farm.v2.abi.service.mock.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/mocks/farm.v2.abi.service.mock.ts#L38

Added line #L38 was not covered by tests
}

lockEpochs(farmAddress: string): Promise<number> {
throw new Error('Method not implemented.');

Check warning on line 42 in src/modules/farm/mocks/farm.v2.abi.service.mock.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/mocks/farm.v2.abi.service.mock.ts#L42

Added line #L42 was not covered by tests
}

lockingScAddress(farmAddress: string): Promise<string> {
throw new Error('Method not implemented.');

Check warning on line 46 in src/modules/farm/mocks/farm.v2.abi.service.mock.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/mocks/farm.v2.abi.service.mock.ts#L46

Added line #L46 was not covered by tests
}
}


export const FarmAbiServiceProviderV2 = {
provide: FarmAbiServiceV2,
useClass: FarmAbiServiceMockV2,
};
2 changes: 2 additions & 0 deletions src/modules/farm/models/farm.v2.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export class FarmModelV2 extends BaseFarmModel {
@Field()
undistributedBoostedRewards: string;
@Field()
undistributedBoostedRewardsClaimed: string;
@Field()
energyFactoryAddress: string;
@Field()
rewardType: FarmRewardType;
Expand Down
81 changes: 81 additions & 0 deletions src/modules/farm/specs/farm.v2.compute.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { BigNumber } from 'bignumber.js';
import { Test, TestingModule } from '@nestjs/testing';
import { FarmComputeServiceV2 } from '../v2/services/farm.v2.compute.service';
import { CommonAppModule } from '../../../common.app.module';
import { CachingModule } from '../../../services/caching/cache.module';
import { FarmAbiServiceProviderV2 } from '../mocks/farm.v2.abi.service.mock';
import { FarmServiceV2 } from '../v2/services/farm.v2.service';
import { MXDataApiServiceProvider } from '../../../services/multiversx-communication/mx.data.api.service.mock';
import { WrapAbiServiceProvider } from '../../wrapping/mocks/wrap.abi.service.mock';
import { RouterAbiServiceProvider } from '../../router/mocks/router.abi.service.mock';
import { TokenComputeService } from '../../tokens/services/token.compute.service';
import { TokenGetterServiceProvider } from '../../tokens/mocks/token.getter.service.mock';
import { PairComputeServiceProvider } from '../../pair/mocks/pair.compute.service.mock';
import { PairAbiServiceProvider } from '../../pair/mocks/pair.abi.service.mock';
import { PairService } from '../../pair/services/pair.service';
import { ContextGetterServiceProvider } from '../../../services/context/mocks/context.getter.service.mock';
import { MXApiServiceProvider } from '../../../services/multiversx-communication/mx.api.service.mock';
import {
WeekTimekeepingAbiServiceProvider,
} from '../../../submodules/week-timekeeping/mocks/week.timekeeping.abi.service.mock';
import {
WeekTimekeepingComputeService,
} from '../../../submodules/week-timekeeping/services/week-timekeeping.compute.service';
import {
WeeklyRewardsSplittingAbiServiceProvider,
} from '../../../submodules/weekly-rewards-splitting/mocks/weekly.rewards.splitting.abi.mock';
import {
WeeklyRewardsSplittingComputeService,
} from '../../../submodules/weekly-rewards-splitting/services/weekly-rewards-splitting.compute.service';
import { EnergyAbiServiceProvider } from '../../energy/mocks/energy.abi.service.mock';

describe('FarmServiceV2', () => {
let module: TestingModule;

beforeEach(async () => {
module = await Test.createTestingModule({
imports: [CommonAppModule, CachingModule],
providers: [
MXApiServiceProvider,
ContextGetterServiceProvider,
PairService,
PairAbiServiceProvider,
PairComputeServiceProvider,
TokenGetterServiceProvider,
TokenComputeService,
RouterAbiServiceProvider,
WrapAbiServiceProvider,
MXDataApiServiceProvider,
WeekTimekeepingAbiServiceProvider,
WeekTimekeepingComputeService,
WeeklyRewardsSplittingAbiServiceProvider,
EnergyAbiServiceProvider,
WeeklyRewardsSplittingComputeService,
FarmComputeServiceV2,
FarmAbiServiceProviderV2,
FarmServiceV2,
],
}).compile();
});
it("should correctly calculate total rewards", async () => {
const service = module.get<FarmComputeServiceV2>(
FarmComputeServiceV2,
);
const result = await service.undistributedBoostedRewards('erd18h5dulxp5zdp80qjndd2w25kufx0rm5yqd2h7ajrfucjhr82y8vqyq0hye', 10);
const expectedTotal = new BigNumber('5000').plus('4000').integerValue().toFixed(); // 4 weeks * 1000
expect(result).toEqual(expectedTotal);
// expect(mockFarmAbi.undistributedBoostedRewards).toHaveBeenCalled();
claudiulataretu marked this conversation as resolved.
Show resolved Hide resolved
// expect(mockFarmAbi.lastUndistributedBoostedRewardsCollectWeek).toHaveBeenCalled();
// expect(mockFarmAbi.remainingBoostedRewardsToDistribute).toHaveBeenCalledTimes(4);
});
// it("should return undistributedBoostedRewards if firstWeek > lastWeek", async () => {
// const service = module.get<FarmComputeServiceV2>(
// FarmComputeServiceV2,
// );
// const result = await service.computeUndistributedBoostedRewards('erd18h5dulxp5zdp80qjndd2w25kufx0rm5yqd2h7ajrfucjhr82y8vqyq0hye', 5);
// expect(result).toEqual('5000');
// // expect(mockFarmAbi.undistributedBoostedRewards).toHaveBeenCalled();
// // expect(mockFarmAbi.lastUndistributedBoostedRewardsCollectWeek).toHaveBeenCalled();
// }, 10000);
});

18 changes: 16 additions & 2 deletions src/modules/farm/v2/farm.v2.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
import { BoostedYieldsFactors, FarmModelV2 } from '../models/farm.v2.model';
import { FarmResolver } from '../base-module/farm.resolver';
import { FarmServiceV2 } from './services/farm.v2.service';
import { GlobalInfoByWeekModel } from '../../../submodules/weekly-rewards-splitting/models/weekly-rewards-splitting.model';
import {
GlobalInfoByWeekModel,
} from '../../../submodules/weekly-rewards-splitting/models/weekly-rewards-splitting.model';
import { WeekTimekeepingModel } from '../../../submodules/week-timekeeping/models/week-timekeeping.model';
import { FarmComputeServiceV2 } from './services/farm.v2.compute.service';
import { constantsConfig } from '../../../config';
import { WeekTimekeepingAbiService } from 'src/submodules/week-timekeeping/services/week-timekeeping.abi.service';
import { WeeklyRewardsSplittingAbiService } from 'src/submodules/weekly-rewards-splitting/services/weekly-rewards-splitting.abi.service';
import {
WeeklyRewardsSplittingAbiService,
} from 'src/submodules/weekly-rewards-splitting/services/weekly-rewards-splitting.abi.service';
import { FarmAbiServiceV2 } from './services/farm.v2.abi.service';

@Resolver(() => FarmModelV2)
Expand Down Expand Up @@ -110,6 +114,16 @@ export class FarmResolverV2 extends FarmResolver {
@ResolveField()
async undistributedBoostedRewards(
@Parent() parent: FarmModelV2,
): Promise<string> {
const currentWeek = await this.weekTimekeepingAbi.currentWeek(
parent.address,
);
return this.farmCompute.undistributedBoostedRewards(parent.address, currentWeek);
}

@ResolveField()
async undistributedBoostedRewardsClaimed(
@Parent() parent: FarmModelV2,
): Promise<string> {
return this.farmAbi.undistributedBoostedRewards(parent.address);
}
Expand Down
17 changes: 17 additions & 0 deletions src/modules/farm/v2/services/farm.v2.abi.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,23 @@
return response.firstValue.valueOf().toFixed();
}

@ErrorLoggerAsync({
className: FarmAbiServiceV2.name,
logArgs: true,
})
@GetOrSetCache({
baseKey: 'farm',
remoteTtl: CacheTtlInfo.ContractState.remoteTtl,
localTtl: CacheTtlInfo.ContractState.localTtl,
})
async lastUndistributedBoostedRewardsCollectWeek(
farmAddress: string,
): Promise<number> {
return this.gatewayService.getSCStorageKey(farmAddress,

Check warning on line 199 in src/modules/farm/v2/services/farm.v2.abi.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/v2/services/farm.v2.abi.service.ts#L199

Added line #L199 was not covered by tests
'lastUndistributedBoostedRewardsCollectWeek'
);
}

@ErrorLoggerAsync({
className: FarmAbiServiceV2.name,
logArgs: true,
Expand Down
71 changes: 67 additions & 4 deletions src/modules/farm/v2/services/farm.v2.compute.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Inject, Injectable, forwardRef } from '@nestjs/common';
import { forwardRef, Inject, Injectable } from '@nestjs/common';
import { FarmComputeService } from '../../base-module/services/farm.compute.service';
import BigNumber from 'bignumber.js';
import { EsdtTokenPayment } from '../../../../models/esdtTokenPayment.model';
Expand All @@ -8,16 +8,22 @@
import { CalculateRewardsArgs } from '../../models/farm.args';
import { PairService } from '../../../pair/services/pair.service';
import { ContextGetterService } from '../../../../services/context/context.getter.service';
import { WeekTimekeepingComputeService } from 'src/submodules/week-timekeeping/services/week-timekeeping.compute.service';
import { WeeklyRewardsSplittingAbiService } from 'src/submodules/weekly-rewards-splitting/services/weekly-rewards-splitting.abi.service';
import {
WeekTimekeepingComputeService,
} from 'src/submodules/week-timekeeping/services/week-timekeeping.compute.service';
import {
WeeklyRewardsSplittingAbiService,
} from 'src/submodules/weekly-rewards-splitting/services/weekly-rewards-splitting.abi.service';
import { FarmAbiServiceV2 } from './farm.v2.abi.service';
import { FarmServiceV2 } from './farm.v2.service';
import { ErrorLoggerAsync } from 'src/helpers/decorators/error.logger';
import { GetOrSetCache } from 'src/helpers/decorators/caching.decorator';
import { CacheTtlInfo } from 'src/services/caching/cache.ttl.info';
import { CachingService } from 'src/services/caching/cache.service';
import { TokenDistributionModel } from 'src/submodules/weekly-rewards-splitting/models/weekly-rewards-splitting.model';
import { WeeklyRewardsSplittingComputeService } from 'src/submodules/weekly-rewards-splitting/services/weekly-rewards-splitting.compute.service';
import {
WeeklyRewardsSplittingComputeService,
} from 'src/submodules/weekly-rewards-splitting/services/weekly-rewards-splitting.compute.service';
import { IFarmComputeServiceV2 } from './interfaces';

@Injectable()
Expand Down Expand Up @@ -457,6 +463,63 @@
.toFixed();
}

@ErrorLoggerAsync({
className: FarmComputeServiceV2.name,
logArgs: true,
})
@GetOrSetCache({
baseKey: 'farm',
remoteTtl: CacheTtlInfo.ContractState.remoteTtl,
localTtl: CacheTtlInfo.ContractState.localTtl,
})
async undistributedBoostedRewards(
scAddress: string,
currentWeek: number,
): Promise<string> {
const amount = await this.undistributedBoostedRewardsRaw(

Check warning on line 479 in src/modules/farm/v2/services/farm.v2.compute.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/v2/services/farm.v2.compute.service.ts#L479

Added line #L479 was not covered by tests
scAddress,
currentWeek,
);
return amount.integerValue().toFixed();

Check warning on line 483 in src/modules/farm/v2/services/farm.v2.compute.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/v2/services/farm.v2.compute.service.ts#L483

Added line #L483 was not covered by tests
}

async undistributedBoostedRewardsRaw(
scAddress: string,
currentWeek: number,
): Promise<BigNumber> {
const [
undistributedBoostedRewards,
lastUndistributedBoostedRewardsCollectWeek,
] = await Promise.all([

Check warning on line 493 in src/modules/farm/v2/services/farm.v2.compute.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/v2/services/farm.v2.compute.service.ts#L493

Added line #L493 was not covered by tests
this.farmAbi.undistributedBoostedRewards(scAddress),
this.farmAbi.lastUndistributedBoostedRewardsCollectWeek(
scAddress,
),
]);

const firstWeek = lastUndistributedBoostedRewardsCollectWeek + 1;
const lastWeek = currentWeek - constantsConfig.USER_MAX_CLAIM_WEEKS - 1;

Check warning on line 501 in src/modules/farm/v2/services/farm.v2.compute.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/v2/services/farm.v2.compute.service.ts#L500-L501

Added lines #L500 - L501 were not covered by tests
if (firstWeek > lastWeek) {
return new BigNumber(undistributedBoostedRewards);

Check warning on line 503 in src/modules/farm/v2/services/farm.v2.compute.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/v2/services/farm.v2.compute.service.ts#L503

Added line #L503 was not covered by tests
}
const promises = []
for (let week = firstWeek; week <= lastWeek; week++) {
promises.push(

Check warning on line 507 in src/modules/farm/v2/services/farm.v2.compute.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/v2/services/farm.v2.compute.service.ts#L505-L507

Added lines #L505 - L507 were not covered by tests
this.farmAbi.remainingBoostedRewardsToDistribute(
scAddress,
week,
)
)
}
const remainingRewards = await Promise.all(promises);
const totalRemainingRewards = remainingRewards.reduce((acc, curr) => {
return new BigNumber(acc).plus(curr);

Check warning on line 516 in src/modules/farm/v2/services/farm.v2.compute.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/v2/services/farm.v2.compute.service.ts#L514-L516

Added lines #L514 - L516 were not covered by tests
});
return new BigNumber(undistributedBoostedRewards)

Check warning on line 518 in src/modules/farm/v2/services/farm.v2.compute.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/farm/v2/services/farm.v2.compute.service.ts#L518

Added line #L518 was not covered by tests
.plus(totalRemainingRewards);

}

async computeBlocksInWeek(
scAddress: string,
week: number,
Expand Down
8 changes: 4 additions & 4 deletions src/modules/farm/v2/services/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { TokenDistributionModel } from 'src/submodules/weekly-rewards-splitting/models/weekly-rewards-splitting.model';
import {
IFarmAbiService,
IFarmComputeService,
} from '../../base-module/services/interfaces';
import { IFarmAbiService, IFarmComputeService } from '../../base-module/services/interfaces';
import { BoostedYieldsFactors } from '../../models/farm.v2.model';
import { EsdtTokenPayment } from '../../../../models/esdtTokenPayment.model';

Expand All @@ -14,6 +11,9 @@ export interface IFarmAbiServiceV2 extends IFarmAbiService {
farmAddress: string,
week: number,
): Promise<string>;
lastUndistributedBoostedRewardsCollectWeek(
farmAddress: string,
): Promise<number>;
undistributedBoostedRewards(farmAddress: string): Promise<string>;
boostedYieldsFactors(farmAddress: string): Promise<BoostedYieldsFactors>;
accumulatedRewardsForWeek(scAddress: string, week: number): Promise<string>;
Expand Down
5 changes: 2 additions & 3 deletions src/modules/rabbitmq/handlers/router.handler.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
} from '@multiversx/sdk-exchange';
import { Inject, Injectable } from '@nestjs/common';
import { RedisPubSub } from 'graphql-redis-subscriptions';
import { constantsConfig } from 'src/config';
import { PUB_SUB } from 'src/services/redis.pubSub.module';
import { generateCacheKeyFromParams } from 'src/utils/generate-cache-key';
import { RouterAbiService } from '../../router/services/router.abi.service';
Expand Down Expand Up @@ -45,8 +44,8 @@ export class RouterHandlerService {
uniqueTokens,
commonTokens,
] = await Promise.all([
this.routerAbiService.pairsMetadata(),
this.routerAbiService.pairsAddress(),
this.routerAbiService.getPairsMetadataRaw(),
this.routerAbiService.getAllPairsAddressRaw(),
this.tokenGetter.getEsdtTokenType(firstTokenID),
this.tokenGetter.getEsdtTokenType(secondTokenID),
this.tokenService.getUniqueTokenIDs(true),
Expand Down
2 changes: 1 addition & 1 deletion src/modules/rabbitmq/rabbitmq.consumer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ export class RabbitMqConsumer {

async getFilterAddresses(): Promise<void> {
this.filterAddresses = [];
this.filterAddresses = await this.routerAbi.pairsAddress();
this.filterAddresses = await this.routerAbi.getAllPairsAddressRaw();
this.filterAddresses.push(...farmsAddresses());
this.filterAddresses.push(scAddress.routerAddress);
this.filterAddresses.push(scAddress.metabondingStakingAddress);
Expand Down
13 changes: 12 additions & 1 deletion src/modules/tokens/services/token.compute.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
}

const pairsMetadata = await this.routerAbi.pairsMetadata();
const tokenPairs: PairMetadata[] = [];
let tokenPairs: PairMetadata[] = [];
for (const pair of pairsMetadata) {
if (
pair.firstTokenID === tokenID ||
Expand All @@ -46,6 +46,17 @@
}
}

if (tokenPairs.length > 1) {
const states = await Promise.all(
tokenPairs.map((pair) => this.pairAbi.state(pair.address)),

Check warning on line 51 in src/modules/tokens/services/token.compute.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/tokens/services/token.compute.service.ts#L50-L51

Added lines #L50 - L51 were not covered by tests
);
if (states.find((state) => state === 'Active')) {
tokenPairs = tokenPairs.filter((pair, index) => {
return states[index] === 'Active';

Check warning on line 55 in src/modules/tokens/services/token.compute.service.ts

View check run for this annotation

Codecov / codecov/patch

src/modules/tokens/services/token.compute.service.ts#L54-L55

Added lines #L54 - L55 were not covered by tests
});
}
}

let largestLiquidityEGLD = new BigNumber(0);
let priceSoFar = '0';

Expand Down
Loading