mint_stake.gno
2.52 Kb ยท 99 lines
1package v1
2
3import (
4 "chain"
5 "chain/banker"
6 "chain/runtime"
7
8 prbac "gno.land/p/gnoswap/rbac"
9 "gno.land/p/nt/ufmt"
10
11 "gno.land/r/gnoswap/access"
12 "gno.land/r/gnoswap/halt"
13
14 pn "gno.land/r/gnoswap/position"
15)
16
17// MintAndStake mints a new liquidity position and immediately stakes it.
18//
19// Atomic operation combining position creation and staking.
20// Saves gas by avoiding separate mint and stake transactions.
21// Position NFT transferred directly to staker contract.
22//
23// Parameters:
24// - token0, token1: Token contract paths
25// - fee: Pool fee tier (500=0.05%, 3000=0.3%, 10000=1%)
26// - tickLower, tickUpper: Price range boundaries
27// - amount0Desired, amount1Desired: Target token amounts
28// - amount0Min, amount1Min: Minimum amounts (slippage protection)
29// - deadline: Transaction expiration timestamp
30// - referrer: Optional referral address
31//
32// Native token support:
33// - Accepts GNOT via std.OriginSend()
34// - Auto-wraps to WUGNOT for liquidity
35// - Minimum 1 GNOT required
36//
37// Returns:
38// - positionId: New NFT token ID
39// - liquidity: Amount of liquidity minted
40// - amount0, amount1: Actual tokens deposited
41// - poolPath: Pool identifier
42func (s *stakerV1) MintAndStake(
43 token0 string,
44 token1 string,
45 fee uint32,
46 tickLower int32,
47 tickUpper int32,
48 amount0Desired string,
49 amount1Desired string,
50 amount0Min string,
51 amount1Min string,
52 deadline int64,
53 referrer string,
54) (uint64, string, string, string, string) {
55 halt.AssertIsNotHaltedStaker()
56
57 stakerAddr := access.MustGetAddress(prbac.ROLE_STAKER.String())
58
59 // if one click native
60 if token0 == GNOT_DENOM || token1 == GNOT_DENOM {
61 // check sent ugnot
62 sent := banker.OriginSend()
63 ugnotSent := sent.AmountOf("ugnot")
64
65 // not enough ugnot sent
66 if ugnotSent < UGNOT_MIN_DEPOSIT_TO_WRAP {
67 panic(ufmt.Errorf(
68 "%v: too less ugnot sent(%d), minimum:%d",
69 errWugnotMinimum, ugnotSent, UGNOT_MIN_DEPOSIT_TO_WRAP,
70 ))
71 }
72
73 // send it over to position to wrap
74 positionAddr := access.MustGetAddress(prbac.ROLE_POSITION.String())
75 banker_ := banker.NewBanker(banker.BankerTypeRealmSend)
76 banker_.SendCoins(stakerAddr, positionAddr, chain.Coins{{Denom: GNOT_DENOM, Amount: ugnotSent}})
77 }
78
79 positionId, liquidity, amount0, amount1 := pn.Mint(
80 cross,
81 token0,
82 token1,
83 fee,
84 tickLower,
85 tickUpper,
86 amount0Desired,
87 amount1Desired,
88 amount0Min,
89 amount1Min,
90 deadline,
91 stakerAddr,
92 runtime.PreviousRealm().Address(),
93 referrer,
94 )
95
96 poolPath := s.StakeToken(positionId, referrer)
97
98 return positionId, liquidity, amount0, amount1, poolPath
99}