Skip to content
Merged
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 @@ -54,7 +54,7 @@ describe('DefaultPayoutsCalculator', () => {
.fn()
.mockImplementation(async () => reservedFunds);

beforeAll(() => {
beforeEach(() => {
mockedEscrowClient.build.mockResolvedValue({
getReservedFunds: mockedGetReservedFunds,
} as unknown as EscrowClient);
Expand Down Expand Up @@ -86,7 +86,50 @@ describe('DefaultPayoutsCalculator', () => {

const expectedPayouts = acceptedResults.map((result) => ({
address: result.workerAddress,
amount: reservedFunds / BigInt(manifest.submissionsRequired),
amount: reservedFunds / BigInt(acceptedResults.length),
}));

expect(normalizePayouts(payouts)).toEqual(
normalizePayouts(expectedPayouts),
);
});

it('should split reserved funds by accepted results when fewer than required submissions are accepted', async () => {
const acceptedCount = faker.number.int({ min: 1, max: 10 });
const rejectedCount = faker.number.int({ min: 1, max: 10 });
const submissionsRequired = faker.number.int({
min: acceptedCount + 1,
max: acceptedCount + 10,
});
const payoutAmount = BigInt(faker.number.int({ min: 1000, max: 100000 }));
const reservedFunds = payoutAmount * BigInt(acceptedCount);
const acceptedResults = Array.from({ length: acceptedCount }, () =>
generateFinalResult(VerificationResult.Accepted),
);
const rejectedResults = Array.from({ length: rejectedCount }, () =>
generateFinalResult(VerificationResult.Rejected),
);
const manifest: BaseManifest<MarketingJobType> = {
requestType: MarketingJobType.SOCIAL_MEDIA_PROMOTION,
submissionsRequired,
};

mockedGetReservedFunds.mockResolvedValueOnce(reservedFunds);
mockedStorageService.downloadJsonLikeData.mockResolvedValueOnce([
...acceptedResults,
...rejectedResults,
]);

const payouts = await calculator.calculate({
chainId: generateTestnetChainId(),
escrowAddress: faker.finance.ethereumAddress(),
finalResultsUrl: faker.internet.url(),
manifest,
});

const expectedPayouts = acceptedResults.map((result) => ({
address: result.workerAddress,
amount: payoutAmount,
}));

expect(normalizePayouts(payouts)).toEqual(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { EscrowClient } from '@human-protocol/sdk';
import { Injectable } from '@nestjs/common';

import {
BaseFinalResult,
FortuneManifest,
MarketingManifest,
VerificationResult,
} from '@/common/types';
import { BaseFinalResult, VerificationResult } from '@/common/types';
import { StorageService } from '@/modules/storage';
import { Web3Service } from '@/modules/web3';

Expand All @@ -16,8 +11,6 @@ import {
EscrowPayoutsCalculator,
} from './types';

type DefaultPayoutsManifest = FortuneManifest | MarketingManifest;

@Injectable()
export class DefaultPayoutsCalculator implements EscrowPayoutsCalculator {
constructor(
Expand All @@ -26,13 +19,10 @@ export class DefaultPayoutsCalculator implements EscrowPayoutsCalculator {
) {}

async calculate({
manifest,
chainId,
escrowAddress,
finalResultsUrl,
}: CalculatePayoutsInput & {
manifest: DefaultPayoutsManifest;
}): Promise<CalculatedPayout[]> {
}: CalculatePayoutsInput): Promise<CalculatedPayout[]> {
const signer = this.web3Service.getSigner(chainId);
const escrowClient = await EscrowClient.build(signer);
const finalResults =
Expand All @@ -51,7 +41,7 @@ export class DefaultPayoutsCalculator implements EscrowPayoutsCalculator {
}

const reservedFunds = await escrowClient.getReservedFunds(escrowAddress);
const payoutAmount = reservedFunds / BigInt(manifest.submissionsRequired);
const payoutAmount = reservedFunds / BigInt(recipients.length);

return recipients.map((recipient) => ({
address: recipient,
Expand Down
Loading