openzeppelin-contracts icon indicating copy to clipboard operation
openzeppelin-contracts copied to clipboard

Reward splitting proportional to token holdings

Open SharjeelSafdar opened this issue 4 years ago • 5 comments

🧐 Motivation

A payment splitter that receives and releases payments in the form of an ERC20 token. While it uses a second ERC20 token to calculate the shares of shareholders instead of fixed shares at construction time.

📝 Details

Currently, there is a payment splitter for ETH here in Openzeppelin. There are many people who have implemented an ERC20 payment splitter to split a payment among shareholders in the form of an ERC20 token by modifying OpenZeppelin's payment splitter for ETH. An example is AirSwap. But the list of shareholders and their shares are fixed at construction time.

This ERC20 payment splitter uses two ERC20 tokens. One token is the Payment Token which is used for receiving and splitting payments. The other is the Shares Token. Shares token (ERC20Shares) is also an ERC20 token with some extended functionality. It snapshots its holders' balances and the total supply of the token when they change using ERC20Snapshot. The ERC20 Payment Splitter uses these balance snapshots and the total supply snapshots as the shares held by addresses and the total shares respectively at different points of time. Whenever a payment is received, each user gets a part of the payment in proportion to her/his balance of Shares Token at that point in time. However, the user doesn't receive the payment automatically. The user can get all the accumulated pending payments anytime.

Benefits

  1. There is no need to add or remove shareholders.
  2. The shareholders can exchange their shares at a DEX.
  3. The same token can be used for both shareholding in a payment splitter and governance on a DAO.

Demonstration

I have created a DApp for demonstration purposes. You must be on Ropsten network to use it. The code for the contracts is here.

I am opening this issue to discuss if this ERC20PaymentSplitter is worth adding to this repo. Please, tell me if you find any problem or there is any room for improvement 😊.

SharjeelSafdar avatar Oct 03 '21 17:10 SharjeelSafdar

Hello @SharjeelSafdar

I did prototype something like this a few weeks ago.

The main difficulty we faces was that we wanted transfers of share tokens to not affect past rewards. This was achieved using release rebalancing during token transfer. I don't see your code doing that, which makes me wonder how your code would behave in such a situation. The downside of this rebalancing approach is that it makes the splitter work with a single asset (ETH or one ERC20, ...) but not with multiple assets like your just-released ERC20 splitter. (from what I can see, your contract has a _paymentToken so that is similar)

We paused the work on this tokenized-splitter because we didn't have any specific user demands. I would love to know more about your usecase.

Amxx avatar Oct 04 '21 07:10 Amxx

Hi @Amxx,

In my use case, I want an ERC20 token that can be used for governance on a DAO. Also, I want to share the revenues among the holders of that governance token. In my case, I want to receive and release payments in the form of a single ERC20 token, specifically DAI.

My ERC20Shares token uses ERC20Snapshot under the hood to take snapshots of totalSupply and account balances. ERC20PaymentSplitter calls _snapshot method of ERC20Snapshot whenever it receives or releases a payment.

My ERC20PaymentSplitter currently supports only a single token for receiving and releasing payments. The other _sharesToken is just for tracking shares of accounts. However, it may be extended to support multiple payment tokens. But I think it would be better to create two contracts. One that supports a single payment token and another that can support multiple payment tokens.

SharjeelSafdar avatar Oct 06 '21 09:10 SharjeelSafdar

@SharjeelSafdar We're interested in this sort of contract, but we feel we need more input from different real world use cases in order to understand what the best solution could look like.

The solution you propose here requires using ERC20Snapshot, and I'm not sure that's sufficiently useful. We're currently focusing our efforts more on ERC20Votes, which is more optimized and checkpoints are opt-in. On the other hand, because of the opt-in nature I don't think it's possible currently to implement proportional rewards for an ERC20Votes contract.

So the particular code you shared here is interesting but I don't think it meets the requirements for generality and usefulness that we expect in order to merge. But again, this is a problem space we're interested in and are looking for other ideas so please feel free to keep exploring and sharing!

frangio avatar Nov 04 '21 23:11 frangio

I consider such ERC20 PaymentSplitter, which can make ERC20 token payments by using ERC20Snapshot mechanism for shares extraction, useful. Especially extended with multiple payment tokens support. In form of any payment ERC20 token arg for receivePayment method (in @SharjeelSafdar contract). And also with support for one payment token its useful too. As example for building contracts for splitting stablecoins, weth payments and the like.

I very like ERC20Votes, but consider that ERC20Snapshot can be useful too. As example for dividend tokens or other token type which dont need voting support.

a17 avatar Dec 05 '21 03:12 a17

I made a contract like this which doesn't use ERC20Snapshot so is gas-efficient upon transfer. It has a couple tradeoffs which do not matter for my, or likely many other, use cases:

  • When somebody transfers shares and is still owed dividends, the contract pays out all owed dividends to them
  • Takes only one type of payment token (ability to take any token may be tough to add)
  • Has a fixed supply (this should be easily modifiable; I just didn't do it. Be careful with the _beforeTokenTransfer() function if burning is allowed as 0 token supply will cause a divide by zero error)

I've tested it but don't guarantee anything (especially as I don't have much experience with automated testing); please don't trust it with a lot of money without doing more diligence!

nanaknihal avatar Dec 26 '21 21:12 nanaknihal