Skip to content

Commit

Permalink
Merge pull request #308 from scorpioborn/feat/sub-main-wager-ticket
Browse files Browse the repository at this point in the history
Refactor / Move sub account deduction props to ticket
  • Loading branch information
3eyedraga authored Nov 20, 2023
2 parents 26ff3f9 + f599abc commit e246937
Show file tree
Hide file tree
Showing 22 changed files with 869 additions and 314 deletions.
4 changes: 2 additions & 2 deletions proto/sge/house/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ message Params {

// max_withdrawal_count is the maximum number of withdrawals allowed
// per participation index.
uint64 max_withdrawal_count = 3
[ (gogoproto.moretags) = "yaml:\"max_withdrawal_count\""];
uint64 max_withdrawal_count = 3
[ (gogoproto.moretags) = "yaml:\"max_withdrawal_count\"" ];
}
6 changes: 4 additions & 2 deletions proto/sge/reward/genesis.proto
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ message GenesisState {
Params params = 1 [ (gogoproto.nullable) = false ];
repeated Campaign campaign_list = 2 [ (gogoproto.nullable) = false ];
repeated Reward reward_list = 3 [ (gogoproto.nullable) = false ];
repeated RewardByCategory reward_by_category_list = 4 [ (gogoproto.nullable) = false ];
repeated RewardByCampaign reward_by_campaign_list = 5 [ (gogoproto.nullable) = false ];
repeated RewardByCategory reward_by_category_list = 4
[ (gogoproto.nullable) = false ];
repeated RewardByCampaign reward_by_campaign_list = 5
[ (gogoproto.nullable) = false ];
}
9 changes: 8 additions & 1 deletion proto/sge/subaccount/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,11 @@ import "gogoproto/gogo.proto";
option go_package = "github.com/sge-network/sge/x/subaccount/types";

// Params defines the parameters for the module.
message Params { option (gogoproto.goproto_stringer) = false; }
message Params {
option (gogoproto.goproto_stringer) = false;

// wager_enabled is enable/disable status of wager feature.
bool wager_enabled = 1;
// deposit_enabled is enable/disable status of deposit feature.
bool deposit_enabled = 2;
}
24 changes: 24 additions & 0 deletions proto/sge/subaccount/ticket.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
syntax = "proto3";
package sgenetwork.sge.subaccount;

import "gogoproto/gogo.proto";

import "sge/bet/tx.proto";

option go_package = "github.com/sge-network/sge/x/subaccount/types";

// SubAccWagerTicketPayload indicates data of subaccount wager ticket.
message SubAccWagerTicketPayload {
// msg holds normal wager message
sgenetwork.sge.bet.MsgWager msg = 1;
// mainacc_deduct_amount is amount to be deducted from main account
string mainacc_deduct_amount = 2 [
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false
];
// subacc_deduct_amount is amount to be deducted from sub account
string subacc_deduct_amount = 3 [
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false
];
}
19 changes: 6 additions & 13 deletions proto/sge/subaccount/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ syntax = "proto3";
package sgenetwork.sge.subaccount;

import "sge/subaccount/balance.proto";
import "sge/bet/tx.proto";
import "sge/house/tx.proto";
import "sge/bet/tx.proto";
import "gogoproto/gogo.proto";

option go_package = "github.com/sge-network/sge/x/subaccount/types";
Expand Down Expand Up @@ -78,18 +78,11 @@ message MsgWithdrawUnlockedBalancesResponse {}

