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

funding.gno

3.71 Kb · 126 lines
  1package game_vault
  2
  3import (
  4	"chain"
  5	"chain/banker"
  6	"strconv"
  7
  8	"gno.land/p/akkadia/beta/accesscontrol"
  9	"gno.land/r/akkadia/beta/admin"
 10)
 11
 12type SystemFunding struct {
 13	ID         uint64
 14	PoolID     uint64
 15	FundingKey string
 16	Depositor  address
 17	Amount     int64
 18	Refunded   bool
 19}
 20
 21func DepositSystemFunding(cur realm, poolID uint64, fundingKey string) uint64 {
 22	depositor := accesscontrol.MustGetAdminOrOperatorCaller(0, cur, admin.IsAdmin, admin.IsOperator)
 23	assertKeyLength(fundingKey, "funding key")
 24	if systemFundingIDs.Has(fundingKey) {
 25		panic("funding key already processed")
 26	}
 27	pool := GetRewardPool(poolID)
 28	if pool.Status != RewardPoolStatusOpen {
 29		panic("reward pool is not open")
 30	}
 31	amount := getAttachedUgnotDeposit()
 32	if latestSystemFundingID == maxUint64 {
 33		panic("system funding id exhausted")
 34	}
 35	if pool.Balance > maxInt64-amount || pool.SystemFundedTotal > maxInt64-amount || accountedUgnotTotal > maxInt64-amount {
 36		panic("vault fund amount overflow")
 37	}
 38
 39	latestSystemFundingID++
 40	fundingID := latestSystemFundingID
 41	treeSet(systemFundings, fundingID, SystemFunding{
 42		ID:         fundingID,
 43		PoolID:     poolID,
 44		FundingKey: fundingKey,
 45		Depositor:  depositor,
 46		Amount:     amount,
 47	})
 48	systemFundingIDs.Set(fundingKey, fundingID)
 49	getOrCreateIDSet(poolSystemFundingIDs, poolID).Set(uint64Key(fundingID), true)
 50	pool.SystemFundedTotal += amount
 51	pool.Balance += amount
 52	treeSet(rewardPools, poolID, pool)
 53	accountedUgnotTotal += amount
 54	return fundingID
 55}
 56
 57func RefundSystemFunding(cur realm, poolID uint64, fundingKey, operationKey string) uint64 {
 58	executor := accesscontrol.MustGetAdminOrOperatorCaller(0, cur, admin.IsAdmin, admin.IsOperator)
 59	assertNoAttachedCoins()
 60	assertNewOperationKey(operationKey)
 61	pool := GetRewardPool(poolID)
 62	if pool.Status != RewardPoolStatusCanceled {
 63		panic("reward pool must be canceled before refund")
 64	}
 65	funding := GetSystemFundingByKey(fundingKey)
 66	if funding.PoolID != poolID {
 67		panic("system funding belongs to another reward pool")
 68	}
 69	if funding.Refunded {
 70		panic("system funding already refunded")
 71	}
 72	if pool.Balance < funding.Amount {
 73		panic("insufficient system funding balance")
 74	}
 75
 76	pool.Balance -= funding.Amount
 77	pool.SystemRefundedTotal += funding.Amount
 78	treeSet(rewardPools, poolID, pool)
 79	funding.Refunded = true
 80	treeSet(systemFundings, funding.ID, funding)
 81	return recordAndSendRefund(cross(cur), poolID, operationKey, fundingKey, funding.Depositor, funding.Amount, "system", executor)
 82}
 83
 84func GetSystemFunding(fundingID uint64) SystemFunding {
 85	value, found := treeGet(systemFundings, fundingID)
 86	if !found {
 87		panic("system funding not found: " + strconv.FormatUint(fundingID, 10))
 88	}
 89	return value.(SystemFunding)
 90}
 91
 92func GetLatestSystemFundingID() uint64 { return latestSystemFundingID }
 93
 94func GetSystemFundingByKey(fundingKey string) SystemFunding {
 95	assertKeyLength(fundingKey, "funding key")
 96	value, found := stringGet(systemFundingIDs, fundingKey)
 97	if !found {
 98		panic("system funding not found: " + fundingKey)
 99	}
100	return GetSystemFunding(value.(uint64))
101}
102
103func GetSystemFundingCountByPool(poolID uint64) int {
104	GetRewardPool(poolID)
105	ids, found := getIDSet(poolSystemFundingIDs, poolID)
106	if !found {
107		return 0
108	}
109	return ids.Size()
110}
111
112func ListSystemFundingIDsByPool(poolID uint64, page, count int) []uint64 {
113	GetRewardPool(poolID)
114	ids, _ := getIDSet(poolSystemFundingIDs, poolID)
115	return listIDs(ids, page, count)
116}
117
118func GetAccountedUgnotTotal() int64 { return accountedUgnotTotal }
119
120func GetUnaccountedUgnotTotal() int64 {
121	actual := banker.NewReadonlyBanker().GetCoins(chain.PackageAddress("gno.land/r/akkadia/beta/game_vault")).AmountOf("ugnot")
122	if actual < accountedUgnotTotal {
123		panic("vault fund accounting exceeds realm balance")
124	}
125	return actual - accountedUgnotTotal
126}