diff --git a/x/colinearcore/keeper/msg_server_unlock_funds.go b/x/colinearcore/keeper/msg_server_unlock_funds.go index 76b9ac1..40bc154 100644 --- a/x/colinearcore/keeper/msg_server_unlock_funds.go +++ b/x/colinearcore/keeper/msg_server_unlock_funds.go @@ -2,16 +2,58 @@ package keeper import ( "context" + "errors" + "fmt" + "math/big" "colinear/x/colinearcore/types" + sdk "github.com/cosmos/cosmos-sdk/types" ) func (k msgServer) UnlockFunds(goCtx context.Context, msg *types.MsgUnlockFunds) (*types.MsgUnlockFundsResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) - // TODO: Handling the message - _ = ctx + lockedUsers, ok := k.Keeper.GetLockedUsers(ctx) + if !ok { + return nil, errors.New("unable to get locked users") + } + + lockedBalStr, ok := lockedUsers.Users[msg.Creator] + if !ok { + return nil, fmt.Errorf("no locked balance found for user %s", msg.Creator) + } + + lockedBal := new(big.Int) + lockedBal.SetString(lockedBalStr, 10) + + unlockAmt := new(big.Int) + unlockAmt.SetString(msg.Amount, 10) + + if unlockAmt.Cmp(big.NewInt(0)) != 1 { + return nil, errors.New("cannot unlock 0 or less uCLR") + } + + if unlockAmt.Cmp(lockedBal) == 1 { + return nil, fmt.Errorf("cannot unlock more than locked amount (max: %s)", lockedBalStr) + } + + sendCoins := sdk.NewCoins(sdk.NewCoin("uclr", sdk.NewIntFromBigInt(unlockAmt))) + + if err := k.bank.SendCoinsFromModuleToAccount(ctx, types.ModuleName, sdk.AccAddress(msg.Creator), sendCoins); err != nil { + return nil, fmt.Errorf("failed to send %s uCLR: %s", unlockAmt.String(), err) + } + + remaining := new(big.Int) + remaining.Sub(lockedBal, unlockAmt) + + if remaining.Cmp(big.NewInt(0)) == 0 { + delete(lockedUsers.Users, msg.Creator) + } else { + lockedUsers.Users[msg.Creator] = remaining.String() + } + + k.Keeper.SetLockedUsers(ctx, lockedUsers) return &types.MsgUnlockFundsResponse{}, nil }