Skip to content

Commit

Permalink
GSW-1069 fix: one click staking for native ugnot coin (wrapping issue)
Browse files Browse the repository at this point in the history
  • Loading branch information
r3v4s committed May 15, 2024
1 parent 22ace36 commit db822b0
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 92 deletions.
11 changes: 11 additions & 0 deletions staker/_TEST_/_TEST_0_INIT_VARIABLE_AND_HELPER_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ var (
)

/* HELPER */
func ugnotBalanceOf(addr std.Address) uint64 {
testBanker := std.GetBanker(std.BankerTypeRealmIssue)

coins := testBanker.GetCoins(addr)
if len(coins) == 0 {
return 0
}

return uint64(testBanker.GetCoins(addr)[0].Amount)
}

func shouldEQ(t *testing.T, got, expected interface{}) {
if got != expected {
t.Errorf("got %v, expected %v", got, expected)
Expand Down
92 changes: 0 additions & 92 deletions staker/_TEST_/_TEST_staker_mint_and_stake_test.gn

This file was deleted.

156 changes: 156 additions & 0 deletions staker/_TEST_/_TEST_staker_mint_and_stake_test.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package staker

import (
"std"
"testing"

pl "gno.land/r/demo/pool"

"gno.land/r/demo/bar"
"gno.land/r/demo/gns"
"gno.land/r/demo/qux"
"gno.land/r/demo/wugnot"

"gno.land/r/demo/gnoswap/consts"
)

func init() {
// init pool tiers
// tier 1
poolTiers["gno.land/r/demo/bar:gno.land/r/demo/qux:500"] = 1 // DEV

// tier 2
poolTiers["GNS/USDT_500"] = 2
poolTiers["ATOM/GNS_500"] = 2

// tier 3
poolTiers["ATOM/GNOT_500"] = 3
poolTiers["ATOM/USDT_500"] = 3
poolTiers["ATOM/WETH_500"] = 3
}

func TestPoolInitCreatePool(t *testing.T) {
std.TestSetPrevAddr(gsa)

gns.Approve(a2u(consts.POOL_ADDR), consts.POOL_CREATION_FEE)
std.TestSkipHeights(1)

pl.CreatePool(barPath, quxPath, 500, "130621891405341611593710811006") // tick 10_000 ≈ x2.7
// --- event: {GNOSWAP gno.land/r/demo/pool CreatePool [{m_origCaller g13f63ua8uhmuf9mgc0x8zfz04yrsaqh7j78vcgq} {m_prevRealm } {p_poolPath gno.land/r/demo/bar:gno.land/r/demo/qux:500}]}

pl.CreatePool(consts.GNOT, consts.GNS_PATH, 500, "130621891405341611593710811006") // tick 10_000 ≈ x2.7
// --- event: {GNOSWAP gno.land/r/demo/pool CreatePool [{m_origCaller g13f63ua8uhmuf9mgc0x8zfz04yrsaqh7j78vcgq} {m_prevRealm } {p_poolPath gno.land/r/demo/gns:gno.land/r/demo/wugnot:500}]}

std.TestSkipHeights(1)
}

func TestMintAndStakeGRC20Pair(t *testing.T) {
std.TestSetPrevAddr(gsa)
bar.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX)
qux.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX)
std.TestSkipHeights(2)

lpTokenId, liquidity, amount0, amount1, poolPath := MintAndStake(
barPath, // token0
quxPath, // token1
fee500, // fee
int32(9000), // tickLower
int32(11000), // tickUpper
"1000", // amount0Desired
"1000", // amount1Desired
"1", // amount0Min
"1", // amount1Min
max_timeout,
)
// event: {GNOSWAP gno.land/r/demo/position Mint [{m_origCaller g13f63ua8uhmuf9mgc0x8zfz04yrsaqh7j78vcgq} {m_prevRealm gno.land/r/demo/staker} {p_poolPath gno.land/r/demo/bar:gno.land/r/demo/qux:500} {p_tickLower 9000} {p_tickUpper 11000} {tokenId 1} {liquidity 12437} {amount0 368} {amount1 1000}]}
// event: {GNOSWAP gno.land/r/demo/staker StakeToken [{p_tokenId 1} {poolPath gno.land/r/demo/bar:gno.land/r/demo/qux:500} {amount0 368} {amount1 1000}]}
shouldEQ(t, lpTokenId, uint64(1))

std.TestSkipHeights(1)
}

func TestMintAndStakeNative(t *testing.T) {
std.TestSetPrevAddr(gsa)
gns.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX)
wugnot.Approve(a2u(consts.POOL_ADDR), consts.UINT64_MAX)
wugnot.Approve(a2u(consts.POSITION_ADDR), consts.UINT64_MAX)
std.TestSkipHeights(2)

// prepare 100005ugnot (5 for refund test)
testBanker := std.GetBanker(std.BankerTypeRealmIssue)
testBanker.IssueCoin(gsa, "ugnot", 100005)

// simulate transfer & decrase
gsaNativeBalance := ugnotBalanceOf(gsa)
shouldEQ(t, gsaNativeBalance, 100005)

