From ec5933df1daa0ad24f7ef46f21b5fa95e8be7aa9 Mon Sep 17 00:00:00 2001 From: michael1011 Date: Wed, 15 Jan 2025 23:01:42 +0100 Subject: [PATCH] refactor: always renegotiate overpaid chain swaps --- lib/swap/EthereumNursery.ts | 2 ++ lib/swap/OverpaymentProtector.ts | 25 +++++++++++++++----- lib/swap/UtxoNursery.ts | 2 ++ test/unit/swap/OverpaymentProtector.spec.ts | 26 ++++++++++++++++++--- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/lib/swap/EthereumNursery.ts b/lib/swap/EthereumNursery.ts index 3d06f499..e2e8a57b 100644 --- a/lib/swap/EthereumNursery.ts +++ b/lib/swap/EthereumNursery.ts @@ -229,6 +229,7 @@ class EthereumNursery extends TypedEventEmitter<{ if ( this.overpaymentProtector.isUnacceptableOverpay( + swap.type, expectedAmount, actualAmountSat, ) @@ -349,6 +350,7 @@ class EthereumNursery extends TypedEventEmitter<{ if ( this.overpaymentProtector.isUnacceptableOverpay( + swap.type, expectedAmount, actualAmount, ) diff --git a/lib/swap/OverpaymentProtector.ts b/lib/swap/OverpaymentProtector.ts index 14de7816..884a2837 100644 --- a/lib/swap/OverpaymentProtector.ts +++ b/lib/swap/OverpaymentProtector.ts @@ -1,5 +1,6 @@ import { OverPaymentConfig } from '../Config'; import Logger from '../Logger'; +import { SwapType } from '../consts/Enums'; class OverpaymentProtector { private static readonly defaultConfig = { @@ -25,12 +26,24 @@ class OverpaymentProtector { ); } - public isUnacceptableOverpay = (expected: number, actual: number): boolean => - actual - expected > - Math.max( - this.overPaymentExemptAmount, - actual * this.overPaymentMaxPercentage, - ); + public isUnacceptableOverpay = ( + type: SwapType, + expected: number, + actual: number, + ): boolean => { + // For chain swaps we renegotiate overpayments + if (type === SwapType.Chain) { + return actual > expected; + } else { + return ( + actual - expected > + Math.max( + this.overPaymentExemptAmount, + actual * this.overPaymentMaxPercentage, + ) + ); + } + }; } export default OverpaymentProtector; diff --git a/lib/swap/UtxoNursery.ts b/lib/swap/UtxoNursery.ts index 211331fa..a0c6d87b 100644 --- a/lib/swap/UtxoNursery.ts +++ b/lib/swap/UtxoNursery.ts @@ -178,6 +178,7 @@ class UtxoNursery extends TypedEventEmitter<{ if ( this.overpaymentProtector.isUnacceptableOverpay( + swap.type, swap.receivingData.expectedAmount, outputValue, ) @@ -770,6 +771,7 @@ class UtxoNursery extends TypedEventEmitter<{ if ( this.overpaymentProtector.isUnacceptableOverpay( + swap.type, updatedSwap.expectedAmount, outputValue, ) diff --git a/test/unit/swap/OverpaymentProtector.spec.ts b/test/unit/swap/OverpaymentProtector.spec.ts index c75d2094..bc2ce1cf 100644 --- a/test/unit/swap/OverpaymentProtector.spec.ts +++ b/test/unit/swap/OverpaymentProtector.spec.ts @@ -1,5 +1,6 @@ import { OverPaymentConfig } from '../../../lib/Config'; import Logger from '../../../lib/Logger'; +import { SwapType } from '../../../lib/consts/Enums'; import OverpaymentProtector from '../../../lib/swap/OverpaymentProtector'; describe('OverpaymentProtector', () => { @@ -68,7 +69,7 @@ describe('OverpaymentProtector', () => { new OverpaymentProtector( Logger.disabledLogger, config, - ).isUnacceptableOverpay(expected, actual), + ).isUnacceptableOverpay(SwapType.Submarine, expected, actual), ).toEqual(false); }, ); @@ -85,7 +86,7 @@ describe('OverpaymentProtector', () => { new OverpaymentProtector( Logger.disabledLogger, config, - ).isUnacceptableOverpay(expected, actual), + ).isUnacceptableOverpay(SwapType.Submarine, expected, actual), ).toEqual(false); }, ); @@ -102,9 +103,28 @@ describe('OverpaymentProtector', () => { new OverpaymentProtector( Logger.disabledLogger, config, - ).isUnacceptableOverpay(expected, actual), + ).isUnacceptableOverpay(SwapType.Submarine, expected, actual), ).toEqual(true); }, ); + + test.each` + expected | actual | expectedResult + ${100} | ${101} | ${true} + ${100} | ${105} | ${true} + ${100} | ${110} | ${true} + ${100} | ${100} | ${false} + `( + 'should not allow overpayment for chain swaps', + ({ expected, actual, expectedResult }) => { + expect( + new OverpaymentProtector(Logger.disabledLogger).isUnacceptableOverpay( + SwapType.Chain, + expected, + actual, + ), + ).toEqual(expectedResult); + }, + ); }); });