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/ammmath

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
ammmath
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/ammmath
gno
0.9

Files (2)

  • gnomod.tomltoml
  • ammmath.gnogno
ammmath.gnogno
1// Package ammmath implements integer bonding-curve and constant-product AMM
2// helpers for the gnomemepad factory (Pump-style virtual CPMM + real CPMM pool).
3package ammmath
4
5import "math/overflow"
6
7// FeeResult is the split of a gross trade fee.
8type FeeResult struct {
9	Gross     int64
10	Net       int64
11	Fee       int64
12	Creator   int64
13	Protocol  int64
14	Remainder int64
15}
16
17// ApplyFee takes gross quote paid by the user and feeBPS (e.g. 120 = 1.20%).
18func ApplyFee(gross, feeBPS, creatorShareBPS, protocolShareBPS int64) FeeResult {
19	if gross <= 0 {
20		panic("ammmath: gross must be positive")
21	}
22	if feeBPS < 0 || feeBPS >= 10000 {
23		panic("ammmath: feeBPS out of range")
24	}
25	if creatorShareBPS < 0 || protocolShareBPS < 0 || creatorShareBPS+protocolShareBPS > 10000 {
26		panic("ammmath: fee share BPS invalid")
27	}
28	fee := gross * feeBPS / 10000
29	net := gross - fee
30	creator := fee * creatorShareBPS / 10000
31	protocol := fee * protocolShareBPS / 10000
32	remainder := fee - creator - protocol
33	return FeeResult{
34		Gross:     gross,
35		Net:       net,
36		Fee:       fee,
37		Creator:   creator,
38		Protocol:  protocol,
39		Remainder: remainder,
40	}
41}
42
43// ApplyFeeOnOutput charges fee on assets leaving the pool/curve.
44func ApplyFeeOnOutput(grossOut, feeBPS, creatorShareBPS, protocolShareBPS int64) FeeResult {
45	if grossOut <= 0 {
46		panic("ammmath: grossOut must be positive")
47	}
48	if feeBPS < 0 || feeBPS >= 10000 {
49		panic("ammmath: feeBPS out of range")
50	}
51	if creatorShareBPS < 0 || protocolShareBPS < 0 || creatorShareBPS+protocolShareBPS > 10000 {
52		panic("ammmath: fee share BPS invalid")
53	}
54	fee := grossOut * feeBPS / 10000
55	net := grossOut - fee
56	if net <= 0 {
57		panic("ammmath: fee consumes entire output")
58	}
59	creator := fee * creatorShareBPS / 10000
60	protocol := fee * protocolShareBPS / 10000
61	remainder := fee - creator - protocol
62	return FeeResult{
63		Gross:     grossOut,
64		Net:       net,
65		Fee:       fee,
66		Creator:   creator,
67		Protocol:  protocol,
68		Remainder: remainder,
69	}
70}
71
72// BuyTokens quotes a virtual constant-product buy (net ugnot in).
73func BuyTokens(virtualUgnot, virtualToken, ugnotIn int64) (tokensOut, newVU, newVT int64) {
74	if ugnotIn <= 0 {
75		panic("ammmath: ugnotIn must be positive")
76	}
77	if virtualUgnot <= 0 || virtualToken <= 0 {
78		panic("ammmath: invalid virtual reserves")
79	}
80	newVU, ok := overflow.Add64(virtualUgnot, ugnotIn)
81	if !ok {
82		panic("ammmath: virtual ugnot overflow")
83	}
84	k, ok := overflow.Mul64(virtualUgnot, virtualToken)
85	if !ok {
86		panic("ammmath: k overflow")
87	}
88	newVT = k / newVU
89	if newVT <= 0 {
90		panic("ammmath: empty virtual token reserve")
91	}
92	if newVT >= virtualToken {
93		panic("ammmath: zero tokens out")
94	}
95	tokensOut = virtualToken - newVT
96	return tokensOut, newVU, newVT
97}
98
99// MaxNetInForTokenOut is the largest net ugnot in that yields tokensOut ≤ maxTokensOut
100// (integer CPMM, same floor rules as BuyTokens). Used to fill the last curve tokens
101// without panicking when the user sends too much GNOT.
102func MaxNetInForTokenOut(virtualUgnot, virtualToken, maxTokensOut int64) int64 {
103	if maxTokensOut <= 0 || virtualUgnot <= 0 || virtualToken <= 0 {
104		return 0
105	}
106	if maxTokensOut >= virtualToken {
107		return 0
108	}
109	targetNewVT := virtualToken - maxTokensOut
110	k, ok := overflow.Mul64(virtualUgnot, virtualToken)
111	if !ok {
112		panic("ammmath: k overflow")
113	}
114	// tokensOut ≤ max  ⇔  k/(vu+net) ≥ targetNewVT  ⇔  vu+net ≤ k/targetNewVT (floor)
115	maxNewVU := k / targetNewVT
116	if maxNewVU <= virtualUgnot {
117		return 0
118	}
119	return maxNewVU - virtualUgnot
120}
121
122// SellTokens quotes a virtual constant-product sell (gross ugnot out).
123func SellTokens(virtualUgnot, virtualToken, tokensIn int64) (ugnotOut, newVU, newVT int64) {
124	if tokensIn <= 0 {
125		panic("ammmath: tokensIn must be positive")
126	}
127	if virtualUgnot <= 0 || virtualToken <= 0 {
128		panic("ammmath: invalid virtual reserves")
129	}
130	newVT, ok := overflow.Add64(virtualToken, tokensIn)
131	if !ok {
132		panic("ammmath: virtual token overflow")
133	}
134	k, ok := overflow.Mul64(virtualUgnot, virtualToken)
135	if !ok {
136		panic("ammmath: k overflow")
137	}
138	newVU = k / newVT
139	if newVU <= 0 {
140		panic("ammmath: empty virtual ugnot reserve")
141	}
142	if newVU >= virtualUgnot {
143		panic("ammmath: zero ugnot out")
144	}
145	ugnotOut = virtualUgnot - newVU
146	return ugnotOut, newVU, newVT
147}
148
149// PoolSwapUgnotForToken swaps net ugnot for tokens; remainderToPool adds to ugnot reserve.
150func PoolSwapUgnotForToken(poolUgnot, poolToken, ugnotIn, remainderToPool int64) (tokensOut, newPU, newPT int64) {
151	if ugnotIn <= 0 {
152		panic("ammmath: ugnotIn must be positive")
153	}
154	if poolUgnot <= 0 || poolToken <= 0 {
155		panic("ammmath: invalid pool reserves")
156	}
157	if remainderToPool < 0 {
158		panic("ammmath: negative remainder")
159	}
160	addU, ok := overflow.Add64(ugnotIn, remainderToPool)
161	if !ok {
162		panic("ammmath: add overflow")
163	}
164	newPU, ok = overflow.Add64(poolUgnot, addU)
165	if !ok {
166		panic("ammmath: pool ugnot overflow")
167	}
168	tokensOut = poolToken * ugnotIn / (poolUgnot + ugnotIn)
169	if tokensOut <= 0 {
170		panic("ammmath: zero tokens out of pool")
171	}
172	if tokensOut >= poolToken {
173		panic("ammmath: would drain pool tokens")
174	}
175	newPT = poolToken - tokensOut
176	return tokensOut, newPU, newPT
177}
178
179// PoolSwapTokenForUgnot swaps tokens for gross ugnot out.
180func PoolSwapTokenForUgnot(poolUgnot, poolToken, tokensIn int64) (ugnotOut, newPU, newPT int64) {
181	if tokensIn <= 0 {
182		panic("ammmath: tokensIn must be positive")
183	}
184	if poolUgnot <= 0 || poolToken <= 0 {
185		panic("ammmath: invalid pool reserves")
186	}
187	newPT, ok := overflow.Add64(poolToken, tokensIn)
188	if !ok {
189		panic("ammmath: pool token overflow")
190	}
191	ugnotOut = poolUgnot * tokensIn / (poolToken + tokensIn)
192	if ugnotOut <= 0 {
193		panic("ammmath: zero ugnot out of pool")
194	}
195	if ugnotOut >= poolUgnot {
196		panic("ammmath: would drain pool ugnot")
197	}
198	newPU = poolUgnot - ugnotOut
199	return ugnotOut, newPU, newPT
200}
201
202// CanGraduate reports whether raised net ugnot meets the threshold.
203func CanGraduate(raisedUgnot, threshold int64) bool {
204	return raisedUgnot >= threshold && threshold > 0
205}
206
207// SpotPriceUgnotPerToken returns ugnot per token scaled by 1e6 (display only).
208func SpotPriceUgnotPerToken(ugnotReserve, tokenReserve int64) int64 {
209	if tokenReserve <= 0 {
210		return 0
211	}
212	return ugnotReserve * 1000000 / tokenReserve
213}
214

Functions

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

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