Kind Realm (renderable)
Name v1
Namespace gnoswap / position
Exported functions 1
Module gno.land/r/gnoswap/position/v1
gno 0.9 reposition.gno gno
⧉
1 package position 2 3 import ( 4 "chain" 5 6 "gno.land/r/gnoswap/access/v1" 7 8 NewPositionV1 (positionStore interface {GetPosition func(uint64) (gno.land/r/gnoswap/position.Position, bool); GetPositionNextID func() uint64; GetPositions func() *gno.land/p/nt/bptree/v0.BPTree; HasPosition func(uint64) bool; HasPositionNextIDStoreKey func() bool; HasPositionsStoreKey func() bool; RemovePosition func(int, .uverse.realm, uint64) .uverse.error; SetPosition func(int, .uverse.realm, uint64, gno.land/r/gnoswap/position.Position) .uverse.error; SetPositionNextID func(int, .uverse.realm, uint64) .uverse.error; SetPositions func(int, .uverse.realm, *gno.land/p/nt/bptree/v0.BPTree) .uverse.error}, accessor interface {Approve func(int, .uverse.realm, .uverse.address, gno.land/p/nt/grc721/v0.TokenID) .uverse.error; Burn func(int, .uverse.realm, gno.land/p/nt/grc721/v0.TokenID); Exists func(gno.land/p/nt/grc721/v0.TokenID) bool; Mint func(int, .uverse.realm, .uverse.address, gno.land/p/nt/grc721/v0.TokenID) gno.land/p/nt/grc721/v0.TokenID; OwnerOf func(gno.land/p/nt/grc721/v0.TokenID) (.uverse.address, .uverse.error); TotalSupply func() int64}) interface {CollectFee func(int, .uverse.realm, uint64) (uint64, string, string, string, string, string); DecreaseLiquidity func(int, .uverse.realm, uint64, string, string, string, int64) (uint64, string, string, string, string, string, string); GetPositionFeeGrowthInside0LastX128 func(uint64) (string, .uverse.error); GetPositionFeeGrowthInside1LastX128 func(uint64) (string, .uverse.error); GetPositionFeeGrowthInsideLastX128 func(uint64) (string, string, .uverse.error); GetPositionLiquidity func(uint64) (string, .uverse.error); GetPositionOperator func(uint64) (.uverse.address, .uverse.error); GetPositionOwner func(uint64) (.uverse.address, .uverse.error); GetPositionPoolKey func(uint64) (string, .uverse.error); GetPositionTickLower func(uint64) (int32, .uverse.error); GetPositionTickUpper func(uint64) (int32, .uverse.error); GetPositionTicks func(uint64) (int32, int32, .uverse.error); GetPositionTokenBalances func(uint64) (int64, int64, .uverse.error); GetPositionTokensOwed func(uint64) (int64, int64, .uverse.error); GetPositionTokensOwed0 func(uint64) (int64, .uverse.error); GetPositionTokensOwed1 func(uint64) (int64, .uverse.error); GetPositions func() *gno.land/p/nt/bptree/rotree/v0.ReadOnlyTree; GetUnclaimedFee func(uint64) (*gno.land/p/gnoswap/uint256/v1.Uint, *gno.land/p/gnoswap/uint256/v1.Uint, .uverse.error); IncreaseLiquidity func(int, .uverse.realm, uint64, string, string, string, string, int64) (uint64, string, string, string, string); IsBurned func(uint64) (bool, .uverse.error); IsInRange func(uint64) (bool, .uverse.error); Mint func(int, .uverse.realm, string, string, uint32, int32, int32, string, string, string, string, int64, .uverse.address, string) (uint64, string, string, string); Render func(string) string; Reposition func(int, .uverse.realm, uint64, int32, int32, string, string, string, string, int64) (uint64, string, int32, int32, string, string); SetPositionOperator func(int, .uverse.realm, uint64, .uverse.address)}
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
Render unavailable
rate limit exceeded — the render query is served by the Gnoland archive RPC.
vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.
u256
"gno.land/p/gnoswap/uint256/v1"
9 "gno.land/p/gnoswap/utils/v1"
10 ufmt "gno.land/p/nt/ufmt/v0"
11
12 "gno.land/r/gnoswap/common"
13 "gno.land/r/gnoswap/emission"
14 "gno.land/r/gnoswap/halt/v1"
15 )
16
17 // Reposition adjusts the price range and liquidity of an existing position.
18 //
19 // Parameters:
20 // - _: leading integer discriminator; callers pass 0
21 // - rlm: current realm context forwarded from the public wrapper; the implementation validates it as current
22 // - positionId: NFT token ID to reposition
23 // - tickLower: new lower tick boundary of the position's price range
24 // - tickUpper: new upper tick boundary of the position's price range
25 // - amount0DesiredStr: desired token0 amount for the new position, represented as a decimal string
26 // - amount1DesiredStr: desired token1 amount for the new position, represented as a decimal string
27 // - amount0MinStr: minimum acceptable token0 amount for slippage protection
28 // - amount1MinStr: minimum acceptable token1 amount for slippage protection
29 // - deadline: transaction expiration timestamp
30 //
31 // Returns:
32 // - positionId: NFT token ID that was repositioned
33 // - liquidity: new liquidity amount, represented as a decimal string
34 // - tickLower: lower tick boundary applied to the position
35 // - tickUpper: upper tick boundary applied to the position
36 // - amount0: actual token0 amount added to the new range, represented as a decimal string
37 // - amount1: actual token1 amount added to the new range, represented as a decimal string
38 func (p *positionV1) Reposition(
39 _ int ,
40 rlm realm,
41 positionId uint64 ,
42 tickLower int32 ,
43 tickUpper int32 ,
44 amount0DesiredStr string ,
45 amount1DesiredStr string ,
46 amount0MinStr string ,
47 amount1MinStr string ,
48 deadline int64 ,
49 ) ( uint64 , string , int32 , int32 , string , string ) {
50 access.AssertIsRlmCurrent( 0 , rlm)
51
52 halt.AssertIsNotHaltedPosition()
53
54 previousRealm := rlm.Previous()
55 caller := previousRealm.Address()
56 assertIsOwnerForToken(p, positionId, caller)
57 assertIsNotExpired(deadline)
58
59 emission.MintAndDistributeGns(cross(rlm))
60
61 // The position must be clear (zero liquidity and zero tokens owed) before
62 // it can be repositioned.
63 position := p.mustGetPosition(positionId)
64
65 token0, token1, _ := splitOf(position.PoolKey())
66 common.AssertIsNotHandleNativeCoin()
67
68 oldTickLower := position.TickLower()
69 oldTickUpper := position.TickUpper()
70
71 if !position.IsClear() {
72 panic(newErrorWithDetail(
73 errNotClear,
74 ufmt.Sprintf(
75 "position(%d) isn't clear(liquidity:%s, tokensOwed0:%d, tokensOwed1:%d)" ,
76 positionId,
77 position.Liquidity(),
78 position.TokensOwed0(),
79 position.TokensOwed1(),
80 ),
81 ))
82 }
83
84 if err := validateTokenPath(token0, token1); err != nil {
85 panic(newErrorWithDetail(err.Error(), ufmt.Sprintf( "token0(%s), token1(%s)" , token0, token1)))
86 }
87
88 poolKey := position.PoolKey()
89
90 liquidity, amount0, amount1 := p.addLiquidity(
91 0 ,
92 rlm,
93 AddLiquidityParams{
94 poolKey: poolKey,
95 tickLower: tickLower,
96 tickUpper: tickUpper,
97 amount0Desired: u256.MustFromDecimal(amount0DesiredStr),
98 amount1Desired: u256.MustFromDecimal(amount1DesiredStr),
99 amount0Min: u256.MustFromDecimal(amount0MinStr),
100 amount1Min: u256.MustFromDecimal(amount1MinStr),
101 caller: caller,
102 },
103 )
104
105 // update position tickLower, tickUpper to new value
106 // because getCurrentFeeGrowth() uses tickLower, tickUpper
107 position.SetTickLower(tickLower)
108 position.SetTickUpper(tickUpper)
109
110 currentFeeGrowth, err := p.getCurrentFeeGrowth(position, caller)
111 if err != nil {
112 panic(newErrorWithDetail(err.Error(), "failed to get current fee growth" ))
113 }
114 position.SetFeeGrowthInside0LastX128(currentFeeGrowth.feeGrowthInside0LastX128.ToString())
115 position.SetFeeGrowthInside1LastX128(currentFeeGrowth.feeGrowthInside1LastX128.ToString())
116
117 position.SetLiquidity(liquidity.ToString())
118
119 // Do not reset the fee-growth checkpoints: a full decrease followed by
120 // repositioning must not create an unintended unclaimed-fee balance.
121 position.SetTokensOwed0( 0 )
122 position.SetTokensOwed1( 0 )
123 position.SetBurned( false )
124 p.mustUpdatePosition( 0 , rlm, positionId, *position)
125
126 pool := mustGetPool(poolKey)
127 positionLiquidity, err := p.GetPositionLiquidity(positionId)
128 if err != nil {
129 panic(err)
130 }
131 tickCumulative, secondsPerLiquidityCumulativeX128, observationTimestamp, err := currentPoolObservation(poolKey)
132 if err != nil {
133 panic(err)
134 }
135
136 chain.Emit(
137 "Reposition" ,
138 "prevAddr" , previousRealm.Address().String(),
139 "prevRealm" , previousRealm.PkgPath(),
140 "lpPositionId" , utils.FormatUint(positionId),
141 "tickLower" , utils.FormatInt(tickLower),
142 "tickUpper" , utils.FormatInt(tickUpper),
143 "liquidityDelta" , liquidity.ToString(),
144 "amount0" , amount0.ToString(),
145 "amount1" , amount1.ToString(),
146 "prevTickLower" , utils.FormatInt(oldTickLower),
147 "prevTickUpper" , utils.FormatInt(oldTickUpper),
148 "poolPath" , poolKey,
149 "sqrtPriceX96" , pool.Slot0SqrtPriceX96().ToString(),
150 "positionLiquidity" , positionLiquidity,
151 "poolLiquidity" , pool.Liquidity().ToString(),
152 "token0Balance" , utils.FormatInt(pool.BalanceToken0()),
153 "token1Balance" , utils.FormatInt(pool.BalanceToken1()),
154 "tickCumulative" , utils.FormatInt(tickCumulative),
155 "secondsPerLiquidityCumulativeX128" , secondsPerLiquidityCumulativeX128,
156 "observationTimestamp" , utils.FormatInt(observationTimestamp),
157 )
158
159 return positionId, liquidity.ToString(), tickLower, tickUpper, amount0.ToString(), amount1.ToString()
160 }
161