osmosis-labs / isotonic

Smart Contracts for the Lendex Protocol
MIT License
1 stars 0 forks source link

Allow LTokens to be converted to native tokens #70

Open ethanfrey opened 2 years ago

ethanfrey commented 2 years ago

Requires https://github.com/CosmWasm/wasmd/issues/671 or equivalent in Osmosis (done in osmo-bindings)

Requirements

Osmosis AMMs can only trade native tokens. Maybe someone wants to trade their LTokens on an AMM. One approach is to allow a contract to emit a custom native token. This requires that said token is no longer on the cw20 balance (and no longer able to be used as collateral), but can be redeemed later for the equivalent cw20 token 1:1 allowing them to accumulate interest while trading it.

This needs some UX design work to clarify raw balance and display balance, but we can make a working version easily and refine UX when we have a real frontend.

Implementation

LTokens are stored in storage as shares and maintain a multiplier. When interest is accrued, the multiplier is increased. Each time we move from eg ATOM to lATOM or lATOM to ATOM, we use the multiplier. If the multiplier is 1.2, and I deposit 12 ATOM, I get 10 lATOM in storage. Later, if the multiplier is 1.4, I can withdraw all 10 lATOM to get 14 ATOMs. Thus, if we trade these underlying "shares" as native tokens, they will implicitly accumulate all interest while they are as native tokens. The value of these "native shares" should just slowly increase.

CW20 to Native: User A can make a call to ConvertToNative{ shares }. The contract checks that user A has at least shares in the raw storage, and that can_transfer(shares) is true (meaning these shares are not required as collateral for other debt). If these checks pass, the contract will move shares in BALANCES from user A account to env.contract.address account. It will then use OsmosisMsg::MintTokens with amount: shares, recipient: user A, sub_denom: "shares". Once these are converted to native tokens, they can be freely transferred to any address.

Native to CW20: Sometime later, user B gets some of these native tokens from user A and wants to use them in isotonic. User B can call Redeem{ } and send coins(shares, custom_denom) as funds. The contract can use FullDenom to check that custom_denomis indeed the denom it issued and fail if it is not. If it is the proper denom, it will then move shares in BALANCES from env.contract.address to user B. It will also burn all the received native tokens. User B can then use these L-Tokens as collateral or withdraw them, remembering it has accumulated the interest via the multiplier.

BirgitPohl commented 2 years ago

Blocked because: We don't yet have cosmos integration point to osmosis blockchain. Help from @ethanfrey We would like to know the status. Any updates?

ethanfrey commented 2 years ago

Yes, this needs custom bindings. I have not started on them, was waiting for Mauro to be available and now getting tied up with wasmd. But I will try to get something by Wednesday

ks-victor commented 2 years ago

@ethanfrey In my mind this would be an obvious version 2 thing. What do you think?

ethanfrey commented 2 years ago

i think they want this for v1 so ltokens can be traded on an amm.

it is not very hard with the new bindings we are developing. I can do a tech meeting with the team on this

ks-victor commented 2 years ago

@ethanfrey l-tokens are the ones I deposited, so buy letting people swap l-tokens for Juno, I am buying and selling collaterals basically, right? Is there a solution to tracking the rewards tokens distributed to those l-token holders we don't know?

ks-victor commented 2 years ago

regarding v1 vs v2 unless they explicitly want it or there are other reasons, I would rather keep it for v2 so that we have a nice v2 that we can offer them - but we can discuss this.

ethanfrey commented 2 years ago

they explicitly asked for this.

you can discuss with sunny. we added support in the wasm bindings.

basically you track shares of ltokens into native tokens, and those aren't credited to any account. when you redeem them, they are credited to an account and automatically get the multiplier (interest).

I can explain more in a dev/tech session

uint commented 2 years ago

@ks-victor I think we can get started on this even before talking with Sunny. Ethan described this well. This doesn't look like a situation where "there are many ways to skin the cat" and where Osmosis might require something vastly different.

uint commented 2 years ago

Note: token contract keeps track of the amount "currently nativified" and exposes internal endpoints only market contract can use. Market contract has the endpoints for UI that also perform the extra checks.

ethanfrey commented 2 years ago

Dev just requested that we not use the Go intregration I did.

For native coin minting, we were thinking of making another module golang side (we’ve been calling it “token factory” for doing this, and storing more metadata chain side) Would it be possible for us to comment out the mint tokens logic, for the first version, and for the next version we have token factory on-chain and can make bindings against that?