// MsgWager wraps the MsgWager message. We need it in order not to have
// double interface registration conflicts.
message MsgWager {
sgenetwork.sge.bet.MsgWager msg = 1;
// mainacc_deduct_amount is amount to be deducted from main account
string mainacc_deduct_amount = 2 [
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false
];
// subacc_deduct_amount is amount to be deducted from sub account
string subacc_deduct_amount = 3 [
(gogoproto.customtype) = "cosmossdk.io/math.Int",
(gogoproto.nullable) = false
];
message MsgWager {
// creator is the subaccount owner.
string creator = 1;
// ticket is the jwt ticket data.
string ticket = 2;
}

// MsgWagerResponse wraps the MsgWagerResponse message. We need it in order not
Expand Down
6 changes: 0 additions & 6 deletions x/orderbook/keeper/bet_settle.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ func (k Keeper) RefundBettor(
return err
}

k.hooks.AfterBettorRefund(ctx, bettorAddress, betAmount, betFee)

return nil
}

Expand Down Expand Up @@ -73,8 +71,6 @@ func (k Keeper) BettorWins(
k.SetOrderBookParticipation(ctx, orderBookParticipation)
}

k.hooks.AfterBettorWin(ctx, bettorAddress, betAmount, payoutProfit)

return nil
}

Expand Down Expand Up @@ -115,7 +111,5 @@ func (k Keeper) BettorLoses(
k.SetOrderBookParticipation(ctx, orderBookParticipation)
}

k.hooks.AfterBettorLoss(ctx, bettorAddress, betAmount)

