Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ describe('AssignmentService', () => {
requesterTitle: 'Example Title',
requesterDescription: 'Example Description',
submissionsRequired: 5,
fundAmount: 100,
};

beforeAll(async () => {
Expand All @@ -128,6 +127,7 @@ describe('AssignmentService', () => {
.mockResolvedValue(null);
jest.spyOn(assignmentRepository, 'countByJobId').mockResolvedValue(0);
jest.spyOn(jobService, 'getManifest').mockResolvedValue(manifest);
jest.spyOn(jobService, 'getRewardAmount').mockResolvedValue(20);
(Escrow__factory.connect as any).mockImplementation(() => ({
duration: jest
.fn()
Expand All @@ -150,13 +150,18 @@ describe('AssignmentService', () => {
workerAddress: workerAddress,
status: AssignmentStatus.ACTIVE,
expiresAt: expect.any(Date),
rewardAmount: manifest.fundAmount / manifest.submissionsRequired,
rewardAmount: 20,
});
expect(jobService.getManifest).toHaveBeenCalledWith(
chainId,
escrowAddress,
MOCK_MANIFEST_URL,
);
expect(jobService.getRewardAmount).toHaveBeenCalledWith(
chainId,
escrowAddress,
manifest.submissionsRequired,
);
});

it('should reassign user who has previously canceled', async () => {
Expand Down Expand Up @@ -371,7 +376,6 @@ describe('AssignmentService', () => {
requesterTitle: 'Example Title',
requesterDescription: 'Example Description',
submissionsRequired: 5,
fundAmount: 100,
};

jest.spyOn(jobService, 'getManifest').mockResolvedValue(manifest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ export class AssignmentService {
data.escrowAddress,
jobEntity.manifestUrl,
);
const rewardAmount = await this.jobService.getRewardAmount(
data.chainId,
data.escrowAddress,
manifest.submissionsRequired,
);

// Check if all required qualifications are present
const userQualificationsSet = new Set(jwtUser.qualifications);
Expand Down Expand Up @@ -110,8 +115,7 @@ export class AssignmentService {
newAssignmentEntity.job = jobEntity;
newAssignmentEntity.workerAddress = jwtUser.address;
newAssignmentEntity.status = AssignmentStatus.ACTIVE;
newAssignmentEntity.rewardAmount =
manifest.fundAmount / manifest.submissionsRequired;
newAssignmentEntity.rewardAmount = rewardAmount;
newAssignmentEntity.expiresAt = expirationDate;
return this.assignmentRepository.createUnique(newAssignmentEntity);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export class ManifestDto {
requesterTitle: string;
requesterDescription: string;
submissionsRequired: number;
fundAmount: number;
qualifications?: string[];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,6 @@ describe('JobService', () => {
requesterTitle: 'Example Title',
requesterDescription: 'Example Description',
submissionsRequired: 5,
fundAmount: 100,
};

jest.spyOn(jobService, 'getManifest').mockResolvedValue(manifest);
Expand Down Expand Up @@ -473,7 +472,6 @@ describe('JobService', () => {
requesterTitle: 'Example Title',
requesterDescription: 'Example Description',
submissionsRequired: 5,
fundAmount: 100,
};

jest
Expand Down Expand Up @@ -531,7 +529,6 @@ describe('JobService', () => {
requesterTitle: 'Example Title',
requesterDescription: 'Example Description',
submissionsRequired: 1,
fundAmount: 100,
};

assignment.status = AssignmentStatus.ACTIVE;
Expand Down Expand Up @@ -564,7 +561,6 @@ describe('JobService', () => {
requesterTitle: 'Example Title',
requesterDescription: 'Example Description',
submissionsRequired: 5,
fundAmount: 100,
};

assignment.status = AssignmentStatus.ACTIVE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import {
Encryption,
EncryptionUtils,
EscrowClient,
EscrowUtils,
} from '@human-protocol/sdk';
import { Inject, Injectable } from '@nestjs/common';
import { ethers } from 'ethers';

import { downloadFileFromUrl } from '../../common/utils/storage';
import { PGPConfigService } from '../../common/config/pgp-config.service';
import { ErrorAssignment, ErrorJob } from '../../common/constant/errors';
import { SortDirection } from '../../common/enums/collection';
Expand All @@ -30,6 +31,7 @@ import {
} from '../../common/errors';
import { ISolution } from '../../common/interfaces/job';
import { PageDto } from '../../common/pagination/pagination.dto';
import { downloadFileFromUrl } from '../../common/utils/storage';
import { AssignmentEntity } from '../assignment/assignment.entity';
import { AssignmentRepository } from '../assignment/assignment.repository';
import { StorageService } from '../storage/storage.service';
Expand Down Expand Up @@ -184,7 +186,11 @@ export class JobService {
data.sortField === JobSortField.REWARD_AMOUNT
) {
job.rewardAmount = (
manifest.fundAmount / manifest.submissionsRequired
await this.getRewardAmount(
entity.chainId,
entity.escrowAddress,
manifest.submissionsRequired,
)
).toString();
}
if (data.fields?.includes(JobFieldName.RewardToken)) {
Expand Down Expand Up @@ -383,4 +389,25 @@ export class JobService {

return manifest;
}

public async getRewardAmount(
chainId: number,
escrowAddress: string,
submissionsRequired: number,
): Promise<number> {
const escrow = await EscrowUtils.getEscrow(chainId, escrowAddress);
if (!escrow) {
throw new NotFoundError(ErrorJob.NotFound);
}

const decimals = await HMToken__factory.connect(
escrow.token,
this.web3Service.getSigner(chainId),
).decimals();

return (
Number(ethers.formatUnits(escrow.totalFundedAmount, decimals)) /
submissionsRequired
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export class Web3Service {

private signers: { [key: number]: Wallet } = {};
readonly signerAddress: string;
readonly currentWeb3Env: string;

constructor(
private readonly web3ConfigService: Web3ConfigService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export interface IManifest {
submissionsRequired: number;
requesterTitle: string;
requesterDescription: string;
fundAmount: string;
requestType: JobRequestType;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import { StorageService } from '../storage/storage.service';
import { Web3Service } from '../web3/web3.service';
import { WebhookDto } from '../webhook/webhook.dto';
import { JobService } from './job.service';
import { HMToken__factory } from '@human-protocol/core/typechain-types';
import { downloadFileFromUrl } from '@/common/utils/storage';

jest.mock('minio', () => {
Expand All @@ -61,6 +60,11 @@ jest.mock('@human-protocol/sdk', () => ({
EscrowClient: {
build: jest.fn().mockImplementation(() => ({})),
},
EscrowUtils: {
getEscrow: jest.fn().mockResolvedValue({
totalFundedAmount: 8n,
}),
},
KVStoreUtils: {
get: jest.fn(),
getPublicKey: jest.fn().mockResolvedValue('publicKey'),
Expand Down Expand Up @@ -130,13 +134,6 @@ describe('JobService', () => {
});

describe('processJobSolution', () => {
beforeAll(() => {
const decimalsMock = jest.fn().mockResolvedValue(18);
const tokenContractMock = { decimals: decimalsMock };
jest
.spyOn(HMToken__factory, 'connect')
.mockReturnValue(tokenContractMock as any);
});
afterEach(() => {
jest.clearAllMocks();
});
Expand Down Expand Up @@ -241,7 +238,6 @@ describe('JobService', () => {
submissionsRequired: 2,
requesterTitle: MOCK_REQUESTER_TITLE,
requesterDescription: MOCK_REQUESTER_DESCRIPTION,
fundAmount: '10',
requestType: JobRequestType.FORTUNE,
};

Expand Down Expand Up @@ -303,7 +299,6 @@ describe('JobService', () => {
submissionsRequired: 2,
requesterTitle: MOCK_REQUESTER_TITLE,
requesterDescription: MOCK_REQUESTER_DESCRIPTION,
fundAmount: '10',
requestType: JobRequestType.FORTUNE,
};

Expand All @@ -316,7 +311,6 @@ describe('JobService', () => {
.fn()
.mockResolvedValue('http://example.com/results'),
storeResults: jest.fn().mockResolvedValue(true),
getTokenAddress: jest.fn().mockResolvedValue(MOCK_ADDRESS),
};
(EscrowClient.build as jest.Mock).mockResolvedValue(escrowClient);

Expand Down Expand Up @@ -370,15 +364,13 @@ describe('JobService', () => {
getManifest: jest.fn().mockResolvedValue('http://example.com/manifest'),
getIntermediateResultsUrl: jest.fn().mockResolvedValue(''),
storeResults: jest.fn().mockResolvedValue(true),
getTokenAddress: jest.fn().mockResolvedValue(MOCK_ADDRESS),
};
(EscrowClient.build as jest.Mock).mockResolvedValue(escrowClient);

const manifest: IManifest = {
submissionsRequired: 3,
requesterTitle: MOCK_REQUESTER_TITLE,
requesterDescription: MOCK_REQUESTER_DESCRIPTION,
fundAmount: '10',
requestType: JobRequestType.FORTUNE,
};

Expand Down Expand Up @@ -426,7 +418,6 @@ describe('JobService', () => {
.fn()
.mockResolvedValue('http://existing-solutions'),
storeResults: jest.fn().mockResolvedValue(true),
getTokenAddress: jest.fn().mockResolvedValue(MOCK_ADDRESS),
};
(EscrowClient.build as jest.Mock).mockResolvedValue(escrowClient);

Expand All @@ -438,7 +429,6 @@ describe('JobService', () => {
submissionsRequired: 2,
requesterTitle: MOCK_REQUESTER_TITLE,
requesterDescription: MOCK_REQUESTER_DESCRIPTION,
fundAmount: '10',
requestType: JobRequestType.FORTUNE,
};

Expand Down Expand Up @@ -504,15 +494,13 @@ describe('JobService', () => {
.fn()
.mockResolvedValue('http://existing-solutions'),
storeResults: jest.fn().mockResolvedValue(true),
getTokenAddress: jest.fn().mockResolvedValue(MOCK_ADDRESS),
};
(EscrowClient.build as jest.Mock).mockResolvedValue(escrowClient);

const manifest: IManifest = {
submissionsRequired: 4,
requesterTitle: MOCK_REQUESTER_TITLE,
requesterDescription: MOCK_REQUESTER_DESCRIPTION,
fundAmount: '10',
requestType: JobRequestType.FORTUNE,
};

Expand Down Expand Up @@ -594,7 +582,6 @@ describe('JobService', () => {
.fn()
.mockResolvedValue('http://existing-solutions'),
storeResults: jest.fn().mockResolvedValue(true),
getTokenAddress: jest.fn().mockResolvedValue(MOCK_ADDRESS),
};
(EscrowClient.build as jest.Mock).mockResolvedValue(escrowClient);
KVStoreUtils.get = jest
Expand All @@ -606,7 +593,6 @@ describe('JobService', () => {
submissionsRequired: 3,
requesterTitle: MOCK_REQUESTER_TITLE,
requesterDescription: MOCK_REQUESTER_DESCRIPTION,
fundAmount: '10',
requestType: JobRequestType.FORTUNE,
};

Expand Down Expand Up @@ -676,7 +662,6 @@ describe('JobService', () => {
.fn()
.mockResolvedValue('http://existing-solutions'),
storeResults: jest.fn().mockResolvedValue(true),
getTokenAddress: jest.fn().mockResolvedValue(MOCK_ADDRESS),
};
(EscrowClient.build as jest.Mock).mockResolvedValue(escrowClient);
KVStoreUtils.get = jest
Expand All @@ -688,7 +673,6 @@ describe('JobService', () => {
submissionsRequired: 3,
requesterTitle: MOCK_REQUESTER_TITLE,
requesterDescription: MOCK_REQUESTER_DESCRIPTION,
fundAmount: '10',
requestType: JobRequestType.FORTUNE,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
EscrowStatus,
KVStoreKeys,
KVStoreUtils,
EscrowUtils,
} from '@human-protocol/sdk';
import { HttpService } from '@nestjs/axios';
import { Inject, Injectable } from '@nestjs/common';
Expand All @@ -25,7 +26,6 @@ import {
SolutionEventData,
WebhookDto,
} from '../webhook/webhook.dto';
import { HMToken__factory } from '@human-protocol/core/typechain-types';

@Injectable()
export class JobService {
Expand Down Expand Up @@ -121,7 +121,7 @@ export class JobService {
}

const manifestUrl = await escrowClient.getManifest(webhook.escrowAddress);
const { submissionsRequired, requestType, fundAmount }: IManifest =
const { submissionsRequired, requestType }: IManifest =
await this.storageService.download(manifestUrl);

if (!submissionsRequired || !requestType) {
Expand Down Expand Up @@ -186,16 +186,16 @@ export class JobService {
s.solution === lastExchangeSolution.solution,
);

const tokenAddress = await escrowClient.getTokenAddress(
const escrow = await EscrowUtils.getEscrow(
webhook.chainId,
webhook.escrowAddress,
);
const tokenContract = HMToken__factory.connect(
tokenAddress,
this.web3Service.getSigner(webhook.chainId),
);
const decimals = await tokenContract.decimals();
const fundAmountInWei = ethers.parseUnits(fundAmount.toString(), decimals);
const amountToReserve = fundAmountInWei / BigInt(submissionsRequired);
if (!escrow) {
throw new ValidationError('Escrow not found');
}

const amountToReserve =
escrow.totalFundedAmount / BigInt(submissionsRequired);

await escrowClient.storeResults(
webhook.escrowAddress,
Expand Down
1 change: 0 additions & 1 deletion packages/apps/fortune/recording-oracle/test/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export const MOCK_MANIFEST: IManifest = {
submissionsRequired: 2,
requesterTitle: 'Fortune',
requesterDescription: 'Some desc',
fundAmount: '8',
requestType: JobRequestType.FORTUNE,
};
export const MOCK_ENCRYPTION_PRIVATE_KEY = 'private-key';
Expand Down
1 change: 0 additions & 1 deletion packages/apps/job-launcher/client/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export type FortuneManifest = {
submissionsRequired: number;
requesterTitle: string;
requesterDescription: string;
fundAmount?: number;
requestType: JobType.FORTUNE;
qualifications?: string[];
};
Expand Down
Loading
Loading