PoolTogether

Analysis of v4 draws (bis)

I extended my set of scripts for calculating the prize distributions a bit more to allow for easier analysis. Upon examining the results, I found some unexpected results.

This is a table of all $2500 winners sorted per draw up to draw 38:

 network  |                   address                  | draw_id | claimable_prizes | claimable_picks
----------+--------------------------------------------+---------+------------------+-----------------
 ethereum | 0x5edcf547ece0ea1765d6c02e9e5bae53b52e09d4 |       1 |    {2500,100}    | {177340,6842}
 polygon  | 0x392027fdc620d397ca27f0c1c3dcb592f27a4dc3 |       1 |    {2500,100}    | {36853,26487}
 ethereum | 0x5edcf547ece0ea1765d6c02e9e5bae53b52e09d4 |       2 |    {2500,100}    | {214958,65129}
 polygon  | 0x238926025e84475e3182774df480021470f8f978 |       2 |    {2500,10}     | {1970,894}
 ethereum | 0x09528b6c6fc792eff0c70563c9b4c4c6e38da61d |       2 |    {2500,10}     | {4089,1386}
 polygon  | 0x3dc3aad10ea65bbba08f2bcaec64bb9d5948958e |       4 |    {2500,100}    | {9930,1500}
 ethereum | 0x636bae3f76b4ccb486f50bf192ea2a8d22d1a79a |       4 |    {2500,100}    | {39879,15469}
 polygon  | 0x16a92f145f3b9ddca3bfc7e9d7fe97f1b193c22a |       5 |    {2500,100}    | {490,746}
 ethereum | 0x5edcf547ece0ea1765d6c02e9e5bae53b52e09d4 |       5 |    {2500,100}    | {189901,6108}
 polygon  | 0xe07e487d5a5e1098bbb4d259dac5ef83ae273f4e |       5 |    {2500}        | {27}
 polygon  | 0x5e4c09abf931b6369ab451503be546241a101fdc |       6 |    {2500}        | {255}
 polygon  | 0x5c10afd2e8c8ae7e282aea60759209f32edfe3d8 |       7 |    {2500,10}     | {17393,3960}
 polygon  | 0x994db2e89a886a80c5495accfdb18e733b434a2b |       8 |    {2500,10}     | {1054,109}
 polygon  | 0x187dcdaac283c78f95a8c2ef3ba611b958f4f3e8 |       9 |    {2500,10}     | {7983,719}
 ethereum | 0xd18236cd213f39d078177b6f6908f0e44e88e4aa |      10 |    {2500,100}    | {82098,29024}
 polygon  | 0xa6faa95b692962d1faaa6b43a6f20545e0d40861 |      12 |    {2500,10}     | {5169,5717}
 polygon  | 0x5a872919133bfe715ecb7fc6a12ee2b59768168f |      12 |    {2500,10}     | {6663,2114}
 ethereum | 0xe866d36a84ff74ca4d9277abcb83640bb2cd2523 |      12 |    {2500,10}     | {51526,8371}
 polygon  | 0xd66f2f1d86c0c5477aa1612ca92f03297a5477b0 |      14 |    {2500,10}     | {51014,640}
 polygon  | 0x685c66df2a77fbc188371b3470d5a2adca538a03 |      15 |    {2500,10}     | {11216,3432}
 polygon  | 0x8ae76ffd692ed84ec160455cd15408fb5d8a00a4 |      16 |    {2500}        | {2117}
 polygon  | 0x3fed71848b74b9f3ff26544cad368c082cb31961 |      16 |    {2500,10}     | {14095,5076}
 polygon  | 0xf89bb80788a728688015765c8f4b75f96a87a5b3 |      18 |    {2500,10}     | {25643,4083}
 polygon  | 0x238926025e84475e3182774df480021470f8f978 |      19 |    {2500,10}     | {5950,1655}
 polygon  | 0xc28bbeb8dcf086aeaf6e50259c553288a16e2a97 |      20 |    {2500,10}     | {1943,1402}
 polygon  | 0xf81cf588c563c4134b26eac8dd468aba887f41b5 |      21 |    {2500}        | {4686}
 polygon  | 0xf89bb80788a728688015765c8f4b75f96a87a5b3 |      22 |    {2500,100}    | {43657,32850}
 polygon  | 0xf232f53d5782147342766d0ea98f96529aaebf6a |      23 |    {2500,10}     | {1190,955}
 polygon  | 0x5c10afd2e8c8ae7e282aea60759209f32edfe3d8 |      23 |    {2500,10}     | {19305,8418}
 polygon  | 0x1f5f84940f3d5dfb72cf4df10df3234f02794ca9 |      25 |    {2500}        | {660}
 ethereum | 0x5edcf547ece0ea1765d6c02e9e5bae53b52e09d4 |      26 |    {2500,10}     | {48251,1498}
 polygon  | 0x85bd4f508b2cd7a17bdfca628059b3b787546726 |      27 |    {2500}        | {183}
 polygon  | 0x74060aebcddace26962f5614f12428c70e2492ca |      28 |    {2500,10}     | {1355,1421}
 polygon  | 0xbe80d8c96c0d5b5aed63b370b495650f30be3724 |      28 |    {2500}        | {3855}
 polygon  | 0xe3d799b498b5f307ba252a9f609e93a2faf37172 |      29 |    {2500}        | {2469}
 polygon  | 0x585fced8e5d357d6f7192de41d0b2d839795d437 |      30 |    {2500}        | {335}
 polygon  | 0x51bc9862ad17023fa88435f51fcaa6e677b2ca97 |      31 |    {2500,10}     | {8181,13237}
 polygon  | 0xc779f7bd848b56a606d8c61502da8264b11f420d |      31 |    {2500}        | {1066}
 ethereum | 0x2024f13b2fdb7957feb422af38edd5218e79ce05 |      32 |    {2500,100}    | {10168,25131}
 polygon  | 0xd79b646031ae71f77de7a50cc5f189f5c62b7a5d |      33 |    {2500,10}     | {56340,4374}
 polygon  | 0x07e836e86f212229c5c4cea8fc556eca87cfab64 |      34 |    {2500,10}     | {5713,1211}
 polygon  | 0x9aa4e6641fefd0764bfebdeda637e7782d7ed4dc |      34 |    {2500,10}     | {1138,8317}
 polygon  | 0x685c66df2a77fbc188371b3470d5a2adca538a03 |      34 |    {2500,10}     | {2126,6400}
 polygon  | 0x0092f2ed23041e6c1355d94a9f4338cf779d03d4 |      34 |    {2500}        | {840}
 polygon  | 0xc7e36bc2f80543b6c244b147606f9501da6c6561 |      35 |    {2500}        | {273}
 ethereum | 0xd18236cd213f39d078177b6f6908f0e44e88e4aa |      36 |    {2500,100}    | {4541,42877}
 polygon  | 0x915e0833be6713260af1ccf7467a37411fb790c0 |      37 |    {2500}        | {1130}
 polygon  | 0xd79b646031ae71f77de7a50cc5f189f5c62b7a5d |      38 |    {2500,100}    | {36773,60614}
 polygon  | 0x2f49b721cc086be9495d5067958f69098d3c72ab |      38 |    {2500}        | {265}
 polygon  | 0xa8afffdffb30c29db59788d357d778dd4210feea |      38 |    {2500,10}     | {5543,348}

