PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/r/gnoswap/position/v1

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v1
Namespace
gnoswap / position
Files
17 (README)(gnomod.toml)
Exported functions
1
Module
gno.land/r/gnoswap/position/v1
gno
0.9

Files (17)

  • README.mdmarkdown
  • gnomod.tomltoml
  • assert.gnogno
  • burn.gnogno
  • doc.gnogno
  • errors.gnogno
  • getter.gnogno
  • init.gnogno
  • instance.gnogno
  • liquidity_management.gnogno
  • manager.gnogno
  • mint.gnogno
  • position.gnogno
  • render.gnogno
  • reposition.gnogno
  • type.gnogno
  • utils.gnogno
  • burn.gnogno
    1package position23import (4	"errors"56	"gno.land/p/gnoswap/consts/v1"7	"gno.land/p/gnoswap/gnsmath/v1"8

    Functions

    • 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.

    Rendered

    RenderedRawgnoweb ↗

    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 pl "gno.land/r/gnoswap/pool"
    13 "gno.land/r/gnoswap/position"
    14)
    15
    16// decreaseLiquidity reduces position liquidity and collects fees.
    17// Returns positionId, liquidity, fee0, fee1, amount0, amount1, poolPath.
    18func (p *positionV1) decreaseLiquidity(_ int, rlm realm, params DecreaseLiquidityParams) (uint64, string, string, string, string, string, string, error) {
    19 caller := params.caller
    20
    21 // before decrease liquidity, collect fee first
    22 _, fee0Str, fee1Str, _, _, _ := p.collectFee(0, rlm, params.positionId, params.caller)
    23
    24 position := p.mustGetPosition(params.positionId)
    25 positionLiquidity := u256.MustFromDecimal(position.Liquidity())
    26 if positionLiquidity.IsZero() {
    27 return params.positionId,
    28 "",
    29 fee0Str,
    30 fee1Str,
    31 "", "",
    32 position.PoolKey(),
    33 makeErrorWithDetails(
    34 errZeroLiquidity,
    35 ufmt.Sprintf("position(position ID:%d) has 0 liquidity", params.positionId),
    36 )
    37 }
    38
    39 liquidityToRemove := u256.MustFromDecimal(params.liquidity)
    40
    41 if liquidityToRemove.Gt(positionLiquidity) {
    42 return params.positionId,
    43 liquidityToRemove.ToString(),
    44 fee0Str,
    45 fee1Str,
    46 "", "",
    47 position.PoolKey(),
    48 makeErrorWithDetails(
    49 errInvalidLiquidity,
    50 ufmt.Sprintf("Liquidity requested(%s) is greater than liquidity held(%s)", liquidityToRemove.ToString(), positionLiquidity.ToString()),
    51 )
    52 }
    53
    54 pToken0, pToken1, pFee := splitOf(position.PoolKey())
    55 burn0, burn1 := pl.Burn(cross(rlm), pToken0, pToken1, pFee, position.TickLower(), position.TickUpper(), liquidityToRemove.ToString(), caller)
    56
    57 burnedAmount0 := utils.SafeParseInt64(burn0)
    58 burnedAmount1 := utils.SafeParseInt64(burn1)
    59
    60 if burnedAmount0 < 0 || burnedAmount1 < 0 {
    61 panic(errors.New(errUnderflow))
    62 }
    63
    64 positionKey := computePositionKey(position.TickLower(), position.TickUpper())
    65 feeGrowthInside0LastX128Str, feeGrowthInside1LastX128Str, err := pl.GetPositionFeeGrowthInsideLastX128(position.PoolKey(), positionKey)
    66 if err != nil {
    67 return 0, "", "", "", "", "", position.PoolKey(), err
    68 }
    69
    70 // Add only burned amounts to tokensOwed since fees were already collected and processed in collectFee
    71 tokensOwed0 := gnsmath.SafeAddInt64(position.TokensOwed0(), burnedAmount0)
    72 tokensOwed1 := gnsmath.SafeAddInt64(position.TokensOwed1(), burnedAmount1)
    73
    74 newLiquidity, underflow := u256.Zero().SubOverflow(positionLiquidity, liquidityToRemove)
    75 if underflow {
    76 panic(newErrorWithDetail(errUnderflow, "positionLiquidity - liquidityToRemove underflow"))
    77 }
    78
    79 position.SetTokensOwed0(tokensOwed0)
    80 position.SetTokensOwed1(tokensOwed1)
    81 position.SetFeeGrowthInside0LastX128(feeGrowthInside0LastX128Str)
    82 position.SetFeeGrowthInside1LastX128(feeGrowthInside1LastX128Str)
    83 position.SetLiquidity(newLiquidity.ToString())
    84
    85 p.mustUpdatePosition(0, rlm, params.positionId, *position)
    86
    87 collect0, collect1 := pl.Collect(
    88 cross(rlm),
    89 pToken0,
    90 pToken1,
    91 pFee,
    92 caller,
    93 position.TickLower(),
    94 position.TickUpper(),
    95 burn0,
    96 burn1,
    97 )
    98
    99 collectAmount0 := u256.MustFromDecimal(collect0)
    100 collectAmount1 := u256.MustFromDecimal(collect1)
    101
    102 // Slippage check on actually collected amounts to ensure user receives minimum expected tokens
    103 if isSlippageExceeded(collectAmount0, collectAmount1, params.amount0Min, params.amount1Min) {
    104 return params.positionId,
    105 liquidityToRemove.ToString(),
    106 fee0Str,
    107 fee1Str,
    108 collect0,
    109 collect1,
    110 position.PoolKey(),
    111 makeErrorWithDetails(
    112 errSlippage,
    113 ufmt.Sprintf("collectAmount0(%s) >= amount0Min(%s) && collectAmount1(%s) >= amount1Min(%s)",
    114 collectAmount0.ToString(),
    115 params.amount0Min.ToString(),
    116 collectAmount1.ToString(),
    117 params.amount1Min.ToString(),
    118 ),
    119 )
    120 }
    121
    122 // Check for underflow when subtracting collected amounts from tokens owed
    123 collectAmount0Int64 := gnsmath.SafeConvertToInt64(collectAmount0)
    124 collectAmount1Int64 := gnsmath.SafeConvertToInt64(collectAmount1)
    125
    126 if position.TokensOwed0() < collectAmount0Int64 {
    127 panic(ufmt.Sprintf("[POSITION] burn.gno | collect() | tokensOwed0(%d) < collectAmount0(%d)", position.TokensOwed0(), collectAmount0Int64))
    128 }
    129 position.SetTokensOwed0(gnsmath.SafeSubInt64(position.TokensOwed0(), collectAmount0Int64))
    130
    131 if position.TokensOwed1() < collectAmount1Int64 {
    132 panic(ufmt.Sprintf("[POSITION] burn.gno | collect() | tokensOwed1(%d) < collectAmount1(%d)", position.TokensOwed1(), collectAmount1Int64))
    133 }
    134 position.SetTokensOwed1(gnsmath.SafeSubInt64(position.TokensOwed1(), collectAmount1Int64))
    135
    136 if position.IsClear() {
    137 position.SetBurned(true) // just update flag (we don't want to burn actual position)
    138 }
    139
    140 p.mustUpdatePosition(0, rlm, params.positionId, *position)
    141
    142 return params.positionId, liquidityToRemove.ToString(), fee0Str, fee1Str, collect0, collect1, position.PoolKey(), nil
    143}
    144
    145// calculateFees calculates the fees for the current position.
    146func (p *positionV1) calculateFees(position *position.Position, currentFeeGrowth FeeGrowthInside) (int64, int64) {
    147 posLiquidity := u256.MustFromDecimal(position.Liquidity())
    148 fee0 := calculateTokensOwed(
    149 currentFeeGrowth.feeGrowthInside0LastX128,
    150 u256.MustFromDecimal(position.FeeGrowthInside0LastX128()),
    151 posLiquidity,
    152 )
    153
    154 fee1 := calculateTokensOwed(
    155 currentFeeGrowth.feeGrowthInside1LastX128,
    156 u256.MustFromDecimal(position.FeeGrowthInside1LastX128()),
    157 posLiquidity,
    158 )
    159
    160 return gnsmath.SafeAddInt64(position.TokensOwed0(), gnsmath.SafeConvertToInt64(fee0)), gnsmath.SafeAddInt64(position.TokensOwed1(), gnsmath.SafeConvertToInt64(fee1))
    161}
    162
    163func calculateTokensOwed(
    164 feeGrowthInsideLastX128 *u256.Uint,
    165 positionFeeGrowthInsideLastX128 *u256.Uint,
    166 positionLiquidity *u256.Uint,
    167) *u256.Uint {
    168 diff := u256.Zero().Sub(feeGrowthInsideLastX128, positionFeeGrowthInsideLastX128)
    169 return u256.MulDiv(diff, positionLiquidity, consts.Q128())
    170}
    171