-
Notifications
You must be signed in to change notification settings - Fork 38
/
handler.go
80 lines (69 loc) · 2.7 KB
/
handler.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
package burn
import (
"fmt"
"reflect"
"strings"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/bank"
"github.com/bnb-chain/node/common/log"
common "github.com/bnb-chain/node/common/types"
"github.com/bnb-chain/node/plugins/tokens/store"
)
func NewHandler(tokenMapper store.Mapper, keeper bank.Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
if msg, ok := msg.(BurnMsg); ok {
return handleBurnToken(ctx, tokenMapper, keeper, msg)
}
errMsg := "Unrecognized msg type: " + reflect.TypeOf(msg).Name()
return sdk.ErrUnknownRequest(errMsg).Result()
}
}
func handleBurnToken(ctx sdk.Context, tokenMapper store.Mapper, keeper bank.Keeper, msg BurnMsg) sdk.Result {
logger := log.With("module", "token", "symbol", msg.Symbol, "amount", msg.Amount)
burnAmount := msg.Amount
symbol := strings.ToUpper(msg.Symbol)
token, err := tokenMapper.GetToken(ctx, symbol)
if err != nil {
logger.Info("burn token failed", "reason", "invalid token symbol")
return sdk.ErrInvalidCoins(err.Error()).Result()
}
var coins sdk.Coins
if !sdk.IsUpgrade(sdk.BEP82) {
if !token.IsOwner(msg.From) {
logger.Info("burn token failed", "reason", "not token's owner", "from", msg.From, "owner", token.GetOwner())
return sdk.ErrUnauthorized("only the owner of the token can burn the token").Result()
}
coins = keeper.GetCoins(ctx, token.GetOwner())
} else {
coins = keeper.GetCoins(ctx, msg.From)
}
balance := coins.AmountOf(symbol)
if balance < burnAmount ||
token.GetTotalSupply().ToInt64() < burnAmount {
logger.Info("burn token failed", "reason", "no enough tokens to burn")
return sdk.ErrInsufficientCoins("do not have enough token to burn").Result()
}
if common.IsMiniTokenSymbol(symbol) {
if burnAmount < common.MiniTokenMinExecutionAmount && balance != burnAmount {
logger.Info("burn token failed", "reason", "burn amount doesn't reach the min amount")
return sdk.ErrInvalidCoins(fmt.Sprintf("burn amount is too small, the min amount is %d or total free balance",
common.MiniTokenMinExecutionAmount)).Result()
}
}
_, _, sdkError := keeper.SubtractCoins(ctx, msg.From, sdk.Coins{{
Denom: symbol,
Amount: burnAmount,
}})
if sdkError != nil {
logger.Error("burn token failed", "reason", "subtract tokens failed: "+sdkError.Error())
return sdkError.Result()
}
newTotalSupply := token.GetTotalSupply().ToInt64() - burnAmount
err = tokenMapper.UpdateTotalSupply(ctx, symbol, newTotalSupply)
if err != nil {
logger.Error("burn token failed", "reason", "update total supply failed: "+err.Error())
return sdk.ErrInternal(err.Error()).Result()
}
logger.Info("successfully burnt token", "NewTotalSupply", newTotalSupply)
return sdk.Result{}
}