From 35f6b83ca22b3ce4f53fbb7bfe93542fb88b2d32 Mon Sep 17 00:00:00 2001 From: Tan Hoang Date: Fri, 27 Sep 2024 13:52:42 +0700 Subject: [PATCH 1/2] fix: fee in mina unlock --- docker-compose.dev.yaml | 11 ----------- src/config/config.module.ts | 3 --- .../repositories/token-price.repository.ts | 10 ---------- src/modules/crawler/crawler.console.ts | 15 --------------- src/modules/crawler/sender.minabridge.ts | 17 +++++++---------- src/modules/crawler/tests/mina-sender.spec.ts | 7 +------ src/modules/users/dto/user-request.dto.ts | 5 ----- src/modules/users/users.service.ts | 10 ++++------ 8 files changed, 12 insertions(+), 66 deletions(-) diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml index 4b8bc99..3c8068f 100644 --- a/docker-compose.dev.yaml +++ b/docker-compose.dev.yaml @@ -59,17 +59,6 @@ services: networks: - myNetwork user: node - get-price-token: - image: mina-bridge:1.0.0 - command: > - sh -c "npm run console get-price-token" - tty: true - restart: always - depends_on: - - postgres - networks: - - myNetwork - user: node validate-evm-signature-1: image: mina-bridge:1.0.0 command: > diff --git a/src/config/config.module.ts b/src/config/config.module.ts index c514785..5b80f7f 100644 --- a/src/config/config.module.ts +++ b/src/config/config.module.ts @@ -50,9 +50,6 @@ import redisConfig from './redis.config.js'; [EEnvKey.ETH_BRIDGE_DOMAIN_NAME]: Joi.string().required(), [EEnvKey.ETH_BRIDGE_DOMAIN_VERSION]: Joi.string().required(), [EEnvKey.MINA_CRAWL_SAFE_BLOCK]: Joi.number().default(MINA_CRAWL_SAFE_BLOCK), - // coinmarketcap - [EEnvKey.COINMARKET_KEY]: Joi.string().required(), - [EEnvKey.COINMARKET_URL]: Joi.string().required(), // mina validator [EEnvKey.MINA_VALIDATOR_THRESHHOLD]: Joi.number().required(), // fee diff --git a/src/database/repositories/token-price.repository.ts b/src/database/repositories/token-price.repository.ts index 9140dd2..b78c17a 100644 --- a/src/database/repositories/token-price.repository.ts +++ b/src/database/repositories/token-price.repository.ts @@ -17,14 +17,4 @@ export class TokenPriceRepository extends BaseRepository { .where(`${this.alias}.symbol IN (:...symbols)`, { symbols }) .getMany(); } - - public async getRateETHToMina() { - const rate = await this.createQueryBuilder(`${this.alias}`) - .select( - `(select CAST(price_usd AS REAL) from token_prices tp2 where tp2.symbol = 'ETH') / (select CAST(price_usd AS REAL) from token_prices tp where tp.symbol = 'MINA') as rateETHMINA`, - ) - .getRawOne(); - - return rate; - } } diff --git a/src/modules/crawler/crawler.console.ts b/src/modules/crawler/crawler.console.ts index 0eeb935..e3fdeb3 100644 --- a/src/modules/crawler/crawler.console.ts +++ b/src/modules/crawler/crawler.console.ts @@ -117,19 +117,4 @@ export class CrawlerConsole { this.logger.error(error); } } - - @Command({ - command: 'get-price-token', - description: 'get price of token', - }) - async getPriceCoinMarketCap() { - try { - while (true) { - await this.jobGetPrice.handleGetPriceToken(); - await sleep(43200); - } - } catch (error) { - this.logger.error(error); - } - } } diff --git a/src/modules/crawler/sender.minabridge.ts b/src/modules/crawler/sender.minabridge.ts index 3cfbc13..5aff5b4 100644 --- a/src/modules/crawler/sender.minabridge.ts +++ b/src/modules/crawler/sender.minabridge.ts @@ -13,7 +13,6 @@ import { CommonConfigRepository } from '../../database/repositories/common-confi import { EventLogRepository } from '../../database/repositories/event-log.repository.js'; import { MultiSignatureRepository } from '../../database/repositories/multi-signature.repository.js'; import { TokenPairRepository } from '../../database/repositories/token-pair.repository.js'; -import { TokenPriceRepository } from '../../database/repositories/token-price.repository.js'; import { LoggerService } from '../../shared/modules/logger/logger.service.js'; import { addDecimal, calculateFee } from '../../shared/utils/bignumber.js'; import { TokenPair } from '../users/entities/tokenpair.entity.js'; @@ -36,7 +35,6 @@ export class SenderMinaBridge { private readonly eventLogRepository: EventLogRepository, private readonly commonConfigRepository: CommonConfigRepository, private readonly tokenPairRepository: TokenPairRepository, - private readonly tokenPriceRepository: TokenPriceRepository, private readonly multiSignatureRepository: MultiSignatureRepository, private readonly loggerService: LoggerService, ) { @@ -72,10 +70,12 @@ export class SenderMinaBridge { config: CommonConfig, amountFrom: string, ): { amountReceived: string; protocolFeeAmount: string } { + // convert decimal from ETH to MINA const amountReceiveConvert = BigNumber(amountFrom) .dividedBy(BigNumber(DECIMAL_BASE).pow(tokenPair.fromDecimal)) .multipliedBy(BigNumber(DECIMAL_BASE).pow(tokenPair.toDecimal)) .toString(); + // calc fee follow MINA decimal. const protocolFeeAmount = BigNumber( calculateFee( amountReceiveConvert, @@ -89,12 +89,11 @@ export class SenderMinaBridge { return { amountReceived, protocolFeeAmount }; } public async handleUnlockMina() { - let dataLock, configTip, rateethmina; + let dataLock, configTip; try { - [dataLock, configTip, { rateethmina }] = await Promise.all([ + [dataLock, configTip] = await Promise.all([ this.eventLogRepository.getEventLockWithNetwork(ENetworkName.MINA, this.validatorThreshhold), this.commonConfigRepository.getCommonConfig(), - this.tokenPriceRepository.getRateETHToMina(), ]); if (!dataLock) { return; @@ -126,9 +125,7 @@ export class SenderMinaBridge { } const { amountReceived, protocolFeeAmount } = this.getAmountReceivedAndFee(tokenPair, configTip, amountFrom); - const rateMINAETH = Number(rateethmina.toFixed(0)) || 2000; // refactor this - - const result = await this.callUnlockFunction(amountReceived, id, receiveAddress, protocolFeeAmount, rateMINAETH); + const result = await this.callUnlockFunction(amountReceived, id, receiveAddress); // Update status eventLog when call function unlock if (result.success) { await this.eventLogRepository.updateStatusAndRetryEvenLog({ @@ -160,7 +157,7 @@ export class SenderMinaBridge { } } - private async callUnlockFunction(amount, txId, receiveAddress, protocolFeeAmount, rateMINAETH) { + private async callUnlockFunction(amount, txId, receiveAddress) { try { const generatedSignatures = await this.multiSignatureRepository.findBy({ txId, @@ -172,7 +169,7 @@ export class SenderMinaBridge { this.logger.info('compile the contract...'); await this.compileContract(); - const fee = protocolFeeAmount * rateMINAETH + +this.configService.get(EEnvKey.BASE_MINA_BRIDGE_FEE); // in nanomina (1 billion = 1.0 mina) + const fee = +this.configService.get(EEnvKey.BASE_MINA_BRIDGE_FEE); // in nanomina (1 billion = 1.0 mina) const feePayerPublicKey = this.feePayerKey.toPublicKey(); const bridgePublicKey = this.bridgeKey.toPublicKey(); const receiverPublicKey = PublicKey.fromBase58(receiveAddress); diff --git a/src/modules/crawler/tests/mina-sender.spec.ts b/src/modules/crawler/tests/mina-sender.spec.ts index d6ed300..ac707df 100644 --- a/src/modules/crawler/tests/mina-sender.spec.ts +++ b/src/modules/crawler/tests/mina-sender.spec.ts @@ -6,7 +6,6 @@ import { CommonConfigRepository } from '../../../database/repositories/common-co import { EventLogRepository } from '../../../database/repositories/event-log.repository.js'; import { MultiSignatureRepository } from '../../../database/repositories/multi-signature.repository.js'; import { TokenPairRepository } from '../../../database/repositories/token-pair.repository.js'; -import { TokenPriceRepository } from '../../../database/repositories/token-price.repository.js'; import { LoggingModule } from '../../../shared/modules/logger/logger.module.js'; import { Web3Module } from '../../../shared/modules/web3/web3.module.js'; import { SenderMinaBridge } from '../sender.minabridge.js'; @@ -30,9 +29,7 @@ const mockCommonConfigRepository = { const mockTokenPairRepository = { getTokenPair: jest.fn(), }; -const mockTokenPriceRepository = { - getRateETHToMina: jest.fn(), -}; + const mockMultiSignatureRepository = { getRateETHToMina: jest.fn(), findBy: jest.fn(), @@ -49,7 +46,6 @@ describe('MinaSenderService', () => { { provide: EventLogRepository, useValue: mockEventLogRepository }, { provide: CommonConfigRepository, useValue: mockCommonConfigRepository }, { provide: TokenPairRepository, useValue: mockTokenPairRepository }, - { provide: TokenPriceRepository, useValue: mockTokenPriceRepository }, { provide: MultiSignatureRepository, useValue: mockMultiSignatureRepository }, ], }).compile(); @@ -91,7 +87,6 @@ describe('MinaSenderService', () => { dailyQuota: '500', id: 1, }); - mockTokenPriceRepository.getRateETHToMina.mockResolvedValue({ rateethmina: 3870.44 }); mockTokenPairRepository.getTokenPair.mockResolvedValue({ id: 5, deletedAt: null, diff --git a/src/modules/users/dto/user-request.dto.ts b/src/modules/users/dto/user-request.dto.ts index 7199223..db4050c 100644 --- a/src/modules/users/dto/user-request.dto.ts +++ b/src/modules/users/dto/user-request.dto.ts @@ -26,9 +26,4 @@ export class GetProtocolFeeBodyDto { required: true, }) pairId: number; - - @StringField({ - required: true, - }) - amount: string; } diff --git a/src/modules/users/users.service.ts b/src/modules/users/users.service.ts index 1a9bbb6..65c733a 100644 --- a/src/modules/users/users.service.ts +++ b/src/modules/users/users.service.ts @@ -13,9 +13,9 @@ import { UserRepository } from '../../database/repositories/user.repository.js'; import { TokenPair } from '../../modules/users/entities/tokenpair.entity.js'; import { httpBadRequest } from '../../shared/exceptions/http-exeption.js'; import { LoggerService } from '../../shared/modules/logger/logger.service.js'; -import { ETHBridgeContract } from '../../shared/modules/web3/web3.service.js'; -import { addDecimal, calculateFee } from '../../shared/utils/bignumber.js'; +import { addDecimal } from '../../shared/utils/bignumber.js'; import { UpdateCommonConfigBodyDto } from './dto/common-config-request.dto.js'; +import { GetProtocolFeeBodyDto } from './dto/user-request.dto.js'; @Injectable() export class UsersService { @@ -27,7 +27,6 @@ export class UsersService { private readonly dataSource: DataSource, private readonly configService: ConfigService, private readonly loggerService: LoggerService, - private readonly ethBridgeContract: ETHBridgeContract, ) { this.logger = this.loggerService.getLogger('USER_SERVICE'); } @@ -72,9 +71,8 @@ export class UsersService { return this.dataSource.getRepository(TokenPair).find(); } - async getProtocolFee(body) { + async getProtocolFee({ pairId }: GetProtocolFeeBodyDto) { let gasFee; - const { pairId, amount } = body; const [tokenPair, configTip] = await Promise.all([ this.dataSource.getRepository(TokenPair).findOne({ where: { id: pairId }, @@ -94,6 +92,6 @@ export class UsersService { ); } - return { amount: calculateFee(amount, gasFee, configTip.tip) }; + return { gasFee, tipRate: configTip.tip }; } } From f4cd80febd066f300ba6c654293d14d6b9678c46 Mon Sep 17 00:00:00 2001 From: Tan Hoang Date: Fri, 27 Sep 2024 16:07:16 +0700 Subject: [PATCH 2/2] feat: add tip and gas fee for event logs --- ...7426782955-create-fee-column-event-logs.ts | 22 ++++++++++ .../repositories/event-log.repository.ts | 2 + .../crawler/entities/event-logs.entity.ts | 6 +++ src/modules/crawler/sender.evmbridge.ts | 31 +++++--------- src/modules/crawler/sender.minabridge.ts | 33 +++++++++------ src/modules/crawler/tests/evm-sender.spec.ts | 42 ++++++++----------- src/modules/users/users.service.ts | 16 +++---- src/shared/utils/bignumber.ts | 11 +++-- src/shared/utils/util.ts | 2 +- 9 files changed, 94 insertions(+), 71 deletions(-) create mode 100644 src/database/migrations/1727426782955-create-fee-column-event-logs.ts diff --git a/src/database/migrations/1727426782955-create-fee-column-event-logs.ts b/src/database/migrations/1727426782955-create-fee-column-event-logs.ts new file mode 100644 index 0000000..d20a9fe --- /dev/null +++ b/src/database/migrations/1727426782955-create-fee-column-event-logs.ts @@ -0,0 +1,22 @@ +import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm'; + +export class CreateFeeColumnEventLogs1727426782955 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + return queryRunner.addColumns('event_logs', [ + new TableColumn({ + name: 'tip', + type: 'varchar', + isNullable: true, + }), + new TableColumn({ + name: 'gas_fee', + type: 'varchar', + isNullable: true, + }), + ]); + } + + public async down(queryRunner: QueryRunner): Promise { + return queryRunner.dropColumns('event_logs', ['tip', 'gas_fee']); + } +} diff --git a/src/database/repositories/event-log.repository.ts b/src/database/repositories/event-log.repository.ts index 795e1dd..9926244 100644 --- a/src/database/repositories/event-log.repository.ts +++ b/src/database/repositories/event-log.repository.ts @@ -51,6 +51,8 @@ export class EventLogRepository extends BaseRepository { protocolFee?: string; errorDetail?: string; txHashUnlock?: string; + gasFee?: string; + tip?: string; }) { return this.createQueryBuilder(`${this.alias}`) .update(EventLog) diff --git a/src/modules/crawler/entities/event-logs.entity.ts b/src/modules/crawler/entities/event-logs.entity.ts index 1c4e2ab..10eaae7 100644 --- a/src/modules/crawler/entities/event-logs.entity.ts +++ b/src/modules/crawler/entities/event-logs.entity.ts @@ -53,6 +53,12 @@ export class EventLog extends BaseEntityIncludeTime { @Column({ name: 'protocol_fee', type: 'varchar', nullable: true }) protocolFee: string; + @Column({ name: 'gas_fee', type: 'varchar', nullable: true }) + gasFee: string; + + @Column({ type: 'varchar', nullable: true }) + tip: string; + @Column({ name: 'event', type: 'varchar', enum: EEventName, nullable: false }) event: EEventName; diff --git a/src/modules/crawler/sender.evmbridge.ts b/src/modules/crawler/sender.evmbridge.ts index 19f3b54..895ba9a 100644 --- a/src/modules/crawler/sender.evmbridge.ts +++ b/src/modules/crawler/sender.evmbridge.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import BigNumber from 'bignumber.js/bignumber.mjs'; +import { BigNumber } from 'bignumber.js'; +// import BigNumber from 'bignumber.js/bignumber.mjs'; import { ethers } from 'ethers'; import { Logger } from 'log4js'; @@ -14,7 +15,7 @@ import { MultiSignatureRepository } from '../../database/repositories/multi-sign import { TokenPairRepository } from '../../database/repositories/token-pair.repository.js'; import { LoggerService } from '../../shared/modules/logger/logger.service.js'; import { ETHBridgeContract } from '../../shared/modules/web3/web3.service.js'; -import { addDecimal, calculateFee } from '../../shared/utils/bignumber.js'; +import { addDecimal, calculateFee, calculateTip } from '../../shared/utils/bignumber.js'; import { EventLog } from './entities/event-logs.entity.js'; import { MultiSignature } from './entities/multi-signature.entity.js'; @@ -58,18 +59,13 @@ export class SenderEVMBridge { await this.updateLogStatusWithRetry(dataLock, EEventStatus.FAILED, EError.OVER_DAILY_QUOTA); return; } - // const gasFee = await this.ethBridgeContract.getEstimateGas( - // tokenReceivedAddress, - // BigNumber(amountReceive), - // txHashLock, - // receiveAddress, - // 0, - // ); - const protocolFee = calculateFee( - amountReceived, - addDecimal(this.configService.get(EEnvKey.GAS_FEE_EVM), this.configService.get(EEnvKey.DECIMAL_TOKEN_EVM)), - configTip.tip, + // fee and received amount. + const gasFeeEth = addDecimal( + this.configService.get(EEnvKey.GAS_FEE_EVM), + this.configService.get(EEnvKey.DECIMAL_TOKEN_EVM), ); + const protocolFee = calculateFee(amountReceived, gasFeeEth, configTip.tip); + // call unlock function const result = await this.ethBridgeContract.unlock( tokenReceivedAddress, BigNumber(amountReceived), @@ -87,6 +83,8 @@ export class SenderEVMBridge { errorDetail: null, protocolFee, amountReceived: BigNumber(amountReceived).minus(protocolFee).toFixed(0).toString(), + gasFee: gasFeeEth, + tip: calculateTip(amountReceived, gasFeeEth, configTip.tip).toFixed(0).toString(), }); } else { await this.handleError(result.error, dataLock); @@ -116,13 +114,6 @@ export class SenderEVMBridge { return; } - // const gasFee = await this.ethBridgeContract.getEstimateGas( - // tokenReceivedAddress, - // BigNumber(amountReceive), - // txHashLock, - // receiveAddress, - // 0, - // ); const protocolFee = calculateFee( amountReceived, addDecimal(this.configService.get(EEnvKey.GAS_FEE_EVM), this.configService.get(EEnvKey.DECIMAL_TOKEN_EVM)), diff --git a/src/modules/crawler/sender.minabridge.ts b/src/modules/crawler/sender.minabridge.ts index 5aff5b4..5583826 100644 --- a/src/modules/crawler/sender.minabridge.ts +++ b/src/modules/crawler/sender.minabridge.ts @@ -14,7 +14,7 @@ import { EventLogRepository } from '../../database/repositories/event-log.reposi import { MultiSignatureRepository } from '../../database/repositories/multi-signature.repository.js'; import { TokenPairRepository } from '../../database/repositories/token-pair.repository.js'; import { LoggerService } from '../../shared/modules/logger/logger.service.js'; -import { addDecimal, calculateFee } from '../../shared/utils/bignumber.js'; +import { addDecimal, calculateFee, calculateTip } from '../../shared/utils/bignumber.js'; import { TokenPair } from '../users/entities/tokenpair.entity.js'; import { CommonConfig } from './entities/common-config.entity.js'; import { MultiSignature } from './entities/multi-signature.entity.js'; @@ -69,24 +69,27 @@ export class SenderMinaBridge { tokenPair: TokenPair, config: CommonConfig, amountFrom: string, - ): { amountReceived: string; protocolFeeAmount: string } { + ): { amountReceived: string; protocolFeeAmount: string; tipAmount: string; gasFeeMina: string } { // convert decimal from ETH to MINA const amountReceiveConvert = BigNumber(amountFrom) .dividedBy(BigNumber(DECIMAL_BASE).pow(tokenPair.fromDecimal)) .multipliedBy(BigNumber(DECIMAL_BASE).pow(tokenPair.toDecimal)) .toString(); + const gasFeeMina = addDecimal( + this.configService.get(EEnvKey.GASFEEMINA), + this.configService.get(EEnvKey.DECIMAL_TOKEN_MINA), + ); // calc fee follow MINA decimal. - const protocolFeeAmount = BigNumber( - calculateFee( - amountReceiveConvert, - addDecimal(this.configService.get(EEnvKey.GASFEEMINA), this.configService.get(EEnvKey.DECIMAL_TOKEN_MINA)), - config.tip, - ), - ) + const protocolFeeAmount = BigNumber(calculateFee(amountReceiveConvert, gasFeeMina, config.tip)) .toFixed(0) .toString(); const amountReceived = BigNumber(amountReceiveConvert).minus(protocolFeeAmount).toFixed(0).toString(); - return { amountReceived, protocolFeeAmount }; + return { + amountReceived, + protocolFeeAmount, + tipAmount: calculateTip(amountReceiveConvert, gasFeeMina, config.tip).toFixed(0).toString(), + gasFeeMina, + }; } public async handleUnlockMina() { let dataLock, configTip; @@ -123,7 +126,11 @@ export class SenderMinaBridge { }); return; } - const { amountReceived, protocolFeeAmount } = this.getAmountReceivedAndFee(tokenPair, configTip, amountFrom); + const { amountReceived, protocolFeeAmount, gasFeeMina, tipAmount } = this.getAmountReceivedAndFee( + tokenPair, + configTip, + amountFrom, + ); const result = await this.callUnlockFunction(amountReceived, id, receiveAddress); // Update status eventLog when call function unlock @@ -134,8 +141,10 @@ export class SenderMinaBridge { status: EEventStatus.PROCESSING, errorDetail: result.error, txHashUnlock: result.data, - amountReceived: BigNumber(amountReceived).minus(protocolFeeAmount).toFixed(0).toString(), + amountReceived, protocolFee: protocolFeeAmount, + gasFee: gasFeeMina, + tip: tipAmount, }); } else { await this.eventLogRepository.updateStatusAndRetryEvenLog({ diff --git a/src/modules/crawler/tests/evm-sender.spec.ts b/src/modules/crawler/tests/evm-sender.spec.ts index 4d214fa..8d10904 100644 --- a/src/modules/crawler/tests/evm-sender.spec.ts +++ b/src/modules/crawler/tests/evm-sender.spec.ts @@ -1,33 +1,30 @@ -import { ConfigModule, ConfigService } from '@nestjs/config'; +import { ConfigModule } from '@nestjs/config'; import { JwtService } from '@nestjs/jwt'; import { Test, TestingModule } from '@nestjs/testing'; -import { ConfigurationModule } from 'config/config.module.js'; -import { EAsset } from 'constants/api.constant.js'; -import { EEventName, EEventStatus, ENetworkName, ETokenPairStatus } from 'constants/blockchain.constant.js'; -import { CommonConfigRepository } from 'database/repositories/common-configuration.repository'; -import { CrawlContractRepository } from 'database/repositories/crawl-contract.repository'; -import { EventLogRepository } from 'database/repositories/event-log.repository'; -import { MultiSignatureRepository } from 'database/repositories/multi-signature.repository'; -import { TokenPairRepository } from 'database/repositories/token-pair.repository'; -import { TokenPair } from 'modules/users/entities/tokenpair.entity.js'; -import { LoggerService } from 'shared/modules/logger/logger.service.js'; -import { Web3Module } from 'shared/modules/web3/web3.module.js'; -import { ETHBridgeContract } from 'shared/modules/web3/web3.service.js'; -import { DataSource, QueryRunner } from 'typeorm'; +import { DataSource } from 'typeorm'; -import { EventLog } from '../entities'; -import { CommonConfig } from '../entities/common-config.entity'; -import { MultiSignature } from '../entities/multi-signature.entity'; -import { SenderEVMBridge } from '../sender.evmbridge'; +import { ConfigurationModule } from '../../../config/config.module.js'; +import { EAsset } from '../../../constants/api.constant.js'; +import { EEventName, EEventStatus, ENetworkName, ETokenPairStatus } from '../../../constants/blockchain.constant.js'; +import { CommonConfigRepository } from '../../../database/repositories/common-configuration.repository.js'; +import { CrawlContractRepository } from '../../../database/repositories/crawl-contract.repository.js'; +import { EventLogRepository } from '../../../database/repositories/event-log.repository.js'; +import { MultiSignatureRepository } from '../../../database/repositories/multi-signature.repository.js'; +import { TokenPairRepository } from '../../../database/repositories/token-pair.repository.js'; +import { TokenPair } from '../../../modules/users/entities/tokenpair.entity.js'; +import { LoggerService } from '../../../shared/modules/logger/logger.service.js'; +import { Web3Module } from '../../../shared/modules/web3/web3.module.js'; +import { ETHBridgeContract } from '../../../shared/modules/web3/web3.service.js'; +import { CommonConfig } from '../entities/common-config.entity.js'; +import { EventLog } from '../entities/index.js'; +import { MultiSignature } from '../entities/multi-signature.entity.js'; +import { SenderEVMBridge } from '../sender.evmbridge.js'; let senderEVMBridge: SenderEVMBridge; -let dataSource: DataSource; -let queryRunner: QueryRunner; let eventLogRepository: EventLogRepository; let commonConfigRepository: CommonConfigRepository; let tokenPairRepository: TokenPairRepository; let multiSignatureRepository: MultiSignatureRepository; -let loggerService: LoggerService; let newEthBridgeContract: ETHBridgeContract; // Mock objects const mockJwtService = { @@ -103,13 +100,10 @@ beforeEach(async () => { newEthBridgeContract = module.get(ETHBridgeContract); senderEVMBridge = module.get(SenderEVMBridge); - dataSource = module.get(DataSource); - queryRunner = dataSource.createQueryRunner(); eventLogRepository = module.get(EventLogRepository); commonConfigRepository = module.get(CommonConfigRepository); tokenPairRepository = module.get(TokenPairRepository); multiSignatureRepository = module.get(MultiSignatureRepository); - loggerService = module.get(LoggerService); }); describe('handleValidateUnlockTxEVM', () => { diff --git a/src/modules/users/users.service.ts b/src/modules/users/users.service.ts index 65c733a..8a9aa45 100644 --- a/src/modules/users/users.service.ts +++ b/src/modules/users/users.service.ts @@ -72,7 +72,7 @@ export class UsersService { } async getProtocolFee({ pairId }: GetProtocolFeeBodyDto) { - let gasFee; + let gasFee, decimal; const [tokenPair, configTip] = await Promise.all([ this.dataSource.getRepository(TokenPair).findOne({ where: { id: pairId }, @@ -81,17 +81,13 @@ export class UsersService { ]); if (tokenPair.toChain == ENetworkName.MINA) { - gasFee = addDecimal( - this.configService.get(EEnvKey.GAS_FEE_EVM), - this.configService.get(EEnvKey.DECIMAL_TOKEN_EVM), - ); + decimal = this.configService.get(EEnvKey.DECIMAL_TOKEN_EVM); + gasFee = addDecimal(this.configService.get(EEnvKey.GAS_FEE_EVM), decimal); } else { - gasFee = addDecimal( - this.configService.get(EEnvKey.GASFEEMINA), - this.configService.get(EEnvKey.DECIMAL_TOKEN_MINA), - ); + decimal = this.configService.get(EEnvKey.DECIMAL_TOKEN_MINA); + gasFee = addDecimal(this.configService.get(EEnvKey.GASFEEMINA), decimal); } - return { gasFee, tipRate: configTip.tip }; + return { gasFee, tipRate: configTip.tip, decimal }; } } diff --git a/src/shared/utils/bignumber.ts b/src/shared/utils/bignumber.ts index 8fee18b..e8dc0cb 100644 --- a/src/shared/utils/bignumber.ts +++ b/src/shared/utils/bignumber.ts @@ -1,15 +1,18 @@ -import BigNumber from 'bignumber.js/bignumber.mjs'; +// import BigNumber from 'bignumber.js/bignumber.mjs'; +import { BigNumber } from 'bignumber.js'; import { isNumber, isNumberString } from 'class-validator'; export const addDecimal = (value: string | number, decimal: number) => { if (!isNumber(value) && !isNumberString(value)) return '0'; return BigNumber(value).multipliedBy(BigNumber(10).pow(decimal)).toFixed().toString(); }; - -export const calculateFee = (amount: string, gasFee: string | number, tipPercent: number) => { - const tip = BigNumber(amount) +export const calculateTip = (amount: string, gasFee: string | number, tipPercent: number): BigNumber => { + return BigNumber(amount) .minus(BigNumber(gasFee)) .multipliedBy(tipPercent * 10) .dividedBy(1000); +}; +export const calculateFee = (amount: string, gasFee: string | number, tipPercent: number) => { + const tip = calculateTip(amount, gasFee, tipPercent); return BigNumber(gasFee).plus(tip).toFixed(0, BigNumber.ROUND_UP); }; diff --git a/src/shared/utils/util.ts b/src/shared/utils/util.ts index ac83db9..da3ac6f 100644 --- a/src/shared/utils/util.ts +++ b/src/shared/utils/util.ts @@ -39,4 +39,4 @@ export const getVariableName = (getVar: () => TResult): string => { export const nullToZero = (value: string | number) => (value ? value.toString() : '0'); export const isDevelopmentEnvironment = () => - [EEnvironments.LOCAL].includes(process.env[EEnvKey.NODE_ENV] as EEnvironments); + [EEnvironments.LOCAL, EEnvironments.DEV].includes(process.env[EEnvKey.NODE_ENV] as EEnvironments);