Incentives via coin emissions play a vital role in any healthy blockchain ecosystem.
Bitplanet's emission rewards serves three roles:
Incentivize coin holders to secure the network as a staker / delegator.
Reward key contributors to the Bitplanet ecosystem with the blockchain's native coin.
Fund the Bitplanet Treasury with BPL to pay for the cost of minting Cores
Note: we use emissions and inflation interchangeably below.
Middle Way between Governments & Corporations
On the 2nd point, imagine a middle way between governments and corporations. In which, citizens (contributors) were compensated in governance coins proportionally to their contribution earnings, thus creating an incentive alignment with skin in the game between all contributor citizens in the digital economic state.
Bitplanet structures these incentives via the x/brahma module as follows.
Implementation
BPL emissions are minted by the x/mint module (cosmos-sdk standard) and sent to the x/distribution module. The x/brahma module siphons a configurable percentage (default 50%) from the distribution module's balance and allocates it to AI participants according to the following mechanism.
Data Structures
// AI is a representation of the state associated with an AI. This object is uniquely identified// + indexed by it's ID. Both the creator + the dApp from which the AI originates is stored in the AI.messageAI {// ID is the identifier of this AIbytesID=1;// Creator is the address of the creator of this AIbytescreator=2;// DAppAddress is the address of the DApp from which this AI creation occured.bytesdAppAddress=3;// RollingAvgMarketCap is a rolling avg. (maintained as a rolling window) of the total market-cap of// this AI's gemsrepeateduint64rolling_avg_market_cap=4; }
AI
The AI data-structure will be populated each time a new AI is created, as indicated by an incoming RequestForCore. The creator will be updated with the address for which the Create action is attributed in the RequestForCore. The DAppAddress will be set to the address associated with the AppID of the RequestForCore
State Transitions
BeginBlock
The x/brahma module will interact with the x/mint's inflation as follows.
// BeginBlock siphons a percentage of newly minted tokens from the distribution module
// and distributes them to AI participants based on market cap
func (k *Keeper) BeginBlock(ctx sdk.Context) error {
// Get configurable parameters (default: creator=40%, dApp=20%, contributor=40%, siphon=50%)
creatorSplit, _ := k.GetCreatorSplit(ctx)
dAppSplit, _ := k.GetDappSplit(ctx)
contributorSplit, _ := k.GetContributorSplit(ctx)
siphonPercentage, _ := k.GetSiphonPercentage(ctx)
// Determine % of rewards to allocate per AI based on market cap
aiToSplitOfRewards := k.SplitInflationPerAI(ctx)
if len(aiToSplitOfRewards) == 0 {
return nil // No AIs to distribute to
}
// Get balance from distribution module
distributionBalance := k.bankKeeper.GetAllBalances(ctx, distributionModuleAccount.GetAddress())
// Calculate amount to siphon for AI rewards (default 50%)
toSiphon := distributionBalance.Mul(siphonPercentage).TruncateInt()
// Transfer siphoned amount to brahma module
k.bankKeeper.SendCoinsFromModuleToAccount(ctx, distributiontypes.ModuleName, brahmaModuleAccount, siphonedCoins)
// For each AI, allocate to creator, dApp, and contributors
for aiID, proportion := range aiToSplitOfRewards {
ai, _ := k.GetAI(ctx, aiID)
toAllocateForAI := toSiphon.Mul(proportion)
// Allocate using configurable splits
k.AllocateToCreator(ctx, toAllocateForAI.Mul(creatorSplit), ai)
k.AllocateToDApp(ctx, toAllocateForAI.Mul(dAppSplit), ai)
k.AllocateToContributors(ctx, toAllocateForAI.Mul(contributorSplit), ai)
}
}
// SplitInflationPerAI determines % of siphoned rewards to allocate per AI based on
// market cap. This method:
// - Queries the gem ERC1155 totalSupply for each AI to get current market cap
// - Maintains a rolling window of market cap observations (MaxMarketCapHistorySize entries)
// - Calculates average market cap from the rolling window
// - Determines each AI's proportion of total market cap across all AIs
func (k Keeper) SplitInflationPerAI(ctx sdk.Context) map[string]math.LegacyDec
// AllocateToCreator allocates rewards to ai.Creator (added to claimable balance)
func (k Keeper) AllocateToCreator(ctx sdk.Context, coinsToAllocate math.LegacyDec, ai AI) error
// AllocateToDApp allocates rewards to ai.DappAddress (added to claimable balance)
func (k Keeper) AllocateToDApp(ctx sdk.Context, coinsToAllocate math.LegacyDec, ai AI) error
// AllocateToContributors allocates rewards to all contributors based on their Core holdings:
// - Iterates through all AITensors for this AI across tracked block heights
// - Tallies total Cores minted for the AI (totalCoresForAI)
// - For each contributor, determines their Core allocation (totalCoresPerContributor)
// - Allocates: (totalCoresPerContributor / totalCoresForAI) * coinsToAllocate
func (k Keeper) AllocateToContributors(ctx sdk.Context, coinsToAllocate math.LegacyDec, ai AI) error