std.TestSetOrigSend(std.Coins{{"ugnot", 100005}}, nil)
testBanker.RemoveCoin(std.GetOrigCaller(), "ugnot", -100005)

gsaNativeBalance = ugnotBalanceOf(gsa)
shouldEQ(t, gsaNativeBalance, 0)

gsaOldWugnotBalance := wugnot.BalanceOf(a2u(gsa))
shouldEQ(t, gsaOldWugnotBalance, 0)

lpTokenId, liquidity, amount0, amount1, poolPath := MintAndStake(
consts.GNOT, // token0
consts.GNS_PATH, // token1
fee500, // fee
int32(9000), // tickLower
int32(11000), // tickUpper
"100000", // amount0Desired
"100000", // amount1Desired
"1", // amount0Min
"1", // amount1Min
max_timeout,
)
// event: {GNOSWAP gno.land/r/demo/position Mint [{m_origCaller g13f63ua8uhmuf9mgc0x8zfz04yrsaqh7j78vcgq} {m_prevRealm gno.land/r/demo/staker} {p_poolPath gno.land/r/demo/gns:gno.land/r/demo/wugnot:500} {p_tickLower -11000} {p_tickUpper -9000} {tokenId 2} {liquidity 1243732} {amount0 100000} {amount1 36790}]}
// event: {GNOSWAP gno.land/r/demo/staker StakeToken [{p_tokenId 2} {poolPath gno.land/r/demo/gns:gno.land/r/demo/wugnot:500} {amount0 100000} {amount1 36790}]}

shouldEQ(t, lpTokenId, uint64(2))
std.TestSkipHeights(1)

// SPEND ALL WUGNOT
newOldWugnotBalance := wugnot.BalanceOf(a2u(gsa))
shouldEQ(t, gsaOldWugnotBalance, 0)

gsaNativeBalance = ugnotBalanceOf(gsa)
shouldEQ(t, gsaNativeBalance, 63215)
// 1. 100005 ugnot sent
// 2. 100005 ugnot wrapped to wugnot
// 3. 36790 wugnot spent to mint (amount1)
// 4. refund 100005 - 36790 = 63215

}

/*
func TestPositionCollectFee(t *testing.T) {
std.TestSetPrevAddr(gsa)
pn.CollectFee(1) // lpTokenId
std.TestSkipHeights(1)
}

func TestCollectReward(t *testing.T) {
// internal reward distribution
std.TestSetPrevAddr(consts.INTERNAL_REWARD_ACCOUNT)
gns.Approve(a2u(consts.STAKER_ADDR), consts.UINT64_MAX)

std.TestSetPrevAddr(gsa)
CollectReward(1) // lpTokenId
std.TestSkipHeights(1)
}

func TestUnstakeToken(t *testing.T) {
ownerOfLp1 := gnft.OwnerOf(tid(1))
shouldEQ(t, ownerOfLp1, a2u(consts.STAKER_ADDR))

std.TestSetPrevAddr(gsa)
UnstakeToken(1) // lpTokenId
std.TestSkipHeights(1)

ownerOfLp1 = gnft.OwnerOf(tid(1))
shouldEQ(t, ownerOfLp1, a2u(gsa))
}

*/
21 changes: 21 additions & 0 deletions staker/mint_stake.gno
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package staker

import (
"std"

pn "gno.land/r/demo/position"

"gno.land/p/demo/ufmt"

"gno.land/r/demo/gnoswap/consts"
)

Expand All @@ -20,6 +24,23 @@ func MintAndStake(
amount1Min string, // *u256.Uint
deadline int64,
) (uint64, string, string, string, string) { // tokenId, liquidity, amount0, amount1, poolPath ( *u256.Uint x3)

// if one click native
if token0 == consts.GNOT || token1 == consts.GNOT {
// check sent ugnot
sent := std.GetOrigSend()
ugnotSent := uint64(sent.AmountOf("ugnot"))

// not enough ugnot sent
if ugnotSent < consts.UGNOT_MINT_DEPOSIT_TO_WRAP {
panic(ufmt.Sprintf("[STAKER] mint_stake.gno__MintAndStake() || too less(%d) ugnot sent (minimum:%d)", ugnotSent, consts.UGNOT_MINT_DEPOSIT_TO_WRAP))
}

// send it over to position to wrap
banker := std.GetBanker(std.BankerTypeRealmSend)
banker.SendCoins(consts.STAKER_ADDR, consts.POSITION_ADDR, std.Coins{{"ugnot", int64(ugnotSent)}})
}

tokenId, liquidity, amount0, amount1 := pn.Mint(
token0,
token1,
Expand Down
10 changes: 10 additions & 0 deletions staker/utils.gno
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,16 @@ func uint64ToStr(i uint64) string {
return strconv.FormatInt(int64(i), 10)
}

func strToUint64(s string) uint64 {
i, err := strconv.Atoi(s)

if err != nil {
panic(ufmt.Sprintf("[STAKER] utils.gno__strToUint64() || failed to convert string(%s) to uint64", s))
}

return uint64(i)
}

func boolToStr(b bool) string {
if b {
return "true"
Expand Down

0 comments on commit db822b0

Please sign in to comment.