The thing that struck me is that, while there are a couple of days / draws without a single $2500 winner. There are a lot more days with more than one $2500 winner:

   Winners  |                                         Days                                          
 -----------+---------------------------------------------------------------------------------------
    0 (5)   |  3, 11, 13, 17, 24
    1 (22)  |  6, 7, 8, 9, 10, 14, 15, 18, 19, 20, 21, 22, 25, 26, 27, 29, 30, 32, 33, 35, 36, 37
    2 (6)   |  1, 4, 16, 23, 28, 31
    3 (4)   |  2, 5, 12, 38
    4 (1)   |  34

In total, over 38 draws, we have 50 $2500 winners. That’s 1.3 winners on average per day. Granted, most days we only have one winner, but I’m still somewhat concerned about this. Obviously, maybe my tools suck and they are wrong. It’s impossible to fully validate these results since prizes that are not claimed are “invisible”.

Let’s take a look at the addresses from draw 34 though. Luckily for me, all of them claimed their prizes for draw 34, confirming that my calculations are not off. If we look at the amounts they claimed and at the picks they claimed, those are also fully in accordance with the data spit out by my scripts.
Claim by 0x07e836e86f212229c5c4cea8fc556eca87cfab64
Claim by 0x9aa4e6641fefd0764bfebdeda637e7782d7ed4dc
Claim by 0x685c66df2a77fbc188371b3470d5a2adca538a03
Claim by 0x0092f2ed23041e6c1355d94a9f4338cf779d03d4

What’s your take on this? There are lies, damned lies and statistics, but at least to me above data seems to be a bit too much to be purely a statistical outlier. Could there be something wrong with the prize distributions? Do we need to look into this a bit further before tweaking them again?

2 Likes

There is a v4-simulator app that allows you to run a simulation of the number of prizes.

You can run a prize count simulation like so:

yarn cli counts -i 38 -br 2

This will run 38 iterations of a random simulation with bit range of 2.

Here is the first run:

