Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TEP: Wrapped TON standard and implementation #102

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

markokhman
Copy link

Publishing this as a draft. The work is in process and will be lot's of updates in upcoming days.
Please leave your comments.

@markokhman
Copy link
Author

Hello guys, could you please review this one?

@Naltox
Copy link

Naltox commented Dec 22, 2022

LGTM

@dariotarantini
Copy link

dariotarantini commented Jan 11, 2023

Hello colleagues!

At ston.fi we offer to update WTON standard to actually transfers TON between wallets when transferring WTON. This approach avoid custom minting calls and works without the need of custom code in any protocol to support it.

Concepts

Unlike current WTON implementations, we propose to not rely on wrapping/unwrapping logic. In this standard, minting WTON doesn’t touch central jetton contract, minting occurs when the user sends TON to a his WTON wallet.
The amount of gas transferred betwen WTON Jetton Wallets is actually the amount of TON sent + some gas for wallet processing. In this way, each wallet will actually store native TON in each wallet without the need of a central autorithy. The jetton transfer amount should be paid from both wallet balance and incoming message gas, prioritizing the WTON wallet balance.
Eg: I want to transfer 10 WTON, my message carry 3 TON and my WTON wallet has 8 TON in it, after the transfer the amount of gas left should be 1 WTON and WTON Wallet Balance 0.
To "withdraw" TON from your own WTON wallet, you call either call a standard burn or can be enabled by default in internal jetton wallet configuration. In this way, you can specify a condition to trigger an auto-withdraw function described in the following document. The outgoing withdraw message should be paid from WTON Wallet TON balance.

Specification

The following opcodes describes only the non-standard core logic needed in the implementation.

// minter
// deploy_wallet: deploy a new wallet contract for a specified to_address address. Can be called by anyone.
// required because there is no central minting. Outgoing message should have an empty body
deploy_wallet#0x656ff420 query_id:uint64 destination:MsgAddress = InternalMsgBody;

// wallet 
// change_mode: changes jettonwallet behavior
// mode=0 means no autounwrap, mode=1 means autounwrap if condition is met (balance > min_balance)
change_mode#0x3508d282 query_id:uint64 mode:Bool min_balance:(VarUInteger 16) = InternalMsgBody;

Pros:

  • Lower gas consumption for WTON transfers with auto wrap/unwrap
  • Simplier message construction

Cons:

  • Impossible to determine total_supply in WTON minter

@EmelyanenkoK
Copy link
Member

EmelyanenkoK commented Jan 11, 2023

I want to emphasize some aspects of @dariotarantini proposal:

  1. each wTON wallet works as minter/burner itself - no need for additional interaction with minter which means one or even two transaction shorter paths
  2. we can reformulate this scheme in the following terms: in original proposal when we want to send TONs we actually send IOU jettons which is redeemable as TON, but in scheme proposed by Dario we send TON themselves but disguised as jetton transfer for compatibility.

It is important to stress that we should be quite cautious about fee-managing to make these wTON fully Jetton compatible. I propose to ensure that amount of TON sent with each inter-wallet transfer to be equal to amount of TON which would be sent in the case it is standard jetton + amount of jettons in message. Anyway, wTON-wallet of the receiver should not trust amount of jetton in incoming internal transfer, instead it should calculate amount that was really sent (TON amount minus all forward amounts/fees).

Another important point is way to unwrap. Dario propose to make auto-unwrap option on jetton wallet, while there is also an option that wallet will peek in payload and if there something very special (that will not intersects with standard transfer) it will understand that it should not send TON as jettons to the other wTON wallet, but unwrap it directly to destination. I used 23bit long prime number as that special payload (since it is expected that for any usual purpose there will be 32bit long op)
My very draft (not tested at all !!!) implementation is https://github.com/EmelyanenkoK/wTON

@dariotarantini
Copy link

