summaryrefslogtreecommitdiff
path: root/design-documents/047-stefan.rst
diff options
context:
space:
mode:
Diffstat (limited to 'design-documents/047-stefan.rst')
-rw-r--r--design-documents/047-stefan.rst172
1 files changed, 172 insertions, 0 deletions
diff --git a/design-documents/047-stefan.rst b/design-documents/047-stefan.rst
new file mode 100644
index 00000000..4cef1865
--- /dev/null
+++ b/design-documents/047-stefan.rst
@@ -0,0 +1,172 @@
+DD 47: STEFAN
+#############
+
+Summary
+=======
+
+The Standardized Template for Effective-Fee Approximation Numbers (STEFAN)
+is a feature to ensure customers see consistent fees for equivalent
+purchases (largely) independent of the specific coins selected. It will also
+make it easier for merchants to configure their systems to pay all reasonable
+fees.
+
+
+Motivation
+==========
+
+Taler has a logarithmic fee structure for good reasons (to compete in
+different market segments with reasonable profit margins). However, the
+logarithmic fee structure inherently implies that the specific coin selection
+made by the wallet can result in very different fees being applicable for the
+same amount at the same merchant merely due to different coins being available
+in the wallet. To minimize support costs, it is important that customers do
+not need to be aware of the concept of coins and are instead shown consistent
+fees for equivalent transactions.
+
+
+Requirements
+============
+
+ - keep the logarithmic nature of the fees (proportionally high fees
+ for tiny amounts, medium fees for medium amounts, low fees for large amounts)
+ - same purchase, same perceived price; prices are predictable for users
+ - enable merchants to easily cover all fees in most cases
+
+
+Proposed Solution
+=================
+
+The proposal is for the exchange to advertise three STEFAN-parameters that
+encode a fee curve of the form ``stefan_abs + stefan_log * log P +
+stefan_lin * P`` where P represents the gross price to be paid.
+Here, the numerical value for P is to be computed by
+dividing the actual gross price by the smallest denomination
+offered by the exchange.
+
+.. note::
+
+ This calculation is already done using floating point (!) as we want the
+ STEFAN-curve to be smooth and not a step-function. This is also needed so
+ that we can invert the computation and calculate gross amounts from net
+ amounts and actually get a nice invertible computation where both
+ directions always match. Note that the computation itself is nevertheless
+ non-trivial involving Newton's method to solve ``f(x)=0`` using a
+ well-estimated starting point for the iteration to avoid divergence issues.
+ Finally, while we do the STEFAN-curve computations using doubles, we should
+ then convert the final amounts back into "human-friendly" numbers rounding
+ towards the nearest value that can be represented using the canonical
+ number of decimal places at the exchange. libtalerexchange (C) has a
+ reference implementation of the gross-net conversion functions (in both
+ directions) and of the final rounding logic. This exception to the general
+ rule of no floating-points for amounts is acceptable as it is not actually
+ done at the protocol level but only in internal computations of the wallet
+ and merchant backend as part of the STEFAN cost estimation logic, which by
+ definition is an estimate and does not need to be exact. (And even if
+ wallet and merchant backend were to (slightly) disagree about the
+ computations due to different floating point implementations, everything
+ would still be fine, and even a significant disagreement would not cause
+ anything but resurface the UI issue the STEFAN-curves addresses.)
+
+The fee curve will be the displayed fee, except in cases where the coin
+selection is exceptionally bad (which should happen in substantially less than
+1% of all cases). The fee curve will also be used as the maximum fee a
+merchant will cover unless the merchant overrides the mechanism.
+
+In the most common case, where the STEFAN-curve fee is at or below what the
+merchant covers, no fees are displayed, except in the exceptionally rare
+case where the actual fees (due to unfortunate coin selection) are above
+both the exchange's STEFAN-curve and the what the merchant covers. In this
+last case the fees shown will be the actual fees minus what the merchant
+covers and here the fees may vary even for equivalent transactions.
+
+In the uncommon case where a merchant does not cover any fees or only covers
+parts of the fee according to the STEFAN-curve, the displayed fee will be the
+value on the STEFAN-curve minus the amount covered by the merchant. If the
+actual fees paid end up being below the approximation by the STEFAN-curve, the
+delta is (by default) *hidden* from the balance of the user to simulate a
+consistent fee.
+
+However, only the total available balance is marked down based on the
+STEFAN-curve value. Thus, the wallet will contains coins with a potentially
+higher balance value than what is shown to the user. This difference is
+reconciled annually by adding a special transaction that increases the wallet
+balance to eliminate the difference without any actual network interaction.
+The entry in the transaction history that boosts the balance links to an
+explanation. We may consider suggesting the user to donate the windfall.
+
+In developer mode, the user should probably be given the choice to see the
+delta, to disable the feature, and/or to force the windfall transaction to
+happen immediately.
+
+
+Computing the curve
+-------------------
+
+Typically, the ``stefan_abs`` value should represent a single wire transfer
+fee. The ``stefan_log`` value should be computed to approximate the deposit
+(and if applicable) refresh and withdraw fees for a coin, to be multiplied by
+the number of coins. In a canonical setup, ``stefan_lin`` would be zero.
+However, if an exchange is configured to use a linear fee structure, then
+``stefan_lin`` would become applicable.
+
+The taler-wallet-cli should have an option to compute the STEFAN-values
+given a denomination fee structure. This computation could probably be done
+either analytically (if the fee structure is systematic) or by simulation.
+
+Modifications to the merchant
+-----------------------------
+
+Instead of having (just) a "default fee", merchants should have an option to
+use the STEFAN-curve when computing the fees they would be willing to cover.
+
+Modifications to the exchange
+-----------------------------
+
+The STEFAN-curve can be configured using three simple configuration values
+in the ``[exchange]`` section. The resulting values should be shared as
+part of the ``/keys`` response, without digital signature.
+
+Modifications to the wallets
+----------------------------
+
+The STEFAN-curves will be useful as an easy approximate way to compare
+exchange fee structures. However, wallets may not want to just trust an
+exchange to honestly report STEFAN-curve values but could possibly use
+a simulation to check that the given STEFAN-curve matches the actual fees.
+
+Wallets will need to keep the hidden STEFAN-balance and add the annual
+internal reconcilliation transaction.
+
+Wallets will need to compute both the STEFAN-fee for display and still
+do their own internal actual coin selection to minimize fees.
+
+
+
+Definition of Done
+==================
+
+ - exchange modified (DONE)
+ - merchant understands STEFAN curve in backend (DONE)
+ - merchant SPA has configuration option to enable use of STEFAN-curves
+ - wallet-core uses STEFAN-curves to compute display fees
+ - wallet-core supports annual reconcilliation transaction
+ - wallet GUIs use STEFAN-curves when comparing exchange fee structures
+
+
+Alternatives
+============
+
+Refresh fees could additionally be waived if the refresh operation yields coins
+of a lower denomination than the original coin. We should check if this allows
+us to define tighter STEFAN-curves.
+
+
+Drawbacks
+=========
+
+
+
+Discussion / Q&A
+================
+
+(This should be filled in with results from discussions on mailing lists / personal communication.)