Pure package detail
amm
gno.land/p/g1mv0052e7r6s09f5t9xsqf00nj3tqsgt9dg52jr/zdex/amm/v1
Indexed deployment identity with independently loaded latest RPC source. Functions and Render are realm-only RPC capabilities.
Indexed deployment
Identity
- Package path
- gno.land/p/g1mv0052e7r6s09f5t9xsqf00nj3tqsgt9dg52jr/zdex/amm/v1
- Block
- 239169
- Deployed (UTC)
- Transaction
- 9IILGF9t0nKT2jTW8rhNIGh28I4zv0x5C9e7iIj4Wl8=
Latest RPC state
Source
package amm
import (
"math"
"math/bits"
"math/overflow"
)
const bpsDen = int64(10000)
// MulDiv returns floor(a * b / d) for non-negative a, b and d > 0.
// Fast path uses int64 product. Overflow path is 128-bit (a*b)/d — same as
// int64((bigint(a)*bigint(b))/bigint(d)) — and panics only if the quotient
// does not fit int64. Gno has no typed bigint(int64) conversion.
func MulDiv(a, b, d int64) int64 {
return mulDiv(a, b, d, false)
}
// MulDivCeil is ceil(a * b / d) for non-negative a, b and d > 0.
// Ceil only when remainder != 0.
func MulDivCeil(a, b, d int64) int64 {
return mulDiv(a, b, d, true)
}
func mulDiv(a, b, d int64, ceil bool) int64 {
if a < 0 || b < 0 {
panic("zdex: negative muldiv")
}
if d <= 0 {
panic("zdex: division by zero")
}
if a == 0 || b == 0 {
return 0
}
prod, ok := overflow.Mul64(a, b)
if ok {
q := prod / d
if ceil && prod%d != 0 {
return add64(q, 1)
}
return q
}
hi, lo := bits.Mul64(uint64(a), uint64(b))
du := uint64(d)
if hi >= du {
panic("zdex: muldiv overflow")
}
q, r := bits.Div64(hi, lo, du)
if ceil && r != 0 {
if q == uint64(math.MaxInt64) {
panic("zdex: muldiv overflow")
}
q++
}
if q > uint64(math.MaxInt64) {
panic("zdex: muldiv overflow")
}
return int64(q)
}
// Sqrt returns floor(sqrt(n)) for n >= 0 (Babylonian method).
func Sqrt(n int64) int64 {
if n < 0 {
panic("zdex: sqrt of negative")
}
if n < 2 {
return n
}
x := n
y := (x + 1) / 2
for y < x {
x = y
y = (x + n/x) / 2
}
return x
}
func add64(a, b int64) int64 {
s, ok := overflow.Add64(a, b)
if !ok {
panic("zdex: add overflow")
}
return s
}
// AmountOut is Uniswap-v2 getAmountOut against effective (real+virtual) reserves.
// Payout is capped by the real reserveOut — virtual offsets only affect price.
func AmountOut(amountIn, reserveIn, virtualIn, reserveOut, virtualOut, feeBps int64) int64 {
if amountIn <= 0 {
panic("zdex: amountIn must be positive")
}
if feeBps < 0 || feeBps >= bpsDen {
panic("zdex: feeBps out of range")
}
x := add64(reserveIn, virtualIn)
y := add64(reserveOut, virtualOut)
if x <= 0 || y <= 0 {
panic("zdex: empty effective reserves")
}
fee := MulDiv(amountIn, feeBps, bpsDen)
net := amountIn - fee
if net <= 0 {
panic("zdex: fee consumes input")
}
out := MulDiv(net, y, add64(x, net))
if out <= 0 {
panic("zdex: zero output")
}
if out >= y {
panic("zdex: would drain effective reserve")
}
if out >= reserveOut {
panic("zdex: insufficient real reserve")
}
return out
}
// AmountIn is the ugnot/token that must be paid so AmountOut >= amountOut.
// Rounded up so ExactOut does not underpay.
func AmountIn(amountOut, reserveIn, virtualIn, reserveOut, virtualOut, feeBps int64) int64 {
if amountOut <= 0 {
panic("zdex: amountOut must be positive")
}
if feeBps < 0 || feeBps >= bpsDen {
panic("zdex: feeBps out of range")
}
if amountOut >= reserveOut {
panic("zdex: insufficient real reserve")
}
x := add64(reserveIn, virtualIn)
y := add64(reserveOut, virtualOut)
if x <= 0 || y <= 0 {
panic("zdex: empty effective reserves")
}
if amountOut >= y {
panic("zdex: would drain effective reserve")
}
net := MulDivCeil(amountOut, x, y-amountOut)
in := MulDivCeil(net, bpsDen, bpsDen-feeBps)
if in <= 0 {
panic("zdex: zero input")
}
got := AmountOut(in, reserveIn, virtualIn, reserveOut, virtualOut, feeBps)
if got < amountOut {
in = add64(in, 1)
}
return in
}
The verified vm/qfuncs operation accepts realm paths only.
Pure packages expose source files but do not have Realm Render.