Current Implementation Methods and Ideas for Rebase Tokens on TON

Introduction

Due to the various applications that Rebase Tokens can achieve, I began to delve into this technology. At the same time, I noticed discussions on implementing Rebase Tokens on TON last year. By reading this TON research, I understood the requirements and challenges of implementing Rebase Tokens on TON.

In the following content, we will discuss the Rebase Token implementation methods mentioned in this article and share my proposed improvements.

Overview of Rebase Token

We won’t go into a detailed introduction of Rebase Tokens, but it can be understood that periodically, the token supply needs to undergo a rebase adjustment. While the number of shares each user holds remains constant, their balance will fluctuate, ensuring the token’s price stays within a certain range. Additionally, this rebase mechanism can be used to generate Yield Bearing Tokens.

For example, let’s consider Lido:

Suppose Bob holds 10 stETH, and the current total ETH in Lido is 1000 ETH, with a total of 1000 shares.

Bob’s share can be calculated using the following formula:

shares[account] = balanceOf(account) * totalShares / totalSupply

For Bob, the calculation would be:

Bob's shares = 10 * 1000 / 1000 = 10 (shares)

Suppose after one day, Lido receives a 10% reward, increasing the total ETH to 1100 ETH. The value of Bob’s 10 shares would also increase accordingly:

10 * 1100 / 1000 = 11 ETH

In this way, automatic compounding is achieved, which is a Yield Bearing Token. Implementing this on Ethereum is relatively straightforward. However, on TON, the implementation complexity increases due to the distinction between Jetton Master and Jetton Wallet contracts.

TEP 130

The following section will discuss the currently proposed TEP 130 on TON. For a detailed introduction to this TEP, you can refer to this article. We will start by introducing the interaction between the frontend and the on-chain contracts, as described in the article, and then discuss the on-chain interaction version proposed by TEP 130.

Frontend Integration

When displaying Pool information on the frontend, get_balances() is used to convert shares into balances. As shown in the figure, 10 rTON actually represents 80 shares (assuming 1 rTON = 8 shares).

However, when interacting with the blockchain, balances need to be converted into shares. Therefore, if Bob wants to exchange 2 rTON for USDT, the frontend will first use get_jetton_shares() to convert 2 rTON into 16 shares, and then transfer these 16 shares to the pool to execute the asset exchange.

From the example in the article, it is clear that directly using shares for on-chain calculations and converting shares and balances on the frontend is not overly complicated. Simply converting the jetton wallet’s balance into shares and adding some functionality can achieve this operation.

Full integration

If Rebase tokens are only interacted with through the frontend, it is clearly insufficient. Therefore, the author proposed an on-chain interaction version for Ston.fi. The specific details are as follows:

The example provided by the author is somewhat confusing because the first example uses shares to run the constant product formula. Theoretically, this approach is feasible. Users transfer USDT to the Router, and the Pool only needs to calculate the received USDT. Using the x * y = k formula, it can similarly determine how many shares should be transferred to the user. It does not seem necessary to call the Jetton Minter to convert shares into balance or balances into shares. The author might be suggesting that if such conversions are needed, it would add an additional 5 transactions.

Therefore, I thought of another example to illustrate the need for converting shares and balances on-chain: when Rebase tokens are used as collateral. In such a situation, it might be necessary to know how much balance the current share represents and then calculate its actual value through an oracle to determine if liquidation is needed.

From the TEP 130 discussion thread and the final implementation of the Rebase Jetton by the author, it is clear that they have removed this method. Thus, the proposed standard does not support on-chain shares → balance or balances → shares operations. The reason for this removal could be that obtaining conversion results through messaging could lead to data expiration issues and high transaction fees. This problem is also mentioned in the discussion thread.

Challenges

Based on the current TEP 130 proposal, Rebase Tokens on TON can only be converted via the frontend and then interact with on-chain protocols through shares. This is clearly insufficient, as there are situations where on-chain operations also need to know the current balances represented by the shares. For example, in the aforementioned case of liquidation in a lending protocol, it is necessary to know the balances represented by the collateralized shares to calculate their value.

Dr. Awesome Doge in the TON Research article also mentioned that the current TEP 130 proposal lacks an on-chain interaction version.

Therefore, it is evident that the current Rebase Token standard has significant room for improvement.

My ideas

From the on-chain solution proposed in TEP 130, we can identify two main issues:

  1. The transaction fees for obtaining conversion results from the Jetton Master whenever shares and balances need to be converted are too high.
  2. There is no clear specification for the validity period of the messages, making it difficult to ensure the accuracy of the Rebase information obtained.

To address these issues, I propose a new solution:

  • Protocols can send a RequestRebaseInfo message to the Jetton Master according to the rebase cycle. For example, Lido performs a rebase every 24 hours, so on TON, a RequestRebaseInfo message can be sent every 24 hours, resulting in minimal transaction fees.
  • The Rebase Jetton Master should include two additional variables besides total_supply and total_shares:
    • rebase_time: The start time of this rebase cycle.
    • rebase_interval: The length of the rebase cycle.
    • The next rebase trigger time would be rebase_time + rebase_interval.
  • Protocols can also check the validity of the Rebase information during user interactions with the contract. If the information is outdated, a RequestRebaseInfo message is sent to the Jetton Master to update the Rebase information.
  • Upon receiving a RequestRebaseInfo message, the Jetton Master will send a ProvideRebaseInfo message to the Protocols, which includes:
    • total_supply: coins
    • total_share: coins
    • expiration: uint32

  • Upon receiving the ProvideRebaseInfo message, the protocols will update the corresponding four variables in the contract.
  • After updating the rebase parameters, protocols can directly perform conversions between shares and balances within the contract based on total_supply and total_share. Users no longer need to send conversion messages to the Jetton Master during interactions.
  • In addition to total_supply and total_share, the Jetton Master will also provide expiration. The protocol’s contract can use now() to determine if the current rebase information is still valid.

By using this method, the issue of having to send messages to the Jetton Master each time for shares and balances conversion confirmation during on-chain interactions can be resolved. If the rebase cycle is once a day, the protocols only need to pay the fee once on behalf of the users. Consequently, each user can save the 5 transactions required by TEP 130. Assuming there are 10 transactions related to the Rebase Token in a day, this would save 5 * 10 = 50 transactions.

Regarding issue 2, obtaining rebase information from the Jetton Master may face expiration issues, which is why the contract cannot call the get_method on the wallet. However, through the expiration variable, the correctness of the rebase information can be confirmed. Additionally, rebase information is updated periodically, unlike wallet balances that may change at any time. Therefore, this method can provide reliable information.

Conclusion

Based on the characteristics of Rebase Tokens, an expiration variable has been added to prevent the use of outdated rebase information. The total_supply and total_shares parameters are updated by sending a RequestRebaseInfo message from the protocols and receiving the ProvideRebaseInfo message. Given the design of the rebase mechanism, signaling according to the rebase cycle should not impose a significant burden on the protocols, yet it can save users substantial fees.

This article does not cover how to update the total_supply and total_share in the Jetton Master, as this aspect is closely related to the design of the Rebase Token itself. It might involve updating parameters via JettonNotification and then updating total_supply and total_share after the rebase cycle completes. This discussion will be reserved for a future article. My proof of concept implementation can be found at this link. I hope developers on TON can join the discussion on how to implement Rebase Tokens and make them a reality on TON.

3 Likes

looks nice for me!!!