Skip to content

Commit

Permalink
Merge pull request #1104 from multiversx/feat/governance-v2
Browse files Browse the repository at this point in the history
Merge feat/governance-v2 into development
  • Loading branch information
claudiulataretu authored Jul 17, 2023
2 parents b80eac4 + 8614afc commit 95782e2
Show file tree
Hide file tree
Showing 50 changed files with 2,074 additions and 423 deletions.
775 changes: 775 additions & 0 deletions src/abis/governance-v2.abi.json

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,8 @@
"energyUpdate": "./src/abis/energy-update.abi.json",
"tokenUnstake": "./src/abis/token-unstake.abi.json",
"lockedTokenWrapper": "./src/abis/locked-token-wrapper.abi.json",
"escrow": "./src/abis/lkmex-transfer.abi.json"
"escrow": "./src/abis/lkmex-transfer.abi.json",
"governance": "./src/abis/governance-v2.abi.json"
},
"cron": {
"transactionCollectorMaxHyperblocks": 10,
Expand Down
8 changes: 7 additions & 1 deletion src/config/devnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,13 @@
"energyUpdate": "erd1qqqqqqqqqqqqqpgqqns0u3hw0e3j0km9h77emuear4xq7k7fd8ss0cwgja",
"tokenUnstake": "erd1qqqqqqqqqqqqqpgqnysvq99c2t4a9pvvv22elnl6p73el8vw0n4spyfv7p",
"lockedTokenWrapper": "erd1qqqqqqqqqqqqqpgq9ej9vcnr38l69rgkc735kgv0qlu2ptrsd8ssu9rwtu",
"escrow": "erd1qqqqqqqqqqqqqpgqz0wkk0j6y4h0mcxfxsg023j4x5sfgrmz0n4s4swp7a"
"escrow": "erd1qqqqqqqqqqqqqpgqz0wkk0j6y4h0mcxfxsg023j4x5sfgrmz0n4s4swp7a",
"governance": {
"energy": [
"erd1qqqqqqqqqqqqqpgqu5u5kgmjm067dhwdfe4l3flwmadm2nqlczfskufug3"
],
"token": []
}
},
"farms": {
"v1.2": [],
Expand Down
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;
}
async undistributedBoostedRewards(farmAddress: string): Promise<string> {
return '5000';
}
async remainingBoostedRewardsToDistribute(
farmAddress: string,
week: number,
): Promise<string> {
return '1000';
}

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

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

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

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

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

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


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();
// 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 @@ export class FarmAbiServiceV2
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,
'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 { constantsConfig } from '../../../../config';
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 @@ export class FarmComputeServiceV2
.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(
scAddress,
currentWeek,
);
return amount.integerValue().toFixed();
}

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

const firstWeek = lastUndistributedBoostedRewardsCollectWeek + 1;
const lastWeek = currentWeek - constantsConfig.USER_MAX_CLAIM_WEEKS - 1;
if (firstWeek > lastWeek) {
return new BigNumber(undistributedBoostedRewards);
}
const promises = []
for (let week = firstWeek; week <= lastWeek; week++) {
promises.push(
this.farmAbi.remainingBoostedRewardsToDistribute(
scAddress,
week,
)
)
}
const remainingRewards = await Promise.all(promises);
const totalRemainingRewards = remainingRewards.reduce((acc, curr) => {
return new BigNumber(acc).plus(curr);
});
return new BigNumber(undistributedBoostedRewards)
.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
Loading

0 comments on commit 95782e2

Please sign in to comment.