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

channel_balance.gno

2.62 Kb · 65 lines
 1package ucs03_zkgm
 2
 3import (
 4	"encoding/hex"
 5
 6	types "gno.land/p/onbloc/ibc/union/types"
 7
 8	u256 "gno.land/p/onbloc/math/uint256"
 9)
10
11// Precision invariant: channel balances are denominated in LOCAL VAULT precision —
12// the actual escrowed amount held on this chain (the grc20 ledger for vouchers,
13// the banker for native), 1:1 with custody — NOT the wire/counterparty precision.
14
15// ChannelBalanceKeyV2 returns the storage key for a v2 channel balance entry.
16func ChannelBalanceKeyV2(channelId types.ChannelId, path *u256.Uint, baseToken, quoteToken []byte) string {
17	return channelId.String() + "/" + path.ToString() + "/" + hex.EncodeToString(baseToken) + "/" + hex.EncodeToString(quoteToken)
18}
19
20// increaseChannelBalanceV2 adds amount to the (channel, path, base, quote) escrow balance.
21// reference: https://github.com/unionlabs/union/blob/d91c5e94354e15801bd5f82dc658eae3b79f2dad/cosmwasm/app/ucs03-zkgm/src/contract.rs#L3272-L3299
22func (v *ucs03ZkgmV1) increaseChannelBalanceV2(_ int, rlm realm, channelId types.ChannelId, path *u256.Uint, baseToken, quoteToken []byte, amount int64) error {
23	key := ChannelBalanceKeyV2(channelId, path, baseToken, quoteToken)
24
25	curAmount, ok := v.store.GetChannelBalanceV2(key)
26	if !ok || curAmount == nil {
27		curAmount = u256.Zero()
28	}
29
30	amountUint256 := u256.NewUint(uint64(amount))
31
32	// silently storing a smaller balance. This entrypoint returns no error,
33	// so an overflow aborts the tx via panic.
34	calculatedAmount, overflow := u256.Zero().AddOverflow(curAmount, amountUint256)
35	if overflow {
36		return makeError(errChannelBalanceOverflow)
37	}
38
39	v.store.SetChannelBalanceV2(0, rlm, key, calculatedAmount)
40
41	return nil
42}
43
44// decreaseChannelBalanceV2 subtracts from the escrow balance, erroring on underflow and preserving a zero entry.
45// reference: https://github.com/unionlabs/union/blob/d91c5e94354e15801bd5f82dc658eae3b79f2dad/cosmwasm/app/ucs03-zkgm/src/contract.rs#L3241-L3268
46func (v *ucs03ZkgmV1) decreaseChannelBalanceV2(_ int, rlm realm, channelId types.ChannelId, path *u256.Uint, baseToken, quoteToken []byte, amount int64) error {
47	key := ChannelBalanceKeyV2(channelId, path, baseToken, quoteToken)
48
49	amountUint256 := u256.NewUint(uint64(amount))
50
51	curAmount, ok := v.store.GetChannelBalanceV2(key)
52	if !ok || curAmount == nil || curAmount.Cmp(amountUint256) < 0 {
53		return makeError(errChannelBalanceUnderflow)
54	}
55
56	// This entrypoint returns an error, so an underflow aborts the tx via return.
57	calculatedAmount, underflow := u256.Zero().SubOverflow(curAmount, amountUint256)
58	if underflow {
59		return makeError(errChannelBalanceUnderflow)
60	}
61
62	v.store.SetChannelBalanceV2(0, rlm, key, calculatedAmount)
63
64	return nil
65}