Say you are tasked with coding a smart contract with the following features:

  1. Users can deposit token A and receive liquidity shares in return.
  2. The contract starts selling token A for token B depending on some arbitrary rules. Every time there is a trade, all users receive a pro rata share of token B.
  3. Users can redeem their liquidity shares in exchange for both token A and token B.
  4. Other users can deposit token A and receive liquidity shares, but they are not eligible to withdraw token B earned by previous users.

In an ideal world, the protocol would do a multisender.app-style distribution of token B, but this is impossible because of block gas limits. Hence I must issue shares and let users retroactively claim their rewards.

Is there a framework or a protocol that I could use to implement this?

I looked at Set Protocol, but their Rebalancing Sets are out of scope for my use case - they depend on auctions to rebalance the composition of the Set.

I also looked at Balancer, which gets close, but their pooled model breaks feature no. 4 from above. Users who deposit late should not be eligible to withdraw tokens B that had been earned by previous depositors.

Is this smart contract design even possible? I personally can't see a way for the contract to selectively distribute token A and token B to users, on a pro-rata basis, while taking into account the times at which users deposited token A.

  • do you have an example of this finished product on github? – user1899588 Apr 13 at 18:39


I eventually found a solution, but it involves relying on an oracle for an USD price feed:

sMinted = sStarting * (aDepositedUSD / (aStartingUSD + bStartingUSD))


  • sMinted: the number of shares to mint
  • sStarting: the number of already existing shares
  • aDepositedUSD: the USD value of the amount of A tokens deposited
  • aStartingUSD: the USD value of the already existing amount of A tokens in the contract
  • bStartingUSD: the USD value of the already existing amount of B tokens in the contract


The logic is that we need a common denominator between the two assets, lest we lose track of "retroactive proportionality". The value in USD of each token serves this purpose.

Of course, there are exceptions: What if the existing amount of shares is zero? And what happens if there are no A and no B tokens in the contract? A proper implementation would have to carry out several checks before applying the formula above.

Interestingly, Uniswap solves a similar problem with their constant product formula (x * y = k), but I cannot apply that here. I didn't want to morph the contract into a DEX - the purpose was simply to bundle two assets and pro-rate their ownership to everybody who deposits money.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.