gnoswap-labs / gno

Gno language & gno.land chain
https://gno.land/
Other
0 stars 0 forks source link

Gno Core Issue Tracker #7

Open dongwon8247 opened 1 year ago

dongwon8247 commented 1 year ago

Description

This issue tracker contains a list of things that Onbloc and Gnoswap need from the Gnoland Core side. Its purpose is to centralize all the issues in one place for better coordination and management.

Major Features

Not required for Mainnet

Minor Bugs

r3v4s commented 1 year ago

6. Support skipping timestamp in test cases. #569 - Usecase: testing logics that depends on how much time have been passed - Depends on: nothing at this moment

Merged with the main comment for better visibility

r3v4s commented 11 months ago

7. PrevRealm - related: https://github.com/gnolang/gno/pull/896 - issue: result is different from gno test and gnoland & gnokey - can be by pass with, https://github.com/gnolang/gno/pull/891

Merged with the main comment for better visibility

r3v4s commented 8 months ago

8. Upgradable Contract - proxy pattern - storage migration

Merged with the main comment for better visibility

r3v4s commented 8 months ago

Details of the Contract Interaction Issue

1. When importing token realms

Current: Import tokens manually (https://github.com/gnoswap-labs/gnoswap/blob/d624686b1d3af19313ab407ac3d626ec87e6c68d/pool/pool_manager.gno#L7-L8)

import (
  "std"
  "strconv"

  foo "gno.land/r/foo" // Import token0 manually
  bar "gno.land/r/bar" // Import token1 manually

  "gno.land/p/demo/ufmt"
)

Ideally with contract interaction functionality:

no need to import each token

2. When creating a pool

Current: Set token0 as foo, and token1 as bar manually, which are imported from above (https://github.com/gnoswap-labs/gnoswap/blob/d624686b1d3af19313ab407ac3d626ec87e6c68d/pool/pool_manager.gno#L119-L135)

return &Pool{
  token0:               foo.GetGRC20(),
  token1:               bar.GetGRC20(),
  balances:             balances,
  fee:                  fee,
  tickSpacing:          tickSpacing,
  maxLiquidityPerTick:  maxLiquidityPerTick,
  slot0:                slot0,
  feeGrowthGlobal0X128: 0,
  feeGrowthGlobal1X128: 0,
  protocolFees:         protocolFees,
  liquidity:            0,
  ticks:                Ticks{},
  tickBitmaps:          TickBitmaps{},
  positions:            Positions{},
}

Ideally with contract interaction functionality:

return &Pool{
  token0:               std.Call("gno.land/r/foo", GetGRC20) // Example with std.Call
  token1:               std.Call("gno.land/r/bar", GetGRC20) // Example with std.Call
  balances:             balances,
  fee:                  fee,
  tickSpacing:          tickSpacing,
  maxLiquidityPerTick:  maxLiquidityPerTick,
  slot0:                slot0,
  feeGrowthGlobal0X128: 0,
  feeGrowthGlobal1X128: 0,
  protocolFees:         protocolFees,
  liquidity:            0,
  ticks:                Ticks{},
  tickBitmaps:          TickBitmaps{},
  positions:            Positions{},
}

3. When swapping tokens

Current: Same as creating a pool, we have to set token0 as foo, and token1 as bar manually, which are imported from above (swap token0 & swap token1)

if amount1 < 0 {
  // handle token1
  bar.Transfer(a2u(recipient), uint64(-1*amount1))
}

// handle token0
from := a2u(GetOrigCaller()) // token should be transferred from actual user(GetOrigCaller), not from the realm(PrevRealm)
to := a2u(GetOrigPkgAddr())

foo.TransferFrom(from, to, uint64(amount0))

Ideally with contract interaction functionality:

if amount1 < 0 {
  // handle token1
  pool.token1.Transfer(a2u(recipient), uint64(-1*amount1))
}

// handle token0
from := a2u(GetOrigCaller()) // token should be transferred from actual user(GetOrigCaller), not from the realm(PrevRealm)
to := a2u(GetOrigPkgAddr())

pool.token0.TransferFrom(from, to, uint64(amount0))

Problems

What Inter-contract Functionality Unlocks

Moving Forward

moul commented 8 months ago

For contract-contract interaction without modifying the gnovm (without adding std.Call or IBC), I propose the following plans:

Option 1: Create a main contract, let's call it r/gnoswap/hub, which includes a RegisterSwapper function. This function can be called from new contracts that you add later, such as r/gnoswap/swapper-foo20. During the init() phase, the new contracts can register themselves on the hub like this: hub.RegisterSwapper("foo20", mySwapper), where mySwapper is a global variable implementing the hub.Swapper interface. Subsequently, the hub can utilize its local registry of tokens and call swapper methods without needing to import them.

Edit: https://github.com/gnolang/gno/pull/1262

Option 2: Consider code generation to register new contracts for each token or potentially for each token-pair. Your frontend would need to be aware of which contract to call depending on the scenario. These contracts could import a hub/keeper to attempt centralizing the GRC20s in a semi-permissionless manner. The goal of the hub/keeper is to provide a central address for both native tokens and GRC20s (you can use the Approve method to delegate GRC20 management to your keeper).