Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

utils.gno

4.31 Kb · 138 lines
  1package position
  2
  3import (
  4	"strconv"
  5	"strings"
  6
  7	prabc "gno.land/p/gnoswap/rbac/v1"
  8	u256 "gno.land/p/gnoswap/uint256/v1"
  9	"gno.land/p/nt/grc721/v0"
 10	ufmt "gno.land/p/nt/ufmt/v0"
 11	"gno.land/r/gnoswap/access/v1"
 12	pl "gno.land/r/gnoswap/pool"
 13)
 14
 15const MAX_UINT256 string = "115792089237316195423570985008687907853269984665640564039457584007913129639935"
 16
 17func mustGetStakerAddress() address {
 18	return access.MustGetAddress(prabc.ROLE_STAKER.String())
 19}
 20
 21// mustGetPool returns the read-only snapshot for poolPath.
 22// It panics when poolPath does not identify a pool.
 23func mustGetPool(poolPath string) *pl.Pool {
 24	pool, ok := pl.GetPools().Get(poolPath).(*pl.Pool)
 25	if !ok || pool == nil {
 26		panic(ufmt.Sprintf("expected poolPath(%s) to exist", poolPath))
 27	}
 28	return pool
 29}
 30
 31// positionIdFrom converts positionId to grc721.TokenID type
 32// input: positionId uint64
 33// output: grc721.TokenID
 34func positionIdFrom(positionId uint64) grc721.TokenID {
 35	return grc721.TokenID(strconv.FormatUint(positionId, 10))
 36}
 37
 38// exists checks whether positionId exists
 39// If positionId doesn't exist, return false, otherwise return true
 40// input: positionId uint64
 41// output: bool
 42func (p *positionV1) exists(positionId uint64) bool {
 43	return p.nftAccessor.Exists(positionIdFrom(positionId))
 44}
 45
 46// isOwner checks whether the caller is the owner of the positionId
 47// If the caller is the owner of the positionId, return true, otherwise return false
 48// input: positionId uint64, addr std.Address
 49// output: bool
 50func (p *positionV1) isOwner(positionId uint64, addr address) bool {
 51	owner, err := p.nftAccessor.OwnerOf(positionIdFrom(positionId))
 52	if err != nil {
 53		return false
 54	}
 55	return owner == addr
 56}
 57
 58// isOperator checks whether the caller is the approved operator of the positionId
 59// If the caller is the approved operator of the positionId, return true, otherwise return false
 60// input: positionId uint64, addr std.Address
 61// output: bool
 62func (p *positionV1) isOperator(positionId uint64, addr address) bool {
 63	operator, err := p.GetPositionOperator(positionId)
 64	return err == nil && operator == addr
 65}
 66
 67// isStaked checks whether positionId is staked
 68// If positionId is staked, owner of positionId is staker contract
 69// If positionId is staked, return true, otherwise return false
 70// input: positionId grc721.TokenID
 71// output: bool
 72func (p *positionV1) isStaked(positionId grc721.TokenID) bool {
 73	exist := p.nftAccessor.Exists(positionId)
 74	if !exist {
 75		return false
 76	}
 77	owner, err := p.nftAccessor.OwnerOf(positionId)
 78	if err == nil && owner == mustGetStakerAddress() {
 79		return true
 80	}
 81	return false
 82}
 83
 84// isOwnerOrOperator checks whether the caller is the owner or approved operator of the positionId
 85// If the caller is the owner or approved operator of the positionId, return true, otherwise return false
 86// input: addr std.Address, positionId uint64
 87// output: bool
 88func (p *positionV1) isOwnerOrOperator(positionId uint64, addr address) bool {
 89	if !addr.IsValid() || !p.exists(positionId) {
 90		return false
 91	}
 92
 93	if p.isStaked(positionIdFrom(positionId)) {
 94		return p.isOperator(positionId, addr)
 95	}
 96
 97	return p.isOwner(positionId, addr)
 98}
 99
100// splitOf divides poolKey into pToken0, pToken1, and pFee
101// If poolKey is invalid, it will panic
102//
103// input: poolKey string
104// output:
105// - token0Path string
106// - token1Path string
107// - fee uint32
108func splitOf(poolKey string) (string, string, uint32) {
109	res := strings.Split(poolKey, ":")
110	if len(res) != 3 {
111		panic(newErrorWithDetail(errInvalidInput, ufmt.Sprintf("invalid poolKey(%s)", poolKey)))
112	}
113
114	pToken0, pToken1, pFeeStr := res[0], res[1], res[2]
115
116	pFee, err := strconv.Atoi(pFeeStr)
117	if err != nil {
118		panic(newErrorWithDetail(errInvalidInput, ufmt.Sprintf("invalid fee(%s)", pFeeStr)))
119	}
120
121	return pToken0, pToken1, uint32(pFee)
122}
123
124func isSlippageExceeded(amount0, amount1, amount0Min, amount1Min *u256.Uint) bool {
125	return !(amount0.Gte(amount0Min) && amount1.Gte(amount1Min))
126}
127
128// currentPoolObservation derives the latest stored observation from the
129// Uniswap-V3-aligned Slot0 and observations surfaces.
130func currentPoolObservation(poolPath string) (int64, string, int64, error) {
131	slot0 := pl.GetSlot0(poolPath)
132	observation, err := pl.GetObservationAt(poolPath, slot0.ObservationIndex())
133	if err != nil {
134		return 0, "", 0, err
135	}
136
137	return observation.TickCumulative(), observation.SecondsPerLiquidityCumulativeX128(), observation.BlockTimestamp(), nil
138}