disperse.gno

2.82 Kb ยท 105 lines
  1package disperse
  2
  3import (
  4	"chain"
  5	"chain/banker"
  6	"chain/runtime"
  7
  8	tokens "gno.land/r/demo/defi/grc20factory"
  9)
 10
 11var realmAddr = runtime.CurrentRealm().Address()
 12
 13// DisperseUgnot parses receivers and amounts and sends out ugnot
 14// The function will send out the coins to the addresses and return the leftover coins to the caller
 15// if there are any to return
 16func DisperseUgnot(cur realm, addresses []address, coins chain.Coins) {
 17	coinSent := banker.OriginSend()
 18	caller := runtime.PreviousRealm().Address()
 19	banker_ := banker.NewBanker(banker.BankerTypeRealmSend)
 20
 21	if len(addresses) != len(coins) {
 22		panic(ErrNumAddrValMismatch)
 23	}
 24
 25	for _, coin := range coins {
 26		if coin.Amount <= 0 {
 27			panic(ErrNegativeCoinAmount)
 28		}
 29
 30		if banker_.GetCoins(realmAddr).AmountOf(coin.Denom) < coin.Amount {
 31			panic(ErrMismatchBetweenSentAndParams)
 32		}
 33	}
 34
 35	// Send coins
 36	for i := range addresses {
 37		banker_.SendCoins(realmAddr, addresses[i], chain.NewCoins(coins[i]))
 38	}
 39
 40	// Return possible leftover coins
 41	for _, coin := range coinSent {
 42		leftoverAmt := banker_.GetCoins(realmAddr).AmountOf(coin.Denom)
 43		if leftoverAmt > 0 {
 44			send := chain.Coins{chain.NewCoin(coin.Denom, leftoverAmt)}
 45			banker_.SendCoins(realmAddr, caller, send)
 46		}
 47	}
 48}
 49
 50// DisperseUgnotString receives a string of addresses and a string of amounts
 51// and parses them to be used in DisperseUgnot
 52func DisperseUgnotString(cur realm, addresses string, amounts string) {
 53	parsedAddresses, err := parseAddresses(addresses)
 54	if err != nil {
 55		panic(err)
 56	}
 57
 58	parsedAmounts, err := parseAmounts(amounts)
 59	if err != nil {
 60		panic(err)
 61	}
 62
 63	coins := make(chain.Coins, len(parsedAmounts))
 64	for i, amount := range parsedAmounts {
 65		coins[i] = chain.NewCoin("ugnot", amount)
 66	}
 67
 68	DisperseUgnot(cur, parsedAddresses, coins)
 69}
 70
 71// DisperseGRC20 disperses tokens to multiple addresses
 72// Note that it is necessary to approve the realm to spend the tokens before calling this function
 73// see the corresponding filetests for examples
 74func DisperseGRC20(cur realm, addresses []address, amounts []int64, symbols []string) {
 75	caller := runtime.PreviousRealm().Address()
 76
 77	if (len(addresses) != len(amounts)) || (len(amounts) != len(symbols)) {
 78		panic(ErrArgLenAndSentLenMismatch)
 79	}
 80	for _, amount := range amounts {
 81		if amount < 0 {
 82			panic(ErrInvalidAmount)
 83		}
 84	}
 85
 86	for i := 0; i < len(addresses); i++ {
 87		tokens.TransferFrom(cross, symbols[i], caller, addresses[i], amounts[i])
 88	}
 89}
 90
 91// DisperseGRC20String receives a string of addresses and a string of tokens
 92// and parses them to be used in DisperseGRC20
 93func DisperseGRC20String(cur realm, addresses string, tokens string) {
 94	parsedAddresses, err := parseAddresses(addresses)
 95	if err != nil {
 96		panic(err)
 97	}
 98
 99	parsedAmounts, parsedSymbols, err := parseTokens(tokens)
100	if err != nil {
101		panic(err)
102	}
103
104	DisperseGRC20(cur, parsedAddresses, parsedAmounts, parsedSymbols)
105}