Skip to content

Commit

Permalink
Merge branch 'upgrade/promoter-category' into release/v1.7.x
Browse files Browse the repository at this point in the history
  • Loading branch information
scorpioborn committed Apr 30, 2024
2 parents a109ef6 + fd1ab06 commit 15b50ae
Show file tree
Hide file tree
Showing 54 changed files with 721 additions and 505 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@
# ignore visual studio code dev container config
.devcontainer

# ignore build directory
# ignore build dir
build
1 change: 1 addition & 0 deletions app/upgrades/v3/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package v3

import (
sdkmath "cosmossdk.io/math"

"github.com/sge-network/sge/app/upgrades"
)

Expand Down
4 changes: 2 additions & 2 deletions app/upgrades/v8/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"github.com/sge-network/sge/app/upgrades"
)

// UpgradeName defines the on-chain upgrade name for the v1.6.1 upgrade.
const UpgradeName = "v1.6.1"
// UpgradeName defines the on-chain upgrade name for the v1.6.2 upgrade.
const UpgradeName = "v1.6.2"

var Upgrade = upgrades.Upgrade{
UpgradeName: UpgradeName,
Expand Down
71 changes: 41 additions & 30 deletions app/upgrades/v8/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/sge-network/sge/app/keepers"
"github.com/sge-network/sge/x/reward/types"
)
Expand All @@ -17,42 +18,52 @@ func CreateUpgradeHandler(
k *keepers.AppKeepers,
) upgradetypes.UpgradeHandler {
return func(ctx sdk.Context, plan upgradetypes.Plan, fromVM module.VersionMap) (module.VersionMap, error) {
allCampaigns := k.RewardKeeper.GetAllCampaign(ctx)
promoters := make(map[string]struct{})
for _, c := range allCampaigns {
c.CapCount = 0 // infinite cap for all campaigns
c.Pool.Withdrawn = sdkmath.ZeroInt()
k.RewardKeeper.SetCampaign(ctx, c)
promoters[c.Promoter] = struct{}{}
}
allPromoters := k.RewardKeeper.GetAllPromoter(ctx)
promoterUID := "f0630627-9e4e-48f3-8cd5-1422b46d2175"
if len(allPromoters) == 0 {
allCampaigns := k.RewardKeeper.GetAllCampaign(ctx)
promoters := make(map[string]struct{})
for _, c := range allCampaigns {
c.CapCount = 0 // infinite cap for all campaigns
c.Pool.Withdrawn = sdkmath.ZeroInt()
k.RewardKeeper.SetCampaign(ctx, c)
promoters[c.Promoter] = struct{}{}
}

promoterAddresses := []string{}
for addr := range promoters {
promoterAddresses = append(promoterAddresses, addr)
}
sort.Strings(promoterAddresses)

if len(promoterAddresses) > 0 {
promoterUID := "f0630627-9e4e-48f3-8cd5-1422b46d2175"
k.RewardKeeper.SetPromoter(ctx, types.Promoter{
Creator: promoterAddresses[0],
UID: promoterUID,
Addresses: promoterAddresses,
Conf: types.PromoterConf{
CategoryCap: []types.CategoryCap{
{Category: types.RewardCategory_REWARD_CATEGORY_SIGNUP, CapPerAcc: 1},
},
},
})
promoterAddresses := []string{}
for addr := range promoters {
promoterAddresses = append(promoterAddresses, addr)
}
sort.Strings(promoterAddresses)

for _, addr := range promoterAddresses {
k.RewardKeeper.SetPromoterByAddress(ctx, types.PromoterByAddress{
PromoterUID: promoterUID,
Address: addr,
if len(promoterAddresses) > 0 {
promoterUID := promoterUID
k.RewardKeeper.SetPromoter(ctx, types.Promoter{
Creator: promoterAddresses[0],
UID: promoterUID,
Addresses: promoterAddresses,
Conf: types.PromoterConf{
CategoryCap: []types.CategoryCap{
{Category: types.RewardCategory_REWARD_CATEGORY_SIGNUP, CapPerAcc: 1},
},
},
})

for _, addr := range promoterAddresses {
k.RewardKeeper.SetPromoterByAddress(ctx, types.PromoterByAddress{
PromoterUID: promoterUID,
Address: addr,
})
}
}
}

allByCat := k.RewardKeeper.GetAllRewardsOfReceiverByPromoterAndCategory(ctx)
for _, rc := range allByCat {
k.RewardKeeper.RemoveRewardOfReceiverByPromoterAndCategory(ctx, "", rc)
k.RewardKeeper.SetRewardOfReceiverByPromoterAndCategory(ctx, promoterUID, rc)
}

return mm.RunMigrations(ctx, configurator, fromVM)
}
}
15 changes: 13 additions & 2 deletions docs/specs/Bet/01_Overview.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# **Overview**

The Bet module is responsible for receiving and processing requests to wager and settle bets. In the case of wagering, it validates the request and places the bet.
The **Bet module** handles requests related to betting and bet settlement. Let's break it down:

For the settlement, blockchain automatically queries resolved markets then for each of these markets, checks the result of the market, determines the bet result, and settles the bet using `orderbook` module.
- **Wagering**:
- When a user places a bet, the Bet module validates the request.
- It then processes the bet and records it.

- **Settlement**:
- After a market is resolved, the blockchain automatically queries the results.
- For each market, the Bet module:
- Checks the outcome.
- Determines the bet result.
- Settles the bet using the `orderbook` module.

In summary, the Bet module ensures smooth betting interactions and accurate settlement based on market outcomes.
84 changes: 51 additions & 33 deletions docs/specs/Bet/02_Concepts.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,70 @@
# **Concepts**

Bet module is tasked with placement and settlement of the bets. the user can place bet on a same market multiple times with different or equal odds through commandline or singing and broadcasting the bet placement message.
The **Bet module** is responsible for handling the placement and settlement of bets. Users can place bets on the same market multiple times, either with different or equal odds, using the command line or by singing and broadcasting the bet placement message.

> Wagering will be done using a ticket containing odds info signed by a trusted source. Verifying this ticket will be done in the placement state itself.
> Bet amount can not be less than a minimum amount which is defined for each market. A module parameter is used for this purpose.
> Also, a betting fee has been defined for each market, A module parameter is used for this purpose.
Here are some key points about the betting process:

1. **Wagering and Ticket Verification**:
- Wagering is facilitated through a ticket that contains odds information, signed by a trusted source.
- The verification of this ticket occurs during the placement state itself.

2. **Minimum Bet Amount**:
- Each market defines a minimum bet amount.
- Users cannot place bets below this minimum threshold.
- A module parameter controls this requirement.

3. **Betting Fee**:
- For each market, a specific betting fee has been established.
- Again, a module parameter governs this fee.

---

Before accepting bet some validation should take place:
**Before Accepting a Bet, Validation Steps:**

1. **Market-Level Validation:**
- Ensure the market is active for bet placement.
- Verify that the market is neither resolved nor canceled.
- Confirm that the bet amount (after deducting the betting fee) meets the minimum allowed bet amount.

- Market level validation:
- Market is active for bet placement.
- Market is not already resolved or canceled.
- Bet amount (deducted by betting fee) is not less than the minimum allowed bet amount.
- Bet level validation:
- Provided UUID is valid.
- Odds Value and the validations according to the American, British and decimal odds.
- Check if the max loss multiplier is positive and less than 1.
- OVM level validation:
- All data provided in placement request is valid e.g. odds value.
- KYC Validation:
- If Ignore is false in bet ticket payload, then the status of kyc approval should be true and tx signer and kyc id should be same for a bet to be placed.
- If Ignore is true in bet ticket payload, then kyc validation is not required and bet can be placed without kyc check.
2. **Bet-Level Validation:**
- Validate the provided UUID.
- Check odds values and apply validations based on American, British, and decimal odds.
- Ensure the max loss multiplier is positive and less than 1.

Wager Assumptions:
3. **OVM-Level Validation:**
- Validate all data provided in the placement request, including odds values.

- For bet placement user can raise a request to place a single bet, it can be done for a single bet only.
- When a user is raising a transaction to place a bet, the creator of the transaction is the owner of the bet.
4. **KYC Validation:**
- If the "Ignore" flag in the bet ticket payload is false:
- Verify that KYC approval status is true.
- Confirm that the transaction signer and KYC ID match for the bet to be placed.
- If the "Ignore" flag is true, KYC validation is not required, and the bet can proceed without further checks.

After a bet is accepted:
**Wager Assumptions:**

- Bet amount transfer to the `orderbook_liquidity_pool` module account this is done by the `orderbook` module.
- Betting fee will be transferred to the `bet_fee_collector` module account. this is done by the `orderbook` module.
- Bet fulfillments are being processed by `orderbook` module in the `ProcessWager` keeper's method.
- Users can request to place a single bet only.
- The creator of the transaction is considered the owner of the bet.

**After Bet Acceptance:**

- The bet amount is transferred to the `orderbook_liquidity_pool` module account by the `orderbook` module.
- Betting fees are transferred to the `bet_fee_collector` module account, also managed by the `orderbook` module.
- Bet fulfillments are processed by the `orderbook` module using the `ProcessWager` keeper's method.

## Supported Odds Types

> Note: Let bet_amount be 3564819
**Note:** Let `bet_amount` be 3,564,819.

- ***Decimal(European):*** Calculated as `bet_amount * oddsValue` ex. `3564819 * 1.29 = 4598616.51`.
- ***Fractional(British):*** Calculated as `bet_amount + (bet_amount * fraction)` ex. `3564819 + (3564819 * 2/7) = 4583338.71`.
- ***Moneyline(American):*** Calculated as:
- Positive odds value: `bet_amount + (bet_amount * |oddsValue/100|)` ex. `3564819 + 3564819 * |+350/100| = 16041685.50` the result will be rounded to floor.
- Negative odds value: `bet_amount + (bet_amount * |100/oddsValue|)` ex. `3564819 + 3564819 * |100/-350| = 4583338.71` the result will be rounded to floor.
- **Decimal (European):** Calculated as `bet_amount * oddsValue`. For example, `3,564,819 * 1.29 = 4,598,616.51`.
- **Fractional (British):** Calculated as `bet_amount + (bet_amount * fraction)`. For instance, `3,564,819 + (3,564,819 * 2/7) = 4,583,338.71`.
- **Moneyline (American):** Calculated as follows:
- For positive odds value: `bet_amount + (bet_amount * |oddsValue/100|)`. For instance, with odds of +350, `3,564,819 + 3,564,819 * |350/100| = 16,041,685.50` (rounded down).
- For negative odds value: `bet_amount + (bet_amount * |100/oddsValue|)`. For example, with odds of -350, `3,564,819 + 3,564,819 * |100/-350| = 4,583,338.71` (rounded down).

### Precision

Some of the Online Calculators round the division result to two-digit precision in Fractional and Moneyline calculations. In other words, these online calculators try to convert Moneyline and Fractional odds to Decimal odds and then calculate the payout according to the calculated rounded decimal value. This approach makes a big difference in the resulting payout. SGE-Network is accepting bets with usge that may have a high value in the market. For this kind of value, it is better to have a high-precision calculation in the blockchain code.
Some online calculators employ a two-digit precision when rounding division results in Fractional and Moneyline calculations. Specifically, these tools convert Moneyline and Fractional odds to Decimal odds and then compute the payout based on the rounded decimal value. This approach significantly impacts the resulting payout.

SGE-Network currently accepts bets with the `usge` currency, which may have substantial value in the market. For such high-value scenarios, it is advisable to perform high-precision calculations within the blockchain code.

> Note: The final calculated payout amounts are rounded to 2 digit float values, so we have a small portion of lost benefits/payouts.
> **Note:** The final calculated payout amounts are rounded to two-digit float values, resulting in a slight loss of benefits or payouts.
14 changes: 7 additions & 7 deletions docs/specs/Bet/03_Accounts.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
# **Accounts**
# **Account Details**

There is one account in the Bet module.
Within the Bet module, there exists a single account:

- Betting Fee Collector: This account holds the betting fee transferred from the bettor to the `bet_fee_collector` module account.
- **Betting Fee Collector**: This account receives the betting fee transferred from the bettor to the `bet_fee_collector` module account.

During bet placement, betting fee is transferred from the bettor's account to the bet module account in the Bet module.
When placing a bet, the betting fee is moved from the bettor's account to the bet module account in the Bet module.

## Wager Transfer

The bet amount (deducted by betting fee) is transferred to the `orderbook_liquidity_pool` module account in `orderbook` module.
The bet amount (after deducting the betting fee) is then transferred to the `orderbook_liquidity_pool` module account within the `orderbook` module.

## Settlement Transfer

- if the user is winner, the bet amount and payout profit will be transferred from `orderbook_liquidity_pool` module account to the winner's account.
- If the user is loser, the bet amount and fee will not go back to bettor's account.
- If the user is a winner, both the bet amount and the payout profit are transferred from the `orderbook_liquidity_pool` module account to the winner's account.
- However, if the user is a loser, the bet amount and fee remain with the bettor and do not return to their account.
25 changes: 12 additions & 13 deletions docs/specs/Bet/04_State.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,23 @@

## **KVStore**

State in bet module is defined by its KVStore. This KVStore has five prefixes:
The state in the bet module is defined by its **KVStore**. This KVStore consists of five prefixes:

1. All bets of a certain creator, using this pattern, blockchain is able to return list of all bets, bets of a certain creator and a single bet. The key prefix is created dynamically using this combination: `BetListPrefix`+`{Creator Address}`+`{Secuential Bet ID}`

2. Map of BetID and BetUID. this helps to get corresponding ID of the bet by issuing the UID. The keys are UIDs of bets and the values are sequencial generated IDs by blockchain.
3. Pending bets of a certain Market to help batch settlement.
4. Settled bets of a block height to keep track of the settled bets for the oracle services.
5. Bet statistics that contains the count of the total bets used to create next sequencial BetID.
1. **All Bets of a Certain Creator**: Using this pattern, the blockchain can retrieve a list of all bets, bets of a specific creator, and individual bets. The key prefix is dynamically created by combining `BetListPrefix`, the `{Creator Address}`, and the `{Sequential Bet ID}`.
2. **Mapping of BetID to BetUID**: This mapping helps retrieve the corresponding bet ID by issuing the UID. The keys represent UIDs of bets, and the values are sequentially generated IDs by the blockchain.
3. **Pending Bets of a Certain Market**: This prefix assists with batch settlement.
4. **Settled Bets of a Block Height**: Used to track settled bets for oracle services.
5. **Bet Statistics**: Contains the total count of bets, which is used to create the next sequential BetID.

The bet model in the Proto files is as below:

## **Params**

1. `batch_settlement_count`: is the count of bets to be automatically settlement in end-blocker.
2. `max_bet_by_uid_query_count`: is the max count of bets to be returned in the bets by uids query.
3. `constraints` contains criteria of the bet placement.
- `min_amount` minimum bet amount while placement.
- `fee` bet fee amount payable by bettor.
1. **`batch_settlement_count`** represents the number of bets that will be automatically settled during the end-blocker process.
2. **`max_bet_by_uid_query_count`** specifies the maximum number of bets to be returned in the query for bets by user IDs.
3. **`constraints`** section includes the criteria for placing bets:
- **`min_amount`**: This is the minimum bet amount required during placement.
- **`fee`**: The bet fee amount payable by the bettor.

```proto
// Params defines the parameters for the module.
Expand All @@ -40,7 +39,7 @@ message Params {

## **Constraints**

Holds bet placement constraints of the bet module.
Holds wager constraints of the bet module.

```proto
// Constraints is the bet constrains type for the bets
Expand Down
Loading

0 comments on commit 15b50ae

Please sign in to comment.