// Deposit performs deposit operation to participate as a house in a specific market/order book
func (k msgServer) Deposit(goCtx context.Context,
msg *types.MsgDeposit,
) (*types.MsgDepositResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
params := k.GetParams(ctx)
if err := msg.ValidateSanity(ctx, ¶ms); err != nil {
return nil, sdkerrors.Wrap(err, "invalid deposit")
}
var payload types.DepositTicketPayload
if err := k.ovmKeeper.VerifyTicketUnmarshal(goCtx, msg.Ticket, &payload); err != nil {
return nil, sdkerrors.Wrapf(types.ErrInTicketVerification, "%s", err)
}
depositorAddr := msg.Creator
if payload.DepositorAddress != "" &&
payload.DepositorAddress != msg.Creator {
if err := k.ValidateMsgAuthorization(ctx, msg.Creator, payload.DepositorAddress, msg); err != nil {
return nil, err
}
depositorAddr = payload.DepositorAddress
}
if err := payload.Validate(depositorAddr); err != nil {
return nil, sdkerrors.Wrapf(types.ErrInTicketPayloadValidation, "%s", err)
}
participationIndex, err := k.Keeper.Deposit(
ctx,
msg.Creator,
depositorAddr,
msg.MarketUID,
msg.Amount,
)
if err != nil {
return nil, sdkerrors.Wrap(err, "failed to deposit")
}
msg.EmitEvent(&ctx, depositorAddr, participationIndex)
return &types.MsgDepositResponse{
MarketUID: msg.MarketUID,
ParticipationIndex: participationIndex,
}, nil
}
// Withdraw performs withdrawal of unused tokens corresponding to a deposit.
func (k msgServer) Withdraw(goCtx context.Context,
msg *types.MsgWithdraw,
) (*types.MsgWithdrawResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
var payload types.WithdrawTicketPayload
if err := k.ovmKeeper.VerifyTicketUnmarshal(goCtx, msg.Ticket, &payload); err != nil {
return nil, sdkerrors.Wrapf(types.ErrInTicketVerification, "%s", err)
}
isOnBehalf := false
depositorAddr := msg.Creator
if payload.DepositorAddress != "" {
depositorAddr = payload.DepositorAddress
isOnBehalf = true
}
if err := payload.Validate(depositorAddr); err != nil {
return nil, sdkerrors.Wrapf(types.ErrInTicketPayloadValidation, "%s", err)
}
// Get the deposit object
deposit, found := k.GetDeposit(ctx, depositorAddr, msg.MarketUID, msg.ParticipationIndex)
if !found {
return nil, sdkerrors.Wrapf(types.ErrDepositNotFound, ": %s, %d", msg.MarketUID, msg.ParticipationIndex)
}
var err error
msg.Amount, err = k.orderbookKeeper.CalcWithdrawalAmount(ctx,
depositorAddr,
msg.MarketUID,
msg.ParticipationIndex,
msg.Mode,
deposit.TotalWithdrawalAmount,
msg.Amount,
)
if err != nil {
return nil, sdkerrors.Wrapf(types.ErrInTicketVerification, "%s", err)
}
if isOnBehalf {
if err := k.ValidateMsgAuthorization(ctx, msg.Creator, payload.DepositorAddress, msg); err != nil {
return nil, err
}
}
id, err := k.Keeper.Withdraw(ctx, deposit, msg.Creator, depositorAddr, msg.MarketUID,
msg.ParticipationIndex, msg.Mode, msg.Amount)
if err != nil {
return nil, sdkerrors.Wrap(err, "process withdrawal")
}
msg.EmitEvent(&ctx, depositorAddr, id)
return &types.MsgWithdrawResponse{
ID: id,
MarketUID: msg.MarketUID,
ParticipationIndex: msg.ParticipationIndex,
}, nil
}