Skip to content

Commit 4fd3fd1

Browse files
committed
fix(hub): compensate minter-hub validation of amount not considering discount
1 parent bf276e9 commit 4fd3fd1

File tree

4 files changed

+970
-687
lines changed

4 files changed

+970
-687
lines changed

components/HubWithdrawForm.vue

+50-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import Big from '~/assets/big.js';
33
import {validationMixin} from 'vuelidate';
44
import required from 'vuelidate/lib/validators/required.js';
5+
import minValue from 'vuelidate/lib/validators/maxValue.js';
56
import maxValue from 'vuelidate/lib/validators/maxValue.js';
67
import minLength from 'vuelidate/lib/validators/minLength.js';
78
import autosize from 'v-autosize';
@@ -139,9 +140,11 @@ export default {
139140
const inverseRate = new Big(this.hubFeeRate).div(new Big(1).minus(this.hubFeeRate));
140141
return amount.times(inverseRate).toString();
141142
},
143+
/*
142144
totalFee() {
143145
return new Big(this.coinFee).plus(this.hubFee).toString();
144146
},
147+
*/
145148
amountToSend() {
146149
return new Big(this.form.amount || 0).plus(this.coinFee).plus(this.hubFee).toString();
147150
},
@@ -170,6 +173,9 @@ export default {
170173
return maxAmount.toString();
171174
}
172175
},
176+
minAmount() {
177+
return getHubMinAmount(this.coinFee, this.hubFeeRate);
178+
},
173179
suggestionList() {
174180
return this.hubCoinList
175181
// show only available coins for selected network
@@ -224,7 +230,7 @@ export default {
224230
amount: {
225231
required,
226232
// validAmount: isValidAmount,
227-
minValue: (value) => value > 0,
233+
minValue: minValue(this.minAmount),
228234
maxValue: maxValue(this.maxAmount || 0),
229235
},
230236
},
@@ -375,6 +381,48 @@ export default {
375381
},
376382
},
377383
};
384+
385+
/**
386+
* // Minter Hub not consider discount in amount validation, so we need compensate amount for discount difference
387+
* @param {number|string} destinationNetworkFee
388+
* @param {number|string} hubFeeRate
389+
* @param {number|string} hubFeeBaseRate - hub fee rate without discount (0.01)
390+
* @return {number|string}
391+
*/
392+
function getHubMinAmount(destinationNetworkFee, hubFeeRate, hubFeeBaseRate = 0.01) {
393+
// minAmount = hubFeeBase - hubFee
394+
// But while form.amount increase hubFee increase too, so we need to find such formAmount which will be equal minAmount, it will be maximum minAmount
395+
396+
// Some 7 grade math below
397+
// hubFeeBase = (destinationNetworkFee + formAmount) * (0.01 / (1 - 0.01));
398+
// hubFee = (destinationNetworkFee + formAmount) * (hubFeeRate / (1 - hubFeeRate))
399+
// define (a = hubFeeBaseRate; b = hubFeeRate)
400+
// minAmount = (destinationNetworkFee + formAmount) * (a / (1 - a)) - (destinationNetworkFee + formAmount) * (b / (1 - b))
401+
// minAmount = (destinationNetworkFee + formAmount) * ((a / (1 - a) - (b / (1 - b));
402+
// minAmount = (destinationNetworkFee + formAmount) * x;
403+
404+
// Let's calculate factor x
405+
// x = a / (1 - a) - b / (1 - b)
406+
// x = a * (1-b) / ((1-a)*(1-b)) - b * (1-a) / ((1-a)*(1-b))
407+
// x = (a * (1-b) - b * (1-a)) / ((1-a)*(1-b))
408+
// x = (a - ab - b + ab) / ((1-a)*(1-b))
409+
// x = (a - b) / ((1-a)*(1-b))
410+
// const factor = (hubFeeBaseRate - hubFeeRate) / ((1 - hubFeeBaseRate) * (1 - hubFeeRate));
411+
const factor = new Big(hubFeeBaseRate).minus(hubFeeRate).div(new Big(1).minus(hubFeeBaseRate).times(new Big(1).minus(hubFeeRate))).toString();
412+
413+
// We are finding formAmount equal to minAmount (fa = formAmount, dnf = destinationNetworkFee)
414+
// fa = minAmount
415+
// fa = (fa + dnf) * x
416+
// fa = fa * x + dnf * x
417+
// fa - fa * x = dnf * x
418+
// fa * 1 - fa * x = dnf * x
419+
// fa * (1 -x) = dnf * x
420+
// fa = dnf * x / (1 - x)
421+
// const minAmount = destinationNetworkFee * factor / (1 - factor);
422+
const minAmount = new Big(destinationNetworkFee).times(factor).div(new Big(1).minus(factor)).toString();
423+
// add 1 pip because 0 will not pass validation too
424+
return new Big(minAmount).plus(1e-18).toString();
425+
}
378426
</script>
379427
380428
<template>
@@ -426,7 +474,7 @@ export default {
426474
:max-value="maxAmount"
427475
/>
428476
<span class="form-field__error" v-if="$v.form.amount.$dirty && !$v.form.amount.required">{{ $td('Enter amount', 'form.amount-error-required') }}</span>
429-
<span class="form-field__error" v-else-if="$v.form.amount.$dirty && (!$v.form.amount.minValue)">{{ $td('Invalid amount', 'form.amount-error-invalid') }}</span>
477+
<span class="form-field__error" v-else-if="$v.form.amount.$dirty && (!$v.form.amount.minValue)">{{ $td(`Minimum ${minAmount}`, 'form.amount-error-min', {min: minAmount}) }}</span>
430478
<span class="form-field__error" v-else-if="$v.form.amount.$dirty && !$v.form.amount.maxValue">{{ $td('Not enough', 'form.amount-error-not-enough') }} {{ form.coin }} ({{ $td('max.', 'hub.max') }} {{ pretty(maxAmount) }})</span>
431479
</div>
432480
<div class="u-cell u-cell--large--1-2 u-cell--large-down--order-minus">

lang/ru.js

+1
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ export default {
392392
'amount': 'Количество',
393393
'amount-error-required': 'Укажите количество',
394394
'amount-error-invalid': 'Некорректное количество',
395+
'amount-error-min': 'Минимум {min}',
395396
'amount-error-not-enough': 'Недостаточно',
396397
'number-invalid': 'Укажите положительное целое число',
397398
'fee': 'Монета для оплаты комиссии',

0 commit comments

Comments
 (0)