/
deposit.go
131 lines (109 loc) · 4.45 KB
/
deposit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package gov
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov/types"
)
// GetDeposit gets the deposit of a specific depositor on a specific proposal
func (keeper Keeper) GetDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress) (deposit Deposit, found bool) {
store := ctx.KVStore(keeper.storeKey)
bz := store.Get(types.DepositKey(proposalID, depositorAddr))
if bz == nil {
return deposit, false
}
keeper.cdc.MustUnmarshalBinaryLengthPrefixed(bz, &deposit)
return deposit, true
}
func (keeper Keeper) setDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, deposit Deposit) {
store := ctx.KVStore(keeper.storeKey)
bz := keeper.cdc.MustMarshalBinaryLengthPrefixed(deposit)
store.Set(types.DepositKey(proposalID, depositorAddr), bz)
}
// AddDeposit adds or updates a deposit of a specific depositor on a specific proposal
// Activates voting period when appropriate
func (keeper Keeper) AddDeposit(ctx sdk.Context, proposalID uint64, depositorAddr sdk.AccAddress, depositAmount sdk.Coins) (sdk.Error, bool) {
// Checks to see if proposal exists
proposal, ok := keeper.GetProposal(ctx, proposalID)
if !ok {
return ErrUnknownProposal(keeper.codespace, proposalID), false
}
// Check if proposal is still depositable
if (proposal.Status != StatusDepositPeriod) && (proposal.Status != StatusVotingPeriod) {
return ErrAlreadyFinishedProposal(keeper.codespace, proposalID), false
}
// update the governance module's account coins pool
err := keeper.supplyKeeper.SendCoinsFromAccountToModule(ctx, depositorAddr, types.ModuleName, depositAmount)
if err != nil {
return err, false
}
// Update proposal
proposal.TotalDeposit = proposal.TotalDeposit.Add(depositAmount)
keeper.SetProposal(ctx, proposal)
// Check if deposit has provided sufficient total funds to transition the proposal into the voting period
activatedVotingPeriod := false
if proposal.Status == StatusDepositPeriod && proposal.TotalDeposit.IsAllGTE(keeper.GetDepositParams(ctx).MinDeposit) {
keeper.activateVotingPeriod(ctx, proposal)
activatedVotingPeriod = true
}
// Add or update deposit object
deposit, found := keeper.GetDeposit(ctx, proposalID, depositorAddr)
if found {
deposit.Amount = deposit.Amount.Add(depositAmount)
} else {
deposit = NewDeposit(proposalID, depositorAddr, depositAmount)
}
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeProposalDeposit,
sdk.NewAttribute(sdk.AttributeKeyAmount, depositAmount.String()),
sdk.NewAttribute(types.AttributeKeyProposalID, fmt.Sprintf("%d", proposalID)),
),
)
keeper.setDeposit(ctx, proposalID, depositorAddr, deposit)
return nil, activatedVotingPeriod
}
// GetAllDeposits returns all the deposits from the store
func (keeper Keeper) GetAllDeposits(ctx sdk.Context) (deposits Deposits) {
keeper.IterateAllDeposits(ctx, func(deposit Deposit) bool {
deposits = append(deposits, deposit)
return false
})
return
}
// GetDeposits returns all the deposits from a proposal
func (keeper Keeper) GetDeposits(ctx sdk.Context, proposalID uint64) (deposits Deposits) {
keeper.IterateDeposits(ctx, proposalID, func(deposit Deposit) bool {
deposits = append(deposits, deposit)
return false
})
return
}
// GetDepositsIterator gets all the deposits on a specific proposal as an sdk.Iterator
func (keeper Keeper) GetDepositsIterator(ctx sdk.Context, proposalID uint64) sdk.Iterator {
store := ctx.KVStore(keeper.storeKey)
return sdk.KVStorePrefixIterator(store, types.DepositsKey(proposalID))
}
// RefundDeposits refunds and deletes all the deposits on a specific proposal
func (keeper Keeper) RefundDeposits(ctx sdk.Context, proposalID uint64) {
store := ctx.KVStore(keeper.storeKey)
keeper.IterateDeposits(ctx, proposalID, func(deposit types.Deposit) bool {
err := keeper.supplyKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, deposit.Depositor, deposit.Amount)
if err != nil {
panic(err)
}
store.Delete(DepositKey(proposalID, deposit.Depositor))
return false
})
}
// DeleteDeposits deletes all the deposits on a specific proposal without refunding them
func (keeper Keeper) DeleteDeposits(ctx sdk.Context, proposalID uint64) {
store := ctx.KVStore(keeper.storeKey)
keeper.IterateDeposits(ctx, proposalID, func(deposit types.Deposit) bool {
err := keeper.supplyKeeper.BurnCoins(ctx, types.ModuleName, deposit.Amount)
if err != nil {
panic(err)
}
store.Delete(DepositKey(proposalID, deposit.Depositor))
return false
})
}