Skip to content

Commit ef37d89

Browse files
authored
Merge pull request #3467 from DFXswiss/develop
Release: develop -> main
2 parents ec61e44 + e6a50df commit ef37d89

8 files changed

Lines changed: 55 additions & 22 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
module.exports = class AddAvailableAmountToLiquidityBalance1774000000000 {
2+
name = 'AddAvailableAmountToLiquidityBalance1774000000000';
3+
4+
async up(queryRunner) {
5+
await queryRunner.query(`ALTER TABLE "dbo"."liquidity_balance" ADD "availableAmount" float`);
6+
}
7+
8+
async down(queryRunner) {
9+
await queryRunner.query(`ALTER TABLE "dbo"."liquidity_balance" DROP COLUMN "availableAmount"`);
10+
}
11+
};

src/integration/exchange/controllers/exchange.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class ExchangeController {
5050
@ApiExcludeEndpoint()
5151
@UseGuards(AuthGuard(), RoleGuard(UserRole.ADMIN), UserActiveGuard())
5252
async getBalance(@Param('exchange') exchange: string): Promise<Balances> {
53-
return this.call(exchange, (e) => e.getBalances());
53+
return this.call(exchange, (e) => e.getRawBalances());
5454
}
5555

5656
@Get(':exchange/price')

src/integration/exchange/services/exchange.service.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { BadRequestException, Inject, OnModuleInit } from '@nestjs/common';
22
import BigNumber from 'bignumber.js';
33
import {
4+
Balance,
45
Balances,
56
ConstructorArgs,
67
Dictionary,
@@ -67,24 +68,30 @@ export abstract class ExchangeService extends PricingProvider implements OnModul
6768
return this.exchange.name;
6869
}
6970

70-
async getBalances(): Promise<Balances> {
71+
async getRawBalances(): Promise<Balances> {
7172
return this.callApi((e) => e.fetchBalance());
7273
}
7374

74-
async getTotalBalances(): Promise<Dictionary<number>> {
75-
const balances = await this.getBalances().then((b) => b.total);
75+
async getBalances(): Promise<{ total: Dictionary<number>; available: Dictionary<number> }> {
76+
const balances = await this.getRawBalances();
7677

77-
const totalBalances = {};
78+
return {
79+
total: this.aggregateBalances(balances.total),
80+
available: this.aggregateBalances(balances.free),
81+
};
82+
}
83+
84+
private aggregateBalances(balances: Balance): Dictionary<number> {
85+
const result: Dictionary<number> = {};
7886
for (const [asset, amount] of Object.entries(balances)) {
7987
const [base, suffix] = asset.split('.');
80-
if (!suffix || suffix === 'F') totalBalances[base] = (totalBalances[base] ?? 0) + amount;
88+
if (!suffix || suffix === 'F') result[base] = (result[base] ?? 0) + (amount as number);
8189
}
82-
83-
return totalBalances;
90+
return result;
8491
}
8592

8693
async getAvailableBalance(currency: string): Promise<number> {
87-
return this.getBalances().then((b) => b.free[currency] ?? 0);
94+
return this.getRawBalances().then((b) => b.free[currency] ?? 0);
8895
}
8996

9097
async getPrice(from: string, to: string): Promise<Price> {

src/integration/exchange/services/scrypt.service.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,31 @@ export class ScryptService extends PricingProvider {
7070

7171
// --- BALANCES --- //
7272

73-
async getTotalBalances(): Promise<Record<string, number>> {
73+
async getBalances(): Promise<{ total: Record<string, number>; available: Record<string, number> }> {
7474
const balances = await this.balances;
7575

76-
const totalBalances: Record<string, number> = {};
76+
const total: Record<string, number> = {};
77+
const available: Record<string, number> = {};
78+
7779
for (const balance of balances.values()) {
78-
totalBalances[balance.Currency] = parseFloat(balance.Amount) || 0;
80+
const amount = parseFloat(balance.Amount) || 0;
81+
const availableAmount = parseFloat(balance.AvailableAmount) || amount;
82+
83+
total[balance.Currency] = amount;
84+
available[balance.Currency] = availableAmount;
7985
}
8086

81-
return totalBalances;
87+
return { total, available };
8288
}
8389

8490
async getAvailableBalance(currency: string): Promise<number> {
8591
const balances = await this.balances;
8692

8793
const balance = balances.get(currency);
88-
return balance ? parseFloat(balance.AvailableAmount) || 0 : 0;
94+
if (!balance) return 0;
95+
96+
const amount = parseFloat(balance.Amount) || 0;
97+
return parseFloat(balance.AvailableAmount) || amount;
8998
}
9099

91100
// --- WITHDRAWALS --- //

src/subdomains/core/liquidity-management/adapters/balances/exchange.adapter.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,14 @@ export class ExchangeAdapter implements LiquidityBalanceIntegration {
5959
async getForExchange(exchange: string, assets: LiquidityManagementAsset[]): Promise<LiquidityBalance[]> {
6060
try {
6161
const exchangeService = this.exchangeRegistry.getExchange(exchange);
62-
const balances = await exchangeService.getTotalBalances();
62+
const { total: totalBalances, available: availableBalances } = await exchangeService.getBalances();
6363

6464
return assets.map((a) => {
6565
const names = [a.dexName, ...(this.ASSET_MAPPINGS[a.dexName] ?? [])];
66-
const balance = Util.sum(names.map((n) => balances[n] ?? 0));
66+
const total = Util.sum(names.map((n) => totalBalances[n] ?? 0));
67+
const available = Util.sum(names.map((n) => availableBalances[n] ?? 0));
6768

68-
return LiquidityBalance.create(a, balance);
69+
return LiquidityBalance.create(a, total, available);
6970
});
7071
} catch (e) {
7172
this.logger.error(`Failed to update liquidity management balance for ${exchange}:`, e);

src/subdomains/core/liquidity-management/entities/liquidity-balance.entity.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,29 @@ export class LiquidityBalance extends IEntity {
1010
@Column({ type: 'float', nullable: true })
1111
amount?: number;
1212

13+
@Column({ type: 'float', nullable: true })
14+
availableAmount?: number;
15+
1316
@Column({ default: true })
1417
isDfxOwned: boolean;
1518

1619
// --- FACTORY METHODS --- //
1720

18-
static create(target: Asset, amount: number): LiquidityBalance {
21+
static create(target: Asset, amount: number, availableAmount?: number): LiquidityBalance {
1922
const balance = new LiquidityBalance();
2023

2124
balance.asset = target;
2225
balance.amount = amount;
26+
balance.availableAmount = availableAmount ?? amount;
2327

2428
return balance;
2529
}
2630

2731
// --- PUBLIC API --- //
2832

29-
updateBalance(amount: number): this {
33+
updateBalance(amount: number, availableAmount?: number): this {
3034
this.amount = amount;
35+
this.availableAmount = availableAmount ?? amount;
3136

3237
return this;
3338
}

src/subdomains/core/liquidity-management/services/liquidity-management-balance.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class LiquidityManagementBalanceService implements OnModuleInit {
8686
if (existingBalance) {
8787
if (existingBalance.updated > startDate) continue;
8888

89-
existingBalance.updateBalance(balance.amount ?? 0);
89+
existingBalance.updateBalance(balance.amount ?? 0, balance.availableAmount);
9090
await this.balanceRepo.save(existingBalance);
9191

9292
continue;

src/subdomains/supporting/log/log-job.service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -452,8 +452,8 @@ export class LogJobService {
452452

453453
const manualLiqPosition = manualLiqPositions.find((p) => p.assetId === curr.id)?.value ?? 0;
454454

455-
// plus
456-
const liquidity = (curr.balance?.amount ?? 0) + (paymentDepositBalance ?? 0) + (manualLiqPosition ?? 0);
455+
// plus (use availableAmount to avoid double-counting with pending exchange orders)
456+
const liquidity = (curr.balance?.availableAmount ?? 0) + (paymentDepositBalance ?? 0) + (manualLiqPosition ?? 0);
457457

458458
const cryptoInput = [Blockchain.MONERO, Blockchain.LIGHTNING, Blockchain.ZANO].includes(curr.blockchain)
459459
? 0

0 commit comments

Comments
 (0)