taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

047-stefan.rst (7964B)


      1 DD 47: STEFAN
      2 #############
      3 
      4 :Design status: Accepted
      5 :Implementation status: Partial
      6 :DD shepherd: TBD
      7 :Historical contributors: Christian Grothoff, Florian Dold
      8 :First published: 2023-08-11
      9 :Last substantive change: 2023-08-24
     10 :Implementation evidence: exchange (2023-08-11), merchant (2023-08-24)
     11 :Normative references: ``core/exchange/get-keys.rst``, ``manpages/taler-exchange.conf.5.rst``
     12 
     13 Summary
     14 =======
     15 
     16 The Standardized Template for Effective-Fee Approximation Numbers (STEFAN)
     17 is a feature to ensure customers see consistent fees for equivalent
     18 purchases (largely) independent of the specific coins selected. It will also
     19 make it easier for merchants to configure their systems to pay all reasonable
     20 fees.
     21 
     22 
     23 Motivation
     24 ==========
     25 
     26 Taler has a logarithmic fee structure for good reasons (to compete in
     27 different market segments with reasonable profit margins). However, the
     28 logarithmic fee structure inherently implies that the specific coin selection
     29 made by the wallet can result in very different fees being applicable for the
     30 same amount at the same merchant merely due to different coins being available
     31 in the wallet. To minimize support costs, it is important that customers do
     32 not need to be aware of the concept of coins and are instead shown consistent
     33 fees for equivalent transactions.
     34 
     35 
     36 Requirements
     37 ============
     38 
     39   - keep the logarithmic nature of the fees (proportionally high fees
     40     for tiny amounts, medium fees for medium amounts, low fees for large amounts)
     41   - same purchase, same perceived price; prices are predictable for users
     42   - enable merchants to easily cover all fees in most cases
     43 
     44 
     45 Proposed Solution
     46 =================
     47 
     48 The proposal is for the exchange to advertise three STEFAN-parameters that
     49 encode a fee curve of the form ``stefan_abs + stefan_log * log P +
     50 stefan_lin * P`` where P represents the gross price to be paid.
     51 Here, the numerical value for P is to be computed by
     52 dividing the actual gross price by the smallest denomination
     53 offered by the exchange.
     54 
     55 .. note::
     56 
     57    This calculation is already done using floating point (!) as we want the
     58    STEFAN-curve to be smooth and not a step-function. This is also needed so
     59    that we can invert the computation and calculate gross amounts from net
     60    amounts and actually get a nice invertible computation where both
     61    directions always match.  Note that the computation itself is nevertheless
     62    non-trivial involving Newton's method to solve ``f(x)=0`` using a
     63    well-estimated starting point for the iteration to avoid divergence issues.
     64    Finally, while we do the STEFAN-curve computations using doubles, we should
     65    then convert the final amounts back into "human-friendly" numbers rounding
     66    towards the nearest value that can be represented using the canonical
     67    number of decimal places at the exchange.  libtalerexchange (C) has a
     68    reference implementation of the gross-net conversion functions (in both
     69    directions) and of the final rounding logic.  This exception to the general
     70    rule of no floating-points for amounts is acceptable as it is not actually
     71    done at the protocol level but only in internal computations of the wallet
     72    and merchant backend as part of the STEFAN cost estimation logic, which by
     73    definition is an estimate and does not need to be exact.  (And even if
     74    wallet and merchant backend were to (slightly) disagree about the
     75    computations due to different floating point implementations, everything
     76    would still be fine, and even a significant disagreement would not cause
     77    anything but resurface the UI issue the STEFAN-curves addresses.)
     78 
     79 The fee curve will be the displayed fee, except in cases where the coin
     80 selection is exceptionally bad (which should happen in substantially less than
     81 1% of all cases).  The fee curve will also be used as the maximum fee a
     82 merchant will cover unless the merchant overrides the mechanism.
     83 
     84 In the most common case, where the STEFAN-curve fee is at or below what the
     85 merchant covers, no fees are displayed, except in the exceptionally rare
     86 case where the actual fees (due to unfortunate coin selection) are above
     87 both the exchange's STEFAN-curve and the what the merchant covers. In this
     88 last case the fees shown will be the actual fees minus what the merchant
     89 covers and here the fees may vary even for equivalent transactions.
     90 
     91 In the uncommon case where a merchant does not cover any fees or only covers
     92 parts of the fee according to the STEFAN-curve, the displayed fee will be the
     93 value on the STEFAN-curve minus the amount covered by the merchant. If the
     94 actual fees paid end up being below the approximation by the STEFAN-curve, the
     95 delta is (by default) *hidden* from the balance of the user to simulate a
     96 consistent fee.
     97 
     98 However, only the total available balance is marked down based on the
     99 STEFAN-curve value.  Thus, the wallet will contains coins with a potentially
    100 higher balance value than what is shown to the user. This difference is
    101 reconciled annually by adding a special transaction that increases the wallet
    102 balance to eliminate the difference without any actual network interaction.
    103 The entry in the transaction history that boosts the balance links to an
    104 explanation.  We may consider suggesting the user to donate the windfall.
    105 
    106 In developer mode, the user should probably be given the choice to see the
    107 delta, to disable the feature, and/or to force the windfall transaction to
    108 happen immediately.
    109 
    110 
    111 Computing the curve
    112 -------------------
    113 
    114 Typically, the ``stefan_abs`` value should represent a single wire transfer
    115 fee. The ``stefan_log`` value should be computed to approximate the deposit
    116 (and if applicable) refresh and withdraw fees for a coin, to be multiplied by
    117 the number of coins.  In a canonical setup, ``stefan_lin`` would be zero.
    118 However, if an exchange is configured to use a linear fee structure, then
    119 ``stefan_lin`` would become applicable.
    120 
    121 The taler-wallet-cli should have an option to compute the STEFAN-values
    122 given a denomination fee structure. This computation could probably be done
    123 either analytically (if the fee structure is systematic) or by simulation.
    124 
    125 Modifications to the merchant
    126 -----------------------------
    127 
    128 Instead of having (just) a "default fee", merchants should have an option to
    129 use the STEFAN-curve when computing the fees they would be willing to cover.
    130 
    131 Modifications to the exchange
    132 -----------------------------
    133 
    134 The STEFAN-curve can be configured using three simple configuration values
    135 in the ``[exchange]`` section. The resulting values should be shared as
    136 part of the ``/keys`` response, without digital signature.
    137 
    138 Modifications to the wallets
    139 ----------------------------
    140 
    141 The STEFAN-curves will be useful as an easy approximate way to compare
    142 exchange fee structures. However, wallets may not want to just trust an
    143 exchange to honestly report STEFAN-curve values but could possibly use
    144 a simulation to check that the given STEFAN-curve matches the actual fees.
    145 
    146 Wallets will need to keep the hidden STEFAN-balance and add the annual
    147 internal reconcilliation transaction.
    148 
    149 Wallets will need to compute both the STEFAN-fee for display and still
    150 do their own internal actual coin selection to minimize fees.
    151 
    152 
    153 
    154 Definition of Done
    155 ==================
    156 
    157   - [x] exchange modified
    158   - [x] merchant understands STEFAN curve in backend
    159   - [ ] merchant SPA has configuration option to enable use of STEFAN-curves
    160   - [ ] wallet-core uses STEFAN-curves to compute display fees
    161   - [ ] wallet-core supports annual reconcilliation transaction
    162   - [ ] wallet GUIs use STEFAN-curves when comparing exchange fee structures
    163 
    164 
    165 Alternatives
    166 ============
    167 
    168 Refresh fees could additionally be waived if the refresh operation yields coins
    169 of a lower denomination than the original coin.  We should check if this allows
    170 us to define tighter STEFAN-curves.
    171 
    172 
    173 Drawbacks
    174 =========
    175 
    176 
    177 
    178 Discussion / Q&A
    179 ================
    180 
    181 (This should be filled in with results from discussions on mailing lists / personal communication.)