PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidatorsAnalytics

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
  • mint.gnogno
    1package position23import (4	"errors"56	u256 "gno.land/p/gnoswap/uint256/v1"7	ufmt "gno.land/p/nt/ufmt/v0"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 ↗
    This realm does not provide renderable output (vm/qrender → NoRenderDeclError). View on gnoweb ↗

    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.

    9 "gno.land/r/gnoswap/common"
    10 pl "gno.land/r/gnoswap/pool"
    11 "gno.land/r/gnoswap/position"
    12)
    13
    14// mint creates a new liquidity position by adding liquidity to a pool and minting an NFT.
    15// Panics if position ID already exists or adding liquidity fails.
    16func (p *positionV1) mint(_ int, rlm realm, params MintParams) (uint64, *u256.Uint, *u256.Uint, *u256.Uint) {
    17 poolKey := pl.GetPoolPath(params.token0, params.token1, params.fee)
    18 liquidity, amount0, amount1 := p.addLiquidity(
    19 0,
    20 rlm,
    21 AddLiquidityParams{
    22 poolKey: poolKey,
    23 tickLower: params.tickLower,
    24 tickUpper: params.tickUpper,
    25 amount0Desired: params.amount0Desired,
    26 amount1Desired: params.amount1Desired,
    27 amount0Min: params.amount0Min,
    28 amount1Min: params.amount1Min,
    29 caller: params.caller,
    30 },
    31 )
    32 // Ensure liquidity is not zero before minting NFT
    33 if liquidity.IsZero() {
    34 panic(newErrorWithDetail(
    35 errZeroLiquidity,
    36 "Liquidity is zero, cannot mint position.",
    37 ))
    38 }
    39
    40 id := p.getNextId()
    41
    42 if p.ExistPosition(id) {
    43 panic(newErrorWithDetail(
    44 errPositionExist,
    45 ufmt.Sprintf("positionId(%d)", id),
    46 ))
    47 }
    48
    49 p.nftAccessor.Mint(0, rlm, params.mintTo, positionIdFrom(id))
    50
    51 positionKey := computePositionKey(params.tickLower, params.tickUpper)
    52 feeGrowthInside0LastX128, feeGrowthInside1LastX128, err := pl.GetPositionFeeGrowthInsideLastX128(poolKey, positionKey)
    53 if err != nil {
    54 panic(err)
    55 }
    56
    57 position := position.NewPosition(
    58 poolKey,
    59 params.tickLower,
    60 params.tickUpper,
    61 liquidity.ToString(),
    62 feeGrowthInside0LastX128,
    63 feeGrowthInside1LastX128,
    64 0,
    65 0,
    66 false,
    67 zeroAddress,
    68 )
    69
    70 // The position ID should not exist at the time of minting
    71 p.mustUpdatePosition(0, rlm, id, *position)
    72 p.incrementNextId(0, rlm)
    73
    74 return id, liquidity, amount0, amount1
    75}
    76
    77// processMintInput processes and validates user input for minting liquidity.
    78// It handles token ordering and amount validation.
    79func (p *positionV1) processMintInput(input MintInput) (ProcessedMintInput, error) {
    80 token0, token1 := input.token0, input.token1
    81 if err := validateTokenPath(token0, token1); err != nil {
    82 return ProcessedMintInput{}, makeErrorWithDetails(err.Error(), ufmt.Sprintf("token0(%s), token1(%s)", token0, token1))
    83 }
    84
    85 pair := TokenPair{
    86 token0: token0,
    87 token1: token1,
    88 }
    89
    90 // parse amounts
    91 amount0Desired, amount1Desired, amount0Min, amount1Min := parseAmounts(input.amount0Desired, input.amount1Desired, input.amount0Min, input.amount1Min)
    92
    93 tickLower, tickUpper := input.tickLower, input.tickUpper
    94
    95 // swap if token1 < token0
    96 if token1 < token0 {
    97 pair.token0, pair.token1 = pair.token1, pair.token0
    98 amount0Desired, amount1Desired = amount1Desired, amount0Desired
    99 amount0Min, amount1Min = amount1Min, amount0Min
    100 tickLower, tickUpper = -tickUpper, -tickLower
    101 }
    102
    103 return ProcessedMintInput{
    104 tokenPair: pair,
    105 amount0Desired: amount0Desired,
    106 amount1Desired: amount1Desired,
    107 amount0Min: amount0Min,
    108 amount1Min: amount1Min,
    109 tickLower: tickLower,
    110 tickUpper: tickUpper,
    111 poolPath: pl.GetPoolPath(pair.token0, pair.token1, input.fee),
    112 }, nil
    113}
    114
    115// increaseLiquidity increases the liquidity of an existing position.
    116func (p *positionV1) increaseLiquidity(_ int, rlm realm, params IncreaseLiquidityParams) (uint64, *u256.Uint, *u256.Uint, *u256.Uint, string, error) {
    117 caller := params.caller
    118 position := p.mustGetPosition(params.positionId)
    119
    120 liquidity, amount0, amount1 := p.addLiquidity(
    121 0,
    122 rlm,
    123 AddLiquidityParams{
    124 poolKey: position.PoolKey(),
    125 tickLower: position.TickLower(),
    126 tickUpper: position.TickUpper(),
    127 amount0Desired: params.amount0Desired,
    128 amount1Desired: params.amount1Desired,
    129 amount0Min: params.amount0Min,
    130 amount1Min: params.amount1Min,
    131 caller: caller,
    132 },
    133 )
    134
    135 positionKey := computePositionKey(position.TickLower(), position.TickUpper())
    136 feeGrowthInside0LastX128Str, feeGrowthInside1LastX128Str, err := pl.GetPositionFeeGrowthInsideLastX128(position.PoolKey(), positionKey)
    137 if err != nil {
    138 return 0, nil, nil, nil, "", err
    139 }
    140
    141 feeGrowth := FeeGrowthInside{
    142 feeGrowthInside0LastX128: u256.MustFromDecimal(feeGrowthInside0LastX128Str),
    143 feeGrowthInside1LastX128: u256.MustFromDecimal(feeGrowthInside1LastX128Str),
    144 }
    145 tokensOwed0, tokensOwed1 := p.calculateFees(position, feeGrowth)
    146
    147 posLiquidity := u256.MustFromDecimal(position.Liquidity())
    148 liquidityAmount, overflow := u256.Zero().AddOverflow(posLiquidity, liquidity)
    149 if overflow {
    150 return 0, nil, nil, nil, "", errors.New(errOverflow)
    151 }
    152
    153 position.SetTokensOwed0(tokensOwed0)
    154 position.SetTokensOwed1(tokensOwed1)
    155
    156 position.SetFeeGrowthInside0LastX128(feeGrowthInside0LastX128Str)
    157 position.SetFeeGrowthInside1LastX128(feeGrowthInside1LastX128Str)
    158
    159 position.SetLiquidity(liquidityAmount.ToString())
    160 position.SetBurned(false)
    161
    162 err = p.setPosition(0, rlm, params.positionId, *position)
    163 if err != nil {
    164 return 0, nil, nil, nil, "", makeErrorWithDetails(
    165 errPositionDoesNotExist,
    166 ufmt.Sprintf("cannot increase liquidity for non-existent position(%d)", params.positionId),
    167 )
    168 }
    169
    170 return params.positionId, liquidity, amount0, amount1, position.PoolKey(), nil
    171}
    172
    173// validateTokenPath validates token paths are not identical, not conflicting, and in valid format.
    174func validateTokenPath(token0, token1 string) error {
    175 if token0 == token1 {
    176 return errors.New(errInvalidTokenPath)
    177 }
    178 if !isValidTokenPath(token0) || !isValidTokenPath(token1) {
    179 return errors.New(errInvalidTokenPath)
    180 }
    181 return nil
    182}
    183
    184// isValidTokenPath checks if the token path is registered in the system.
    185func isValidTokenPath(tokenPath string) bool {
    186 return common.IsRegistered(tokenPath) == nil
    187}
    188
    189// parseAmounts converts amount strings to u256.Uint values.
    190func parseAmounts(amount0Desired, amount1Desired, amount0Min, amount1Min string) (*u256.Uint, *u256.Uint, *u256.Uint, *u256.Uint) {
    191 return u256.MustFromDecimal(amount0Desired), u256.MustFromDecimal(amount1Desired), u256.MustFromDecimal(amount0Min), u256.MustFromDecimal(amount1Min)
    192}
    193