The method is purely score-based, which means that all the information required to calculate payouts can be encoded with a single score value per participant. There is no fundamental need to keep a history of shares. However, because the scores grow exponentially, it is advised to use a logarithmic scale to store their values and do the calculations.

We will denote by B the block reward (assumed constant) and p = 1/Difficulty. In addition there are 3 parameters which can be adjusted to balance average fee, operator variance, share- and pool-based participant variance, and maturity time:

f - Fixed fee.

c - Average variable fee. The average total fee will be (c+f-cf)B per block. Increasing c reduces participants' variance but increases operator's variance.

o - Cross-round leakage. Increasing o reduces participants' share-based variance but increases maturity time. When o=0 this becomes the geometric method. When o->1 this becomes a variant of PPLNS, with exponential decay instead of 0-1 cutoff (note that "exponential" does not mean "rapid", the decay can be chosen to be slow). For o=1, c must be 0 and r (defined below) can be chosen freely instead of being given by a formula.

The method is as follows:

1. When the pool first starts running, initialize s=1. Initialize the scores of all workers to 0.

2. Set r = 1 + p(1-c)(1-o)/c. If at any point the difficulty changes, p and then r should be recalculated.

3. When a share is found, increase by p*s*B the score of the participant who found it. Set s=s*r.

4. If the share found happens to be a valid block, then after doing #3, also do the following for each participant: Letting S be his score, give him a payout of (S(r-1)(1-f))/(ps). Set S=S*o. The remaining reward is given to the operator. Or, if the total is higher than the block reward (only possible if f<0), the operator pays the difference out of his own funds.

The inutition is this: Instead of keeping the score unchanged when a block is found (as in PPLNS) or setting all scores to 0 and effectively transferring them to the operator (as in the geometric method), a part of the score is transferred to the operator. When rounds are long, participants get to keep most of their score between rounds and this is similar to PPLNS. However, if several blocks are found in rapid succession, the operator will collect a large portion of the score and thus be the primary beneficiary of the good fortune. The fees collected this way allow letting f be negative, sweetening the rewards of long rounds. Overall, this decreases the dependence of participants' rewards on the pool's luck, thus reducing the variance caused by it.

The variance of the payout for a single submitted share is

(1-c)^4(1-o)(1-p)p^2(1-f)^2B^2

------------------------------

(2-c+co)c+(1-c)^2(1-o)p

(1-c)^4(1-o)(1-p)p^2(1-f)^2B^2

------------------------------

(2-c+co)c+(1-c)^2(1-o)p

Notably, the factor of (1-o) allows this to be much smaller than the variance of the geometric method, if o is chosen close to 1. This value is of relevance, though, only to small miners, and the potential advantage of this system is for large miners (which suffer from pool-based variance but not so much from share-based variance). It would be of interest to evaluate the total variance for a participant constituting a given portion of the pool, and the variance of the operator. So far I was unable to derive symbolic expressions for these, but they can be evaluated in simulation. For c = 0.5, o = 1-c = 0.5, f = (-c)/(1-c) = -1 I got that a miner constituting the entirety of the pool has about 30% of solo variance (instead of 100% as in PPLNS), and the operator's variance is about 25% of PPS variance.

The geometric method was so called because shares decay in a geometric sequence, and its analysis crucially depends on summation of geometric series and the fact that round length follows the geometric distribution. Because in this new method shares decay geometrically along two directions, both for every share found and for every block found, I call it the double geometric method.

The variables used in the calculations grow rapidly, so if the method is implemented naively, they will overflow the data types used. Thus the implementation should use one of the following:

a. Periodic rescaling: The only thing that matters is the values of the scores relative to the variable s. Thus, if the values grow to large, all that is needed is to rescale them. This means dividing the scores of all participants by s, and then setting s=1. This should be done once in a while, the exact times do not matter (it can even be done for every share).

b. Logarithmic scale: Instead of maintaining the variables themselves, their logarithms are stored and updated. The following is the method expressed in logarithmic scale, denoting by log the natural logarithm function and by exp the natural exponentiation function:

1. When the pool first starts running, initialize ls=0. For every worker define a variable lS and initialize it to negative infinity (or a negative number of very large magnitude, say -1000000), and do this also for every worker which later joins.

2. Set r = 1 + p(1-c)(1-o)/c, lr = log(r). If at any point the difficulty changes, p, r and lr should be recalculated.

3. When a share is found, let lS = ls + log(exp(lS-ls) + pB) for the participant who found it. Set ls = ls + lr.

4. If the share found happens to be a valid block, then after doing #3, also do the following for each participant: Give him a payout of (exp(lS-ls)*(r-1)*(1-f))/p. Set lS = lS + log(o).

For display purposes, the quantity that should be shown as the score of a worker is S/s (or exp(lS-ls) in logarithmic scale). This represents the expected payout the worker should receive in addition to any confirmed rewards (before fees). To display the expected payout after deducting fees, use (1-f)*(1-c)*S/s, or (1-f)*(1-c)*exp(lS-ls).