mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-05-19 07:29:32 +00:00
parent
bf9001c363
commit
d92a61fd9b
@ -172,7 +172,8 @@ Item {
|
|||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: navbar.currentIndex === 1
|
visible: navbar.currentIndex === 1
|
||||||
|
|
||||||
property int activeLiquidityTab: 0
|
property int activeLiquidityTab: 0
|
||||||
|
property real slippageTolerancePercent: 0.5
|
||||||
|
|
||||||
DummyPoolState {
|
DummyPoolState {
|
||||||
id: poolState
|
id: poolState
|
||||||
@ -216,16 +217,26 @@ Item {
|
|||||||
|
|
||||||
AddLiquidityForm {
|
AddLiquidityForm {
|
||||||
poolState: poolState
|
poolState: poolState
|
||||||
|
slippageTolerancePercent: liquidityView.slippageTolerancePercent
|
||||||
visible: liquidityView.activeLiquidityTab === 0
|
visible: liquidityView.activeLiquidityTab === 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: visible ? implicitHeight : 0
|
Layout.preferredHeight: visible ? implicitHeight : 0
|
||||||
|
|
||||||
|
onSlippageToleranceChangeRequested: function(tolerancePercent) {
|
||||||
|
liquidityView.slippageTolerancePercent = poolState.clampSlippageTolerancePercent(tolerancePercent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveLiquidityForm {
|
RemoveLiquidityForm {
|
||||||
poolState: poolState
|
poolState: poolState
|
||||||
|
slippageTolerancePercent: liquidityView.slippageTolerancePercent
|
||||||
visible: liquidityView.activeLiquidityTab === 1
|
visible: liquidityView.activeLiquidityTab === 1
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: visible ? implicitHeight : 0
|
Layout.preferredHeight: visible ? implicitHeight : 0
|
||||||
|
|
||||||
|
onSlippageToleranceChangeRequested: function(tolerancePercent) {
|
||||||
|
liquidityView.slippageTolerancePercent = poolState.clampSlippageTolerancePercent(tolerancePercent)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,19 +7,24 @@ Rectangle {
|
|||||||
|
|
||||||
required property DummyPoolState poolState
|
required property DummyPoolState poolState
|
||||||
|
|
||||||
|
property real slippageTolerancePercent: 0.5
|
||||||
property string amountA: ""
|
property string amountA: ""
|
||||||
property string amountB: ""
|
property string amountB: ""
|
||||||
property string lastEditedToken: "A"
|
property string lastEditedToken: "A"
|
||||||
readonly property real parsedA: root.poolState.parseAmount(root.amountA)
|
readonly property real parsedA: root.poolState.parseAmount(root.amountA)
|
||||||
readonly property real parsedB: root.poolState.parseAmount(root.amountB)
|
readonly property real parsedB: root.poolState.parseAmount(root.amountB)
|
||||||
readonly property var preview: root.poolState.addLiquidityPreview(root.parsedA, root.parsedB)
|
readonly property var preview: root.poolState.addLiquidityPreview(root.parsedA, root.parsedB)
|
||||||
|
readonly property int minLpReceived: root.poolState.minReceivedAmount(root.preview.deltaLp, root.slippageTolerancePercent)
|
||||||
readonly property bool hasAnyAmount: root.parsedA > 0 || root.parsedB > 0
|
readonly property bool hasAnyAmount: root.parsedA > 0 || root.parsedB > 0
|
||||||
readonly property bool amountAOverBalance: root.parsedA > root.poolState.walletBalanceA
|
readonly property bool amountAOverBalance: root.parsedA > root.poolState.walletBalanceA
|
||||||
readonly property bool amountBOverBalance: root.parsedB > root.poolState.walletBalanceB
|
readonly property bool amountBOverBalance: root.parsedB > root.poolState.walletBalanceB
|
||||||
|
readonly property bool minReceivedIsZero: root.hasAnyAmount && root.minLpReceived === 0
|
||||||
readonly property bool zeroTokenDeposit: root.hasAnyAmount && (root.preview.actualA === 0 || root.preview.actualB === 0)
|
readonly property bool zeroTokenDeposit: root.hasAnyAmount && (root.preview.actualA === 0 || root.preview.actualB === 0)
|
||||||
readonly property bool zeroLpDeposit: root.preview.actualA > 0 && root.preview.actualB > 0 && root.preview.deltaLp === 0
|
readonly property bool zeroLpDeposit: root.preview.actualA > 0 && root.preview.actualB > 0 && root.preview.deltaLp === 0
|
||||||
readonly property string warningText: root.zeroTokenDeposit ? qsTr("Deposit would be rejected because one token amount rounds to zero") : root.zeroLpDeposit ? qsTr("Deposit would mint 0 LP tokens") : ""
|
readonly property string warningText: root.zeroTokenDeposit ? qsTr("Deposit would be rejected because one token amount rounds to zero") : root.zeroLpDeposit ? qsTr("Deposit would mint 0 LP tokens") : ""
|
||||||
|
|
||||||
|
signal slippageToleranceChangeRequested(real tolerancePercent)
|
||||||
|
|
||||||
color: "#1D1D1D"
|
color: "#1D1D1D"
|
||||||
implicitHeight: content.implicitHeight + 20
|
implicitHeight: content.implicitHeight + 20
|
||||||
radius: 8
|
radius: 8
|
||||||
@ -128,6 +133,34 @@ Rectangle {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SlippageToleranceControl {
|
||||||
|
tolerancePercent: root.slippageTolerancePercent
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
onToleranceChangeRequested: function (tolerancePercent) {
|
||||||
|
root.slippageToleranceChangeRequested(tolerancePercent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
label: qsTr("Min LP received")
|
||||||
|
value: root.poolState.formatLpAmount(root.minLpReceived)
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: "#F08A76"
|
||||||
|
font.pixelSize: 12
|
||||||
|
lineHeight: 1.25
|
||||||
|
text: qsTr("Minimum received is 0. Increase amount or lower slippage.")
|
||||||
|
visible: root.minReceivedIsZero
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
color: "#F08A76"
|
color: "#F08A76"
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
|
|||||||
@ -8,6 +8,7 @@ Rectangle {
|
|||||||
|
|
||||||
required property DummyPoolState poolState
|
required property DummyPoolState poolState
|
||||||
|
|
||||||
|
property real slippageTolerancePercent: 0.5
|
||||||
property int burnAmount: 0
|
property int burnAmount: 0
|
||||||
readonly property int maxBurnAmount: root.poolState.clampBurnAmount(root.poolState.userLpBalance)
|
readonly property int maxBurnAmount: root.poolState.clampBurnAmount(root.poolState.userLpBalance)
|
||||||
readonly property bool hasLpTokens: root.maxBurnAmount > 0
|
readonly property bool hasLpTokens: root.maxBurnAmount > 0
|
||||||
@ -16,8 +17,13 @@ Rectangle {
|
|||||||
readonly property int preset75Amount: root.poolState.burnAmountForPercent(75)
|
readonly property int preset75Amount: root.poolState.burnAmountForPercent(75)
|
||||||
readonly property real removePercent: root.maxBurnAmount > 0 ? root.burnAmount * 100 / root.maxBurnAmount : 0
|
readonly property real removePercent: root.maxBurnAmount > 0 ? root.burnAmount * 100 / root.maxBurnAmount : 0
|
||||||
readonly property var preview: root.poolState.removeLiquidityPreview(root.burnAmount)
|
readonly property var preview: root.poolState.removeLiquidityPreview(root.burnAmount)
|
||||||
|
readonly property int minTokenAReceived: root.poolState.minReceivedAmount(root.preview.withdrawA, root.slippageTolerancePercent)
|
||||||
|
readonly property int minTokenBReceived: root.poolState.minReceivedAmount(root.preview.withdrawB, root.slippageTolerancePercent)
|
||||||
|
readonly property bool minReceivedIsZero: root.burnAmount > 0 && (root.minTokenAReceived === 0 || root.minTokenBReceived === 0)
|
||||||
readonly property string estimateHelp: qsTr("Estimated with the same integer floor math used by the remove-liquidity contract path.")
|
readonly property string estimateHelp: qsTr("Estimated with the same integer floor math used by the remove-liquidity contract path.")
|
||||||
|
|
||||||
|
signal slippageToleranceChangeRequested(real tolerancePercent)
|
||||||
|
|
||||||
color: "#1D1D1D"
|
color: "#1D1D1D"
|
||||||
implicitHeight: content.implicitHeight + 20
|
implicitHeight: content.implicitHeight + 20
|
||||||
radius: 8
|
radius: 8
|
||||||
@ -393,6 +399,41 @@ Rectangle {
|
|||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SlippageToleranceControl {
|
||||||
|
tolerancePercent: root.slippageTolerancePercent
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
onToleranceChangeRequested: function (tolerancePercent) {
|
||||||
|
root.slippageToleranceChangeRequested(tolerancePercent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
label: qsTr("Min %1 received").arg(root.poolState.tokenA)
|
||||||
|
value: root.poolState.formatTokenAmount(root.minTokenAReceived, root.poolState.tokenA)
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
SummaryRow {
|
||||||
|
label: qsTr("Min %1 received").arg(root.poolState.tokenB)
|
||||||
|
value: root.poolState.formatTokenAmount(root.minTokenBReceived, root.poolState.tokenB)
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: "#F08A76"
|
||||||
|
font.pixelSize: 12
|
||||||
|
lineHeight: 1.25
|
||||||
|
text: qsTr("Minimum received is 0. Increase amount or lower slippage.")
|
||||||
|
visible: root.minReceivedIsZero
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
SummaryRow {
|
SummaryRow {
|
||||||
label: qsTr("New reserve A")
|
label: qsTr("New reserve A")
|
||||||
value: root.poolState.formatTokenAmount(root.preview.newReserveA, root.poolState.tokenA)
|
value: root.poolState.formatTokenAmount(root.preview.newReserveA, root.poolState.tokenA)
|
||||||
|
|||||||
281
amm-ui/qml/components/SlippageToleranceControl.qml
Normal file
281
amm-ui/qml/components/SlippageToleranceControl.qml
Normal file
@ -0,0 +1,281 @@
|
|||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property real tolerancePercent: 0.5
|
||||||
|
property string customText: ""
|
||||||
|
readonly property string thresholdText: root.tolerancePercent <= 1 ? qsTr("Standard slippage") : root.tolerancePercent <= 5 ? qsTr("Higher slippage") : qsTr("High slippage risk")
|
||||||
|
readonly property string thresholdIcon: root.tolerancePercent <= 1 ? "i" : root.tolerancePercent <= 5 ? "!" : "!!"
|
||||||
|
|
||||||
|
signal toleranceChangeRequested(real tolerancePercent)
|
||||||
|
|
||||||
|
color: "#151515"
|
||||||
|
implicitHeight: content.implicitHeight + 20
|
||||||
|
radius: 8
|
||||||
|
border.color: customField.activeFocus ? "#F26A21" : "#343434"
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Component.onCompleted: root.restoreCustomText()
|
||||||
|
|
||||||
|
onTolerancePercentChanged: {
|
||||||
|
if (!customField.activeFocus) {
|
||||||
|
root.restoreCustomText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTolerance(value) {
|
||||||
|
const amount = Number(value) || 0;
|
||||||
|
return amount.toFixed(2).replace(/0+$/, "").replace(/[.]$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function restoreCustomText() {
|
||||||
|
root.customText = root.formatTolerance(root.tolerancePercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clampTolerance(value) {
|
||||||
|
return Math.max(0.01, Math.min(50, Number(value) || 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
function commitPreset(value) {
|
||||||
|
const nextValue = root.clampTolerance(value);
|
||||||
|
root.customText = root.formatTolerance(nextValue);
|
||||||
|
root.toleranceChangeRequested(nextValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
function commitCustom() {
|
||||||
|
const parsed = Number(root.customText);
|
||||||
|
|
||||||
|
if (root.customText.length === 0 || !isFinite(parsed) || parsed < 0) {
|
||||||
|
root.restoreCustomText();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
root.commitPreset(parsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 10
|
||||||
|
spacing: 8
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: "#A9A098"
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: qsTr("Slippage tolerance")
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
spacing: 6
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: preset01
|
||||||
|
|
||||||
|
readonly property real presetValue: 0.1
|
||||||
|
readonly property bool selected: Math.abs(root.tolerancePercent - presetValue) < 0.000001
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
focusPolicy: Qt.StrongFocus
|
||||||
|
hoverEnabled: true
|
||||||
|
text: qsTr("0.1%")
|
||||||
|
|
||||||
|
Accessible.name: qsTr("Set slippage tolerance to 0.1 percent")
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: 44
|
||||||
|
|
||||||
|
onClicked: root.commitPreset(presetValue)
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
color: preset01.hovered || preset01.activeFocus || preset01.selected ? "#151515" : "#A9A098"
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 11
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: preset01.text
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
border.color: preset01.activeFocus || preset01.selected ? "#F26A21" : "#343434"
|
||||||
|
border.width: 1
|
||||||
|
color: preset01.pressed ? "#D95C1E" : preset01.selected ? "#F26A21" : preset01.hovered || preset01.activeFocus ? "#E7E1D8" : "#101010"
|
||||||
|
radius: 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: preset05
|
||||||
|
|
||||||
|
readonly property real presetValue: 0.5
|
||||||
|
readonly property bool selected: Math.abs(root.tolerancePercent - presetValue) < 0.000001
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
focusPolicy: Qt.StrongFocus
|
||||||
|
hoverEnabled: true
|
||||||
|
text: qsTr("0.5%")
|
||||||
|
|
||||||
|
Accessible.name: qsTr("Set slippage tolerance to 0.5 percent")
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: 44
|
||||||
|
|
||||||
|
onClicked: root.commitPreset(presetValue)
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
color: preset05.hovered || preset05.activeFocus || preset05.selected ? "#151515" : "#A9A098"
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 11
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: preset05.text
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
border.color: preset05.activeFocus || preset05.selected ? "#F26A21" : "#343434"
|
||||||
|
border.width: 1
|
||||||
|
color: preset05.pressed ? "#D95C1E" : preset05.selected ? "#F26A21" : preset05.hovered || preset05.activeFocus ? "#E7E1D8" : "#101010"
|
||||||
|
radius: 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: preset10
|
||||||
|
|
||||||
|
readonly property real presetValue: 1.0
|
||||||
|
readonly property bool selected: Math.abs(root.tolerancePercent - presetValue) < 0.000001
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
focusPolicy: Qt.StrongFocus
|
||||||
|
hoverEnabled: true
|
||||||
|
text: qsTr("1.0%")
|
||||||
|
|
||||||
|
Accessible.name: qsTr("Set slippage tolerance to 1.0 percent")
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: 44
|
||||||
|
|
||||||
|
onClicked: root.commitPreset(presetValue)
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
color: preset10.hovered || preset10.activeFocus || preset10.selected ? "#151515" : "#A9A098"
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 11
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: preset10.text
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
border.color: preset10.activeFocus || preset10.selected ? "#F26A21" : "#343434"
|
||||||
|
border.width: 1
|
||||||
|
color: preset10.pressed ? "#D95C1E" : preset10.selected ? "#F26A21" : preset10.hovered || preset10.activeFocus ? "#E7E1D8" : "#101010"
|
||||||
|
radius: 6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: customField.activeFocus ? "#1F1B18" : "#101010"
|
||||||
|
radius: 6
|
||||||
|
border.color: customField.activeFocus ? "#F26A21" : "#343434"
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Layout.minimumHeight: 44
|
||||||
|
Layout.preferredWidth: 88
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
fill: parent
|
||||||
|
leftMargin: 8
|
||||||
|
rightMargin: 8
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: customField
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
color: "#E7E1D8"
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 12
|
||||||
|
horizontalAlignment: Text.AlignRight
|
||||||
|
inputMethodHints: Qt.ImhFormattedNumbersOnly
|
||||||
|
placeholderText: qsTr("0.5")
|
||||||
|
selectByMouse: true
|
||||||
|
selectedTextColor: "#151515"
|
||||||
|
selectionColor: "#F26A21"
|
||||||
|
text: root.customText
|
||||||
|
validator: RegularExpressionValidator {
|
||||||
|
regularExpression: /[0-9]*([.][0-9]*)?/
|
||||||
|
}
|
||||||
|
|
||||||
|
Accessible.name: qsTr("Custom slippage tolerance percent")
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: 42
|
||||||
|
|
||||||
|
onEditingFinished: root.commitCustom()
|
||||||
|
onTextEdited: root.customText = text
|
||||||
|
Keys.onEscapePressed: {
|
||||||
|
root.restoreCustomText();
|
||||||
|
customField.focus = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Item {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: "#A9A098"
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 12
|
||||||
|
text: qsTr("%")
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
|
Layout.preferredWidth: 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
spacing: 6
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: root.tolerancePercent <= 1 ? "#8FD6A4" : root.tolerancePercent <= 5 ? "#F2B366" : "#F08A76"
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: 11
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: root.thresholdIcon
|
||||||
|
|
||||||
|
Layout.preferredWidth: 18
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: root.tolerancePercent <= 1 ? "#8FD6A4" : root.tolerancePercent <= 5 ? "#F2B366" : "#F08A76"
|
||||||
|
font.pixelSize: 11
|
||||||
|
text: root.thresholdText
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
color: "#A9A098"
|
||||||
|
font.pixelSize: 11
|
||||||
|
text: qsTr("Allowed range: 0.01% to 50%.")
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -104,6 +104,17 @@ QtObject {
|
|||||||
return Math.min(floorAmount(value), Math.max(0, floorAmount(userLpBalance)));
|
return Math.min(floorAmount(value), Math.max(0, floorAmount(userLpBalance)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clampSlippageTolerancePercent(value) {
|
||||||
|
return Math.max(0.01, Math.min(50, Number(value) || 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
function minReceivedAmount(previewAmount, slippageTolerancePercent) {
|
||||||
|
const safeAmount = floorAmount(previewAmount);
|
||||||
|
const safeSlippage = clampSlippageTolerancePercent(slippageTolerancePercent);
|
||||||
|
|
||||||
|
return Math.floor(safeAmount * (1 - safeSlippage / 100));
|
||||||
|
}
|
||||||
|
|
||||||
function burnAmountForPercent(percent) {
|
function burnAmountForPercent(percent) {
|
||||||
const safePercent = Math.max(0, Math.min(100, Number(percent) || 0));
|
const safePercent = Math.max(0, Math.min(100, Number(percent) || 0));
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user