PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidators

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/p/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/gnomi/ammmathv2

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
ammmathv2
Namespace
g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt / gnomi
Files
2 (gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/gnomi/ammmathv2
gno
0.9

Files (2)

  • gnomod.tomltoml
  • ammmath.gnogno
ammmath.gnogno
1// Package ammmath implements integer bonding-curve and constant-product AMM2// helpers for the gnomemepad factory (Pump-style virtual CPMM + real CPMM pool).3package ammmathv245import (6	"math/bits"7	"math/overflow"8)910// FeeResult is the split of a gross trade fee.11type FeeResult struct {12	Gross     int6413	Net       int6414	Fee       int6415	Creator   int6416	Protocol  int6417	Remainder int6418}1920// maxInt64 is 2^63-1; MulDiv results must fit here.21const maxInt64 = int64(^uint64(0) >> 1)2223// MulDiv returns floor((x * y) / d) for x,y >= 0 and d > 0.24// Uses a 128-bit intermediate so mainnet-scale k (VU*VT ≈ 1.1e20) does not overflow.25// Panics on bad domain or if the quotient does not fit in int64.26func MulDiv(x, y, d int64) int64 {27	if x < 0 || y < 0 {28		panic("ammmath: MulDiv negative operand")29	}30	if d <= 0 {31		panic("ammmath: MulDiv non-positive divisor")32	}33	if x == 0 || y == 0 {34		return 035	}36	if prod, ok := overflow.Mul64(x, y); ok {37		return prod / d38	}39	hi, lo := bits.Mul64(uint64(x), uint64(y))40	// bits.Div64 panics if d == 0 or uint64(d) <= hi (quotient ≥ 2^64).41	quo, _ := bits.Div64(hi, lo, uint64(d))42	if quo > uint64(maxInt64) {43		panic("ammmath: MulDiv result overflow")44	}45	return int64(quo)46}4748// ApplyFee takes gross quote paid by the user and feeBPS (e.g. 120 = 1.20%).49func ApplyFee(gross, feeBPS, creatorShareBPS, protocolShareBPS int64) FeeResult {50	if gross <= 0 {51		panic("ammmath: gross must be positive")52	}53	if feeBPS < 0 || feeBPS >= 10000 {54		panic("ammmath: feeBPS out of range")55	}56	if creatorShareBPS < 0 || protocolShareBPS < 0 || creatorShareBPS+protocolShareBPS > 10000 {57		panic("ammmath: fee share BPS invalid")58	}59	fee := gross * feeBPS / 1000060	net := gross - fee61	creator := fee * creatorShareBPS / 1000062	protocol := fee * protocolShareBPS / 1000063	remainder := fee - creator - protocol64	return FeeResult{65		Gross:     gross,66		Net:       net,67		Fee:       fee,68		Creator:   creator,69		Protocol:  protocol,70		Remainder: remainder,71	}72}7374// ApplyFeeOnOutput charges fee on assets leaving the pool/curve.75func ApplyFeeOnOutput(grossOut, feeBPS, creatorShareBPS, protocolShareBPS int64) FeeResult {76	if grossOut <= 0 {77		panic("ammmath: grossOut must be positive")78	}79	if feeBPS < 0 || feeBPS >= 10000 {80		panic("ammmath: feeBPS out of range")81	}82	if creatorShareBPS < 0 || protocolShareBPS < 0 || creatorShareBPS+protocolShareBPS > 10000 {83		panic("ammmath: fee share BPS invalid")84	}85	fee := grossOut * feeBPS / 1000086	net := grossOut - fee87	if net <= 0 {88		panic("ammmath: fee consumes entire output")89	}90	creator := fee * creatorShareBPS / 1000091	protocol := fee * protocolShareBPS / 1000092	remainder := fee - creator - protocol93	return FeeResult{94		Gross:     grossOut,95		Net:       net,96		Fee:       fee,97		Creator:   creator,98		Protocol:  protocol,99		Remainder: remainder,100	}101}102103// BuyTokens quotes a virtual constant-product buy (net ugnot in).104func BuyTokens(virtualUgnot, virtualToken, ugnotIn int64) (tokensOut, newVU, newVT int64) {105	if ugnotIn <= 0 {106		panic("ammmath: ugnotIn must be positive")107	}108	if virtualUgnot <= 0 || virtualToken <= 0 {109		panic("ammmath: invalid virtual reserves")110	}111	newVU, ok := overflow.Add64(virtualUgnot, ugnotIn)112	if !ok {113		panic("ammmath: virtual ugnot overflow")114	}115	// newVT = floor((VU*VT)/newVU) without materializing k in int64116	newVT = MulDiv(virtualUgnot, virtualToken, newVU)117	if newVT <= 0 {118		panic("ammmath: empty virtual token reserve")119	}120	if newVT >= virtualToken {121		panic("ammmath: zero tokens out")122	}123	tokensOut = virtualToken - newVT124	return tokensOut, newVU, newVT125}126127// MaxNetInForTokenOut is the largest net ugnot in that yields tokensOut ≤ maxTokensOut128// (integer CPMM, same floor rules as BuyTokens). Used to fill the last curve tokens129// without panicking when the user sends too much GNOT.130func MaxNetInForTokenOut(virtualUgnot, virtualToken, maxTokensOut int64) int64 {131	if maxTokensOut <= 0 || virtualUgnot <= 0 || virtualToken <= 0 {132		return 0133	}134	if maxTokensOut >= virtualToken {135		return 0136	}137	targetNewVT := virtualToken - maxTokensOut138	// maxNewVU = floor((VU*VT)/targetNewVT)139	maxNewVU := MulDiv(virtualUgnot, virtualToken, targetNewVT)140	if maxNewVU <= virtualUgnot {141		return 0142	}143	return maxNewVU - virtualUgnot144}145146// SellTokens quotes a virtual constant-product sell (gross ugnot out).147func SellTokens(virtualUgnot, virtualToken, tokensIn int64) (ugnotOut, newVU, newVT int64) {148	if tokensIn <= 0 {149		panic("ammmath: tokensIn must be positive")150	}151	if virtualUgnot <= 0 || virtualToken <= 0 {152		panic("ammmath: invalid virtual reserves")153	}154	newVT, ok := overflow.Add64(virtualToken, tokensIn)155	if !ok {156		panic("ammmath: virtual token overflow")157	}158	newVU = MulDiv(virtualUgnot, virtualToken, newVT)159	if newVU <= 0 {160		panic("ammmath: empty virtual ugnot reserve")161	}162	if newVU >= virtualUgnot {163		panic("ammmath: zero ugnot out")164	}165	ugnotOut = virtualUgnot - newVU166	return ugnotOut, newVU, newVT167}168169// PoolSwapUgnotForToken swaps net ugnot for tokens; remainderToPool adds to ugnot reserve.170func PoolSwapUgnotForToken(poolUgnot, poolToken, ugnotIn, remainderToPool int64) (tokensOut, newPU, newPT int64) {171	if ugnotIn <= 0 {172		panic("ammmath: ugnotIn must be positive")173	}174	if poolUgnot <= 0 || poolToken <= 0 {175		panic("ammmath: invalid pool reserves")176	}177	if remainderToPool < 0 {178		panic("ammmath: negative remainder")179	}180	addU, ok := overflow.Add64(ugnotIn, remainderToPool)181	if !ok {182		panic("ammmath: add overflow")183	}184	newPU, ok = overflow.Add64(poolUgnot, addU)185	if !ok {186		panic("ammmath: pool ugnot overflow")187	}188	den, ok := overflow.Add64(poolUgnot, ugnotIn)189	if !ok {190		panic("ammmath: pool denom overflow")191	}192	tokensOut = MulDiv(poolToken, ugnotIn, den)193	if tokensOut <= 0 {194		panic("ammmath: zero tokens out of pool")195	}196	if tokensOut >= poolToken {197		panic("ammmath: would drain pool tokens")198	}199	newPT = poolToken - tokensOut200	return tokensOut, newPU, newPT201}202203// PoolSwapTokenForUgnot swaps tokens for gross ugnot out.204func PoolSwapTokenForUgnot(poolUgnot, poolToken, tokensIn int64) (ugnotOut, newPU, newPT int64) {205	if tokensIn <= 0 {206		panic("ammmath: tokensIn must be positive")207	}208	if poolUgnot <= 0 || poolToken <= 0 {209		panic("ammmath: invalid pool reserves")210	}211	newPT, ok := overflow.Add64(poolToken, tokensIn)212	if !ok {213		panic("ammmath: pool token overflow")214	}215	ugnotOut = MulDiv(poolUgnot, tokensIn, newPT)216	if ugnotOut <= 0 {217		panic("ammmath: zero ugnot out of pool")218	}219	if ugnotOut >= poolUgnot {220		panic("ammmath: would drain pool ugnot")221	}222	newPU = poolUgnot - ugnotOut223	return ugnotOut, newPU, newPT224}225226// CanGraduate reports whether raised net ugnot meets the threshold.227func CanGraduate(raisedUgnot, threshold int64) bool {228	return raisedUgnot >= threshold && threshold > 0229}230231// SpotPriceUgnotPerToken returns ugnot per token scaled by 1e6 (display only).232func SpotPriceUgnotPerToken(ugnotReserve, tokenReserve int64) int64 {233	if tokenReserve <= 0 {234		return 0235	}236	if ugnotReserve <= 0 {237		return 0238	}239	return MulDiv(ugnotReserve, 1_000_000, tokenReserve)240}241

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.