Using bit range of 2
Using cardinality of 5
Using iterations of 38
Total computed probability space: 1024
Estimated count per iteration of prize 5: 1
Estimated count per iteration of prize 4: 3
Estimated count per iteration of prize 3: 12
Estimated count per iteration of prize 2: 48
Estimated count per iteration of prize 1: 192
Simulation matched 5: 45
Simulation matched 4: 122
Simulation matched 3: 466
Simulation matched 2: 1890
Simulation matched 1: 7243
Average matched 5: 1.1842105263157894
Average matched 4: 3.210526315789474
Average matched 3: 12.263157894736842
Average matched 2: 49.73684210526316
Average matched 1: 190.60526315789474

You can see the variance in distribution. The simulation matched 45 grand prizes in 38 runs

If we crank iterations up to 10000 we get: (edited)

Using bit range of 2
Using cardinality of 5
Using iterations of 10000
Total computed probability space: 1024
Estimated count per iteration of prize 5: 1
Estimated count per iteration of prize 4: 3
Estimated count per iteration of prize 3: 12
Estimated count per iteration of prize 2: 48
Estimated count per iteration of prize 1: 192
Simulation matched 5: 9991
Simulation matched 4: 30013
Simulation matched 3: 119600
Simulation matched 2: 479708
Simulation matched 1: 1921629
Average matched 5: 0.9991
Average matched 4: 3.0013
Average matched 3: 11.96
Average matched 2: 47.9708
Average matched 1: 192.1629

They converge on the expected probabilities.

Conclusion: we need more data!

I don’t get it. Why are multiple wallets winning $2500 on a single draw? I thought only 1 wallet won $2500 per draw (day)?

Prizes are distributed according to a statistical model, so there are bound to be outliers where more than one person wins per day.

I calculated the maximum USDC that can be claimed per draw (and how much is dropped):

  Draw  |  Claimable prizes  |  Dropped prizes  |   Total
--------+--------------------+------------------+----------
   1    |        9140        |       7170       |   16310
   2    |       13470        |       7290       |   20760
   3    |        5580        |       7590       |   13170
   4    |       11210        |       7430       |   18640
   5    |       13500        |       5650       |   19150
   6    |        9940        |       4960       |   14900
   7    |        9290        |       4020       |   13310
   8    |       10990        |       4390       |   15380
   9    |        9890        |       4260       |   14150
   10   |        9600        |       4480       |   14080
   11   |        8730        |       3970       |   12700
   12   |       14670        |       4940       |   19610
   13   |        8300        |       4140       |   12440
   14   |       11540        |       4130       |   15670
   15   |       11370        |       3700       |   15070
   16   |       14280        |       3950       |   18230
   17   |        8960        |       3610       |   12570
   18   |       10450        |       3450       |   13900
   19   |       11450        |       3700       |   15150
   20   |        9990        |       3220       |   13210
   21   |       11960        |       3100       |   15060
   22   |       11460        |       2650       |   14110
   23   |       15040        |       3460       |   18500
   24   |       10320        |       3060       |   13380
   25   |       12230        |       2790       |   15020
   26   |       12810        |       2350       |   15160
   27   |       12770        |       2430       |   15200
   28   |       15750        |       2160       |   17910
   29   |       12020        |       3370       |   15390
   30   |       11940        |       3590       |   15530
   31   |       14680        |       3540       |   18220
   32   |       11730        |       3810       |   15540
   33   |       11700        |       2890       |   14590
   34   |       19860        |       2280       |   22140
   35   |       12630        |       2190       |   14820
   36   |       12970        |       2350       |   15320
   37   |       13610        |       2480       |   16090
   38   |       17070        |       2060       |   19130
   39   |       10580        |       1910       |   12490
--------+--------------------+------------------+----------
 Total  |       463480       |      148520      |   612000

Some interesting conclusions:

  1. In the beginning, most days the total claimable prizes are relatively in line with the prediction of about $14k, but for example day 34 is a pretty massive outlier.
  2. Looking at the dropped prizes value, this decreases significantly the further down we go in the draw list. I’m guessing people are catching up on the wallet splitting technique to maximize APR.
  3. Due to more people splitting over wallets, it seems we are exceeding our projected $14k expenditure on most days.
1 Like

Splitting over wallets to maximise draw eligibility was always going to be the simplest workaround of the ‘whale mitigation’ technique. I’m surprised it wasn’t done straight off the bat when v4 was launched.

I think there comes a point where the app should just be explicit about it. “Deposits over x amount will contribute to the prize but are not eligible for prize draws.”

I know this goes against the whole idea of the whale mitigation in the first place, but it feels like users who just dont know about it are being penalized and taken advantage of by the protocol for their lack of understanding of how it works.

I am inclined to agree. Though maybe some people just don’t want the maintenance hassle too.

I feel like a good mitigation technique of this would be “prize upgradeability”. You can only win in the higher tiers when you’ve won a prize in a lower tier. That would make wallet splitting less efficient. However, I guess that’s not possible to implement within the current protocol?