while there is also an option that wallet will peek in payload and if there something very special (that will not intersects with standard transfer) it will understand that it should not send TON as jettons to the other wTON wallet, but unwrap it directly to destination.

This assume that, if you are interacting with another contract, the receiver contract will forward the payload in the next transaction. Some may not; that's why I proposed an alternative on user-side, similar to status in stablecoin contract.

@EmelyanenkoK
Copy link
Member

EmelyanenkoK commented Jan 11, 2023

This assume that, if you are interacting with another contract, the receiver contract will forward the payload in the next transaction. Some may not; that's why I proposed an alternative on user-side, similar to status in stablecoin contract.

Not forcing my option, just emphasize that my implementation differs from your suggestion.
By the way, why not have both?

Also in my implementation reading of special op and thus "unwrapping" happens on the receiver jetton-wallet. Now I understand that it is excessive: sender wallet may peek into payload as well and unwrap and send TONs to destination itself (minus yet another tx in chain).

@markokhman
Copy link
Author

Hey @dariotarantini @EmelyanenkoK, thank you very much for this suggestion!
Very interesting idea with shifting the mint/burn logic into the WTON wallet, eliminating centralised minter.
I will have a deeper look and play around with your implementation draft @EmelyanenkoK

Thank you very much!

@dariotarantini
Copy link

By the way, why not have both?

Correct me if I'm wrong, but in your proposal the receiver has no way to refuse an auto-unwrap payment, right?
In the case of the receiver is a DEX, the sender may set the special op and the DEX contract will receive native TON. But the DEX has no way to handle correctly this, leading to inconsistency where the payment has been done, but the DEX is not supposed to manually send a fixed amount of TON.

@EmelyanenkoK
Copy link
Member

EmelyanenkoK commented Jan 11, 2023

@markokhman
I just want to say that I'm not going to polish my implementation till release quality. It was done to check the idea, I hope that if you embrace the whole concept, team behind this TEP will make final implementation (whether based on mine or from scratch).

@dariotarantini
I have the following idea in my head:
by default wTON will not be unwrapped.
Sender may force "unwrap" by putting magic number into payload of transfer request to his own wallet. In this case TONs will be unwrapped on sender wallet and sent directly to the destination (instead of sending wTONs to destination wallet).
If Sender doesn't enforce unwrap, wTON will came to destination wallet. This wallet can have mode as you suggested and unwrap (or not) all incoming wTONs as owner desires.

That way, I believe we get benefits from both approaches and no downsides. Indeed ability sender to forcefully unwrap wTONs does not make system more unpredictable: sender always have privilege to shot his leg (and for instance send TON directly instead of through wTON system). But this combined scheme allows both sender auto-unwrap tokens and receiver auto-unwrap token if wanted.

@markokhman
Copy link
Author

@EmelyanenkoK I understand, sure

We'll first make sure every interested party took their time to view and comment, the will do further code polishing on our end if needed.

Thank you very much!

@NickNekilov
Copy link

@dariotarantini @EmelyanenkoK
I have read in detail both an idea description and a draft solution.
I've found it much more elegant and effient comparing to a previous implementation.
Also I like the idea of having a "magic flag" for auto-unwrapping.
I've double-checks all use-cases of DEX and it covers all of them.
What are the next steps?

@markokhman
Copy link
Author

@NickNekilov
as @EmelyanenkoK have mentioned, we should make sure the solution is ready for production, meaning writing tests and ensuring there is no drawbacks.

I believe it would be great to have some tests that are actually demonstrating core usecases and maybe also those DEX, if that's the case

@EmelyanenkoK
Copy link
Member

I guess next step is explicit listing of additional functionality such as

  • external transfer (it is when you send TON directly to wton-wallet of receiver to wrap it in-place without additional tx)
  • details of auto-unwrap
  • exact mechanics of the the fees with examples: interaction of amount, forward_ton_amount and gas-consumption/min-storage fees

Get consensus from interested parties and then reference implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants