diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 461a70a00..240369006 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -57,7 +57,12 @@ export const executeTransaction = async ( // validate amount const receivedCallDate = new Date() - const sendBalance = await calculateBalance(sender.id, amount.mul(-1), receivedCallDate) + const sendBalance = await calculateBalance( + sender.id, + amount.mul(-1), + receivedCallDate, + transactionLink, + ) if (!sendBalance) { throw new Error("user hasn't enough GDD or amount is < 0") } diff --git a/backend/src/util/validate.ts b/backend/src/util/validate.ts index 95e1bf699..8d1c90ca4 100644 --- a/backend/src/util/validate.ts +++ b/backend/src/util/validate.ts @@ -4,6 +4,7 @@ import { Transaction } from '@entity/Transaction' import { Decay } from '@model/Decay' import { getCustomRepository } from '@dbTools/typeorm' import { TransactionLinkRepository } from '@repository/TransactionLink' +import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink' function isStringBoolean(value: string): boolean { const lowerValue = value.toLowerCase() @@ -21,6 +22,7 @@ async function calculateBalance( userId: number, amount: Decimal, time: Date, + transactionLink?: dbTransactionLink | null, ): Promise<{ balance: Decimal; decay: Decay; lastTransactionId: number } | null> { const lastTransaction = await Transaction.findOne({ userId }, { order: { balanceDate: 'DESC' } }) if (!lastTransaction) return null @@ -32,7 +34,13 @@ async function calculateBalance( const transactionLinkRepository = getCustomRepository(TransactionLinkRepository) const { sumHoldAvailableAmount } = await transactionLinkRepository.summary(userId, time) - if (balance.minus(sumHoldAvailableAmount.toString()).lessThan(0)) { + // If we want to redeem a link we need to make sure that the link amount is not considered as blocked + // else we cannot redeem links which are more or equal to half of what an account actually owns + const releasedLinkAmount = transactionLink ? transactionLink.holdAvailableAmount : new Decimal(0) + + if ( + balance.minus(sumHoldAvailableAmount.toString()).plus(releasedLinkAmount.toString()).lessThan(0) + ) { return null } return { balance, lastTransactionId: lastTransaction.id, decay }