Skip to content

Commit 58a4414

Browse files
authored
Remove temporal fix for cancelation refunds (#3731)
1 parent 1263e6e commit 58a4414

2 files changed

Lines changed: 15 additions & 135 deletions

File tree

‎packages/apps/job-launcher/server/src/modules/job/job.service.spec.ts‎

Lines changed: 5 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1660,62 +1660,17 @@ describe('JobService', () => {
16601660
expect(mockJobRepository.updateOne).toHaveBeenCalledWith(jobEntity);
16611661
});
16621662

1663-
it('should not create a refund and set status to CANCELED when no refund is found', async () => {
1663+
it('should throw ConflictError when no refund is found', async () => {
16641664
const jobEntity = createJobEntity();
16651665
mockPaymentService.getJobPayments.mockResolvedValueOnce([]);
16661666
mockedEscrowUtils.getCancellationRefund.mockResolvedValueOnce(
16671667
null as any,
16681668
);
16691669

1670-
jest
1671-
.spyOn(jobService as any, 'getRefundAmount')
1672-
.mockResolvedValueOnce(0n);
1673-
1674-
mockJobRepository.updateOne.mockResolvedValueOnce(jobEntity);
1675-
1676-
await jobService.cancelJob(jobEntity);
1677-
1678-
expect(mockPaymentService.getJobPayments).toHaveBeenCalledWith(
1679-
jobEntity.id,
1680-
PaymentType.SLASH,
1681-
);
1682-
expect(EscrowUtils.getCancellationRefund).toHaveBeenCalledWith(
1683-
jobEntity.chainId,
1684-
jobEntity.escrowAddress,
1685-
);
1686-
expect(mockPaymentService.createRefundPayment).not.toHaveBeenCalled();
1687-
expect(jobEntity.status).toBe(JobStatus.CANCELED);
1688-
expect(mockJobRepository.updateOne).toHaveBeenCalledWith(jobEntity);
1689-
});
1690-
1691-
it('should create a refund when on-chain refund amount is greater than 0', async () => {
1692-
const jobEntity = createJobEntity();
1693-
const tokenDecimals = (TOKEN_ADDRESSES[jobEntity.chainId as ChainId] ??
1694-
{})[jobEntity.token as EscrowFundToken]?.decimals;
1695-
1696-
mockPaymentService.getJobPayments.mockResolvedValueOnce([]);
1697-
mockedEscrowUtils.getCancellationRefund.mockResolvedValueOnce(
1698-
null as any,
1670+
await expect(jobService.cancelJob(jobEntity)).rejects.toThrow(
1671+
new ConflictError(ErrorJob.NoRefundFound),
16991672
);
17001673

1701-
const refundAmount = faker.number.float({
1702-
min: 1,
1703-
max: 10,
1704-
fractionDigits: tokenDecimals,
1705-
});
1706-
1707-
// Mock on-chain refund lookup to return a positive amount
1708-
jest
1709-
.spyOn(jobService as any, 'getRefundAmount')
1710-
.mockResolvedValueOnce(
1711-
ethers.parseUnits(refundAmount.toString(), tokenDecimals),
1712-
);
1713-
1714-
mockPaymentService.createRefundPayment.mockResolvedValueOnce(undefined);
1715-
mockJobRepository.updateOne.mockResolvedValueOnce(jobEntity);
1716-
1717-
await jobService.cancelJob(jobEntity);
1718-
17191674
expect(mockPaymentService.getJobPayments).toHaveBeenCalledWith(
17201675
jobEntity.id,
17211676
PaymentType.SLASH,
@@ -1724,14 +1679,8 @@ describe('JobService', () => {
17241679
jobEntity.chainId,
17251680
jobEntity.escrowAddress,
17261681
);
1727-
expect(mockPaymentService.createRefundPayment).toHaveBeenCalledWith({
1728-
refundAmount: refundAmount,
1729-
refundCurrency: jobEntity.token,
1730-
userId: jobEntity.userId,
1731-
jobId: jobEntity.id,
1732-
});
1733-
expect(jobEntity.status).toBe(JobStatus.CANCELED);
1734-
expect(mockJobRepository.updateOne).toHaveBeenCalledWith(jobEntity);
1682+
expect(mockPaymentService.createRefundPayment).not.toHaveBeenCalled();
1683+
expect(mockJobRepository.updateOne).not.toHaveBeenCalled();
17351684
});
17361685

17371686
it('should throw ConflictError if refund.amount is empty', async () => {

‎packages/apps/job-launcher/server/src/modules/job/job.service.ts‎

Lines changed: 10 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
import { Escrow, Escrow__factory } from '@human-protocol/core/typechain-types';
21
import {
32
ChainId,
43
EscrowClient,
54
EscrowStatus,
65
EscrowUtils,
7-
ICancellationRefund,
86
KVStoreKeys,
97
KVStoreUtils,
108
NETWORKS,
@@ -863,35 +861,20 @@ export class JobService {
863861
PaymentType.SLASH,
864862
);
865863
if (!slash?.length) {
866-
let refund: ICancellationRefund | null = null;
867-
try {
868-
refund = await EscrowUtils.getCancellationRefund(
869-
jobEntity.chainId,
870-
jobEntity.escrowAddress!,
871-
);
872-
} catch {
873-
// Ignore error
874-
}
875-
876-
let amount = 0n;
864+
const refund = await EscrowUtils.getCancellationRefund(
865+
jobEntity.chainId,
866+
jobEntity.escrowAddress!,
867+
);
877868

878-
if (!refund) {
879-
//Temp fix
880-
amount = await this.getRefundAmount(
881-
jobEntity.chainId,
882-
jobEntity.escrowAddress!,
883-
token.address,
884-
);
885-
} else {
886-
if (!refund.amount) {
887-
throw new ConflictError(ErrorJob.NoRefundFound);
888-
}
889-
amount = refund.amount;
869+
if (!refund || !refund.amount) {
870+
throw new ConflictError(ErrorJob.NoRefundFound);
890871
}
891872

892-
if (amount > 0n) {
873+
if (refund.amount > 0n) {
893874
await this.paymentService.createRefundPayment({
894-
refundAmount: Number(ethers.formatUnits(amount, token.decimals)),
875+
refundAmount: Number(
876+
ethers.formatUnits(refund.amount, token.decimals),
877+
),
895878
refundCurrency: jobEntity.token,
896879
userId: jobEntity.userId,
897880
jobId: jobEntity.id,
@@ -902,56 +885,4 @@ export class JobService {
902885
jobEntity.status = JobStatus.CANCELED;
903886
await this.jobRepository.updateOne(jobEntity);
904887
}
905-
906-
public async getRefundAmount(
907-
chainId: ChainId,
908-
escrowAddress: string,
909-
tokenAddress: string,
910-
): Promise<bigint> {
911-
const signer = this.web3Service.getSigner(chainId);
912-
const provider = signer.provider!;
913-
const contract: Escrow = Escrow__factory.connect(escrowAddress!, provider);
914-
const fromBlock = 79278120; //This issue started at this block
915-
const toBlock = 'latest';
916-
const cancelledFilter = contract.filters?.Cancelled?.();
917-
const cancelledLogs = await contract.queryFilter(
918-
cancelledFilter,
919-
fromBlock,
920-
toBlock,
921-
);
922-
923-
for (const log of cancelledLogs) {
924-
const erc20Interface = new ethers.Interface([
925-
'event Transfer(address indexed from, address indexed to, uint256 value)',
926-
]);
927-
928-
const transferTopic = erc20Interface.getEvent('Transfer')!.topicHash;
929-
const receipt = await provider.getTransactionReceipt(log.transactionHash);
930-
931-
const transferLogs = receipt!.logs.filter(
932-
(l) =>
933-
l.address.toLowerCase() === tokenAddress.toLowerCase() &&
934-
l.topics[0] === transferTopic,
935-
);
936-
for (const tlog of transferLogs) {
937-
const decoded = erc20Interface.decodeEventLog(
938-
'Transfer',
939-
tlog.data,
940-
tlog.topics,
941-
);
942-
943-
const from = decoded.from as string;
944-
const to = decoded.to as string;
945-
const value = decoded.value as bigint;
946-
if (
947-
from.toLowerCase() === escrowAddress.toLowerCase() &&
948-
to.toLowerCase() === (await signer.getAddress()).toLowerCase()
949-
) {
950-
return value;
951-
}
952-
}
953-
}
954-
955-
return 0n;
956-
}
957888
}

0 commit comments

Comments
 (0)