package keeper import ( "context" "fmt" "math/big" "colinear/x/colinearcore/auctionconfig" "colinear/x/colinearcore/types" sdk "github.com/cosmos/cosmos-sdk/types" ) func (k msgServer) LockFunds(goCtx context.Context, msg *types.MsgLockFunds) (*types.MsgLockFundsResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) senderAddr, err := sdk.AccAddressFromBech32(msg.Creator) if err != nil { return nil, fmt.Errorf("must be a bech32-formatted address: %s", msg.Creator) } lockedUsers, found := k.Keeper.GetLockedUsers(ctx) if !found { // initialize if not yet initialized lockedUsers = types.LockedUsers{ Users: map[string]string{}, } // return nil, errors.New("unable to get locked users") } required := big.NewInt(auctionconfig.ProviderMinLockedUClr) paying := new(big.Int) paying.SetString(msg.Amount, 10) prevAmountS, ok := lockedUsers.Users[msg.Creator] if !ok { // not found prevAmountS = "0" } prevAmount := new(big.Int) prevAmount.SetString(prevAmountS, 10) // make sure that total amount after lock meets minimum required locked amount totalAfterPay := new(big.Int) totalAfterPay.Add(prevAmount, paying) if totalAfterPay.Cmp(required) == -1 { return nil, fmt.Errorf("final locked amount must be at least minimum required (actual: %s)", totalAfterPay.String()) } spendable := k.bank.SpendableCoins(ctx, senderAddr) if spendable.AmountOf("uclr").BigInt().Cmp(paying) != -1 { sendCoins := sdk.NewCoins(sdk.NewCoin("uclr", sdk.NewIntFromBigInt(paying))) if err := k.bank.SendCoinsFromAccountToModule(ctx, senderAddr, types.ModuleName, sendCoins); err != nil { return nil, fmt.Errorf("failed to lock %s uCLR in bank module: %s", paying.String(), err) } } else { return nil, fmt.Errorf("not enough balance to lock %s uCLR (your balance: %s)", paying.String(), spendable.AmountOf("uclr").String()) } lockedUsers.Users[msg.Creator] = totalAfterPay.String() k.Keeper.SetLockedUsers(ctx, lockedUsers) return &types.MsgLockFundsResponse{}, nil }