Hi, I’m looking for a proven implementation of an ERC20 with the capability to distribute dividends to the token holders even if the total supply changes frequently by minting. I have found many implementations based on Nick Johnson’s 2017 algorithm. Such algorithm, although very cleaver, breaks when the total supply changes. This failure is hard to notice if the percentage change of the total supply is small, but it becomes very evident with large changes of the total supply. Has anyone solved that problem?
Welcome to the forum @nunezlt. In Nick Johnson’s post about this there is a section about changing totalSupply. I’m assuming you’ve seen that already? He talks about rounding errors but I don’t think they will be significant.
I don’t think this approach is a good idea in today’s world, though, because it will add a high cost to every token transfer (although you should measure it!). I feel it would be better to manage dividends separately.
A possible approach is to use
ERC20Snapshot. When there are dividends to distribute, you can take a snapshot of balances and total supply and store the snapshot id and dividend total, which token holders can later come and claim proportionally to their balance at the time. If these snapshots were to happen often, it would incur a high cost on transfers as well, and in that case another approach should be preferred.
Wow Fragio!, thank you, that is an awesome solution. I was working on a different but similar concept of the snapshot, unaware of the existence of that contract. The snapshot contract is a much better solution. I do expect to issue a few hundred Rewards or Dividends per month. Do you see a big cost problem on that? Do you know of an even better solution?
Best regards to you and the OpenZeppelin Team, you are doing an amazing job.
A few hundred per month sounds like it would result in additional cost for almost every transfer. ERC20Snapshot is better when snapshots are low frequency. But this is something you should measure and check if the cost is acceptable to you. I recommend
eth-gas-reporter if you’re not familiar with it already.
There are a number of optimizations you can do on
ERC20Snapshot depending on your specific scenario. The idea is basically to reduce the number of different storage slots you access, so packing multiple values into the same slot. The new
ERC20Votes (not yet released) is similar and implements one of these optimizations, by packing this struct in one slot:
But this places a cap on your total supply (technically, only on your balances), which must fit in 224 bits. If you can establish an even lower cap, you could pack two or more of these checkpoints/snapshots in one slot, and this would optimize the average cost of transfers (this is what COMP does). Note that
ERC20Votes as is now is not useful to you because people have to opt in to these checkpoints, and some of the dividends would never be distributed.
There may be other things you could do.
Of course this is all if you care about gas costs…