return nil
}
4 changes: 0 additions & 4 deletions x/orderbook/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,6 @@ type FeeGrantKeeper interface {

// OrderBookHooks event hooks for orderbook methods.
type OrderBookHooks interface {
AfterBettorWin(ctx sdk.Context, bettor sdk.AccAddress, originalAmount, profit sdkmath.Int)
AfterBettorLoss(ctx sdk.Context, bettor sdk.AccAddress, originalAmount sdkmath.Int)
AfterBettorRefund(ctx sdk.Context, bettor sdk.AccAddress, originalAmount, fee sdkmath.Int)

AfterHouseWin(ctx sdk.Context, house sdk.AccAddress, originalAmount, profit sdkmath.Int)
AfterHouseLoss(ctx sdk.Context, house sdk.AccAddress, originalAmount, lostAmt sdkmath.Int)
AfterHouseRefund(ctx sdk.Context, house sdk.AccAddress, originalAmount sdkmath.Int)
Expand Down
21 changes: 0 additions & 21 deletions x/orderbook/types/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,6 @@ func NewMultiOrderBookHooks(hooks ...OrderBookHooks) MultiOrderBookHooks {
return hooks
}

// AfterBettorWin registers all of hooks for this method.
func (h MultiOrderBookHooks) AfterBettorWin(ctx sdk.Context, bettor sdk.AccAddress, originalAmount, profit sdkmath.Int) {
for i := range h {
h[i].AfterBettorWin(ctx, bettor, originalAmount, profit)
}
}

// AfterBettorLoss registers all of hooks for this method.
func (h MultiOrderBookHooks) AfterBettorLoss(ctx sdk.Context, bettor sdk.AccAddress, originalAmount sdkmath.Int) {
for i := range h {
h[i].AfterBettorLoss(ctx, bettor, originalAmount)
}
}

// AfterBettorRefund registers all of hooks for this method.
func (h MultiOrderBookHooks) AfterBettorRefund(ctx sdk.Context, bettor sdk.AccAddress, originalAmount, fee sdkmath.Int) {
for i := range h {
h[i].AfterBettorRefund(ctx, bettor, originalAmount, fee)
}
}

// AfterHouseWin registers all of hooks for this method.
func (h MultiOrderBookHooks) AfterHouseWin(ctx sdk.Context, house sdk.AccAddress, originalAmount, profit sdkmath.Int) {
for i := range h {
Expand Down
24 changes: 6 additions & 18 deletions x/subaccount/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/version"

bettypes "github.com/sge-network/sge/x/bet/types"
housetypes "github.com/sge-network/sge/x/house/types"
"github.com/sge-network/sge/x/subaccount/types"
)
Expand Down Expand Up @@ -171,38 +170,27 @@ func TxWithdraw() *cobra.Command {
// TxWager implements a command to place and store a single bet
func TxWager() *cobra.Command {
cmd := &cobra.Command{
Use: "wager [uid] [amount] [ticket] --from subaccount-owner-key",
Use: "wager [ticket] --from subaccount-owner-key",
Short: "Wager on an odds",
Long: "Wager on an odds. the uuid, amount and ticket required.",
Args: cobra.ExactArgs(3),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) (err error) {
// Get value arguments
uid := args[0]
argAmount := args[1]
argTicket := args[2]

argAmountCosmosInt, ok := sdkmath.NewIntFromString(argAmount)
if !ok {
return fmt.Errorf("invalid amount: %s", argAmount)
}
argTicket := args[0]

clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

msg := bettypes.NewMsgWager(
msg := types.NewMsgWager(
clientCtx.GetFromAddress().String(),
bettypes.WagerProps{
UID: uid,
Amount: argAmountCosmosInt,
Ticket: argTicket,
},
argTicket,
)
if err := msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &types.MsgWager{Msg: msg})
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

Expand Down
53 changes: 0 additions & 53 deletions x/subaccount/keeper/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,59 +19,6 @@ var _ orderbooktypes.OrderBookHooks = Hooks{}
// Create new distribution hooks
func (k Keeper) Hooks() Hooks { return Hooks{k} }

// AfterBettorWin is subaccount module hook for subaccount bettor winning.
func (h Hooks) AfterBettorWin(ctx sdk.Context, bettor sdk.AccAddress, originalAmount, profit sdkmath.Int) {
balance, exists := h.k.GetAccountSummary(ctx, bettor)
if !exists {
return
}
err := balance.Unspend(originalAmount)
if err != nil {
panic(err)
}
// send profits to subaccount owner
owner, exists := h.k.GetSubAccountOwner(ctx, bettor)
if !exists {
panic("subaccount owner not found")
}
err = h.k.bankKeeper.SendCoins(ctx, bettor, owner, sdk.NewCoins(sdk.NewCoin(params.DefaultBondDenom, profit)))
if err != nil {
panic(err)
}
h.k.SetAccountSummary(ctx, bettor, balance)
}

// AfterBettorLoss is subaccount module hook for subaccount bettor loss.
func (h Hooks) AfterBettorLoss(ctx sdk.Context, bettor sdk.AccAddress, originalAmount sdkmath.Int) {
balance, exists := h.k.GetAccountSummary(ctx, bettor)
if !exists {
return
}
err := balance.Unspend(originalAmount)
if err != nil {
panic(err)
}
err = balance.AddLoss(originalAmount)
if err != nil {
panic(err)
}
h.k.SetAccountSummary(ctx, bettor, balance)
}

// AfterBettorRefund is subaccount module hook for subaccount bettor refund.
func (h Hooks) AfterBettorRefund(ctx sdk.Context, bettor sdk.AccAddress, originalAmount, fee sdkmath.Int) {
balance, exists := h.k.GetAccountSummary(ctx, bettor)
if !exists {
return
}
totalUnspent := originalAmount.Add(fee)
err := balance.Unspend(totalUnspent)
if err != nil {
panic(err)
}
h.k.SetAccountSummary(ctx, bettor, balance)
}

// AfterHouseWin is subaccount module hook for house winning over subbacount.
func (h Hooks) AfterHouseWin(ctx sdk.Context, house sdk.AccAddress, originalAmount, profit sdkmath.Int) {
// update balance
Expand Down
40 changes: 27 additions & 13 deletions x/subaccount/keeper/msg_server_bet.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,54 @@ import (
func (k msgServer) Wager(goCtx context.Context, msg *types.MsgWager) (*types.MsgWagerResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

subAccOwner := sdk.MustAccAddressFromBech32(msg.Msg.Creator)
if !k.keeper.GetWagerEnabled(ctx) {
return nil, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidRequest, "currently the subacount wager tx is not enabled")
}

subAccOwner := sdk.MustAccAddressFromBech32(msg.Creator)
// find subaccount
subAccAddr, exists := k.keeper.GetSubAccountByOwner(ctx, subAccOwner)
if !exists {
return nil, status.Error(codes.NotFound, "subaccount not found")
}

bet, oddsMap, err := k.keeper.betKeeper.PrepareBetObject(ctx, msg.Msg.Creator, msg.Msg.Props)
payload := &types.SubAccWagerTicketPayload{}
err := k.keeper.ovmKeeper.VerifyTicketUnmarshal(sdk.WrapSDKContext(ctx), msg.Ticket, &payload)
if err != nil {
return nil, sdkerrors.Wrapf(types.ErrInTicketVerification, "%s", err)
}

if msg.Creator != payload.Msg.Creator {
return nil, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidRequest, "message creator should be the same as the sub message creator%s", msg.Creator)
}

bet, oddsMap, err := k.keeper.betKeeper.PrepareBetObject(ctx, payload.Msg.Creator, payload.Msg.Props)
if err != nil {
return nil, err
}

if err := payload.Validate(bet.Amount); err != nil {
return nil, sdkerrors.Wrapf(types.ErrInTicketPayloadValidation, "%s", err)
}

mainAccBalance := k.keeper.bankKeeper.GetBalance(
ctx,
sdk.MustAccAddressFromBech32(bet.Creator),
params.DefaultBondDenom)
if mainAccBalance.Amount.LT(msg.MainaccDeductAmount) {
if mainAccBalance.Amount.LT(payload.MainaccDeductAmount) {
return nil, sdkerrors.Wrapf(sdkerrtypes.ErrInvalidRequest, "not enough balance in main account")
}

accSummary, unlockedBalance, _ := k.keeper.getAccountSummary(ctx, subAccAddr)
if unlockedBalance.GTE(msg.SubaccDeductAmount) {
if unlockedBalance.GTE(payload.SubaccDeductAmount) {
if err := k.keeper.bankKeeper.SendCoins(ctx,
subAccAddr,
sdk.MustAccAddressFromBech32(msg.Msg.Creator),
sdk.NewCoins(sdk.NewCoin(params.DefaultBondDenom, msg.SubaccDeductAmount))); err != nil {
sdk.MustAccAddressFromBech32(msg.Creator),
sdk.NewCoins(sdk.NewCoin(params.DefaultBondDenom, payload.SubaccDeductAmount))); err != nil {
return nil, sdkerrors.Wrapf(types.ErrSendCoinError, "error sending coin from subaccount to main account %s", err)
}
} else {
lockedAmountToWithdraw := msg.SubaccDeductAmount.Sub(unlockedBalance)
lockedAmountToWithdraw := payload.SubaccDeductAmount.Sub(unlockedBalance)

if err := accSummary.Withdraw(lockedAmountToWithdraw); err != nil {
return nil, sdkerrors.Wrapf(types.ErrWithdrawLocked, "%s", err)
Expand Down Expand Up @@ -88,19 +106,15 @@ func (k msgServer) Wager(goCtx context.Context, msg *types.MsgWager) (*types.Msg
k.keeper.SetLockedBalances(ctx, subAccAddr, updatedLockedBalances)
}

// if err := accSummary.Spend(msg.SubaccDeductAmount); err != nil {
// return nil, err
// }

if err := k.keeper.betKeeper.Wager(ctx, bet, oddsMap); err != nil {
return nil, err
}

k.keeper.SetAccountSummary(ctx, subAccAddr, accSummary)

msg.EmitEvent(&ctx, subAccOwner.String())
msg.EmitEvent(&ctx, payload.Msg, subAccOwner.String())

return &types.MsgWagerResponse{
Response: &bettypes.MsgWagerResponse{Props: msg.Msg.Props},
Response: &bettypes.MsgWagerResponse{Props: payload.Msg.Props},
}, nil
}
Loading

0 comments on commit e246937

Please sign in to comment.