|
@@ -0,0 +1,111 @@
|
|
|
+--- tokenomics
|
|
|
+-- @module tokenomics
|
|
|
+
|
|
|
+local tokenomics = {
|
|
|
+ name = "Tokenomics",
|
|
|
+ slug = "tokenomics",
|
|
|
+ desc = "A simple library for token economics",
|
|
|
+ hide = true;
|
|
|
+}
|
|
|
+
|
|
|
+--- (Required) Data for module
|
|
|
+-- Variables that module uses during the course of a process
|
|
|
+-- Can be blank
|
|
|
+tokenomics.data = {
|
|
|
+}
|
|
|
+
|
|
|
+--- (Required): config for module
|
|
|
+-- @field consent Require consent to create?
|
|
|
+-- @field token_variables the data that goes into the token
|
|
|
+-- @field token_slug A no-spaces slug for the token
|
|
|
+-- @field initial_treasury Quantity in org treasury
|
|
|
+-- @field negative_spend Boolean: can users spend negative tokens? (for mutual credit)
|
|
|
+-- @field balances Table of user balances
|
|
|
+tokenomics.config = {
|
|
|
+ consent = false,
|
|
|
+ token_slug = "token",
|
|
|
+ token_variables = {
|
|
|
+ treasury = 0,
|
|
|
+ negative_spend = true,
|
|
|
+ balances = {}
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+--- (Required): initiate function: creates a token in an org
|
|
|
+-- set up the token data structure
|
|
|
+-- create an org treasury
|
|
|
+-- @param result (optional) Callback if this module is embedded in other modules
|
|
|
+-- @function initiate
|
|
|
+function tokenomics:initiate(result)
|
|
|
+ -- TODO need to create a series of interactions to get the info from users
|
|
|
+ if self.org.tokens and self.org.tokens[slug] then
|
|
|
+ modpol.interactions.message(
|
|
|
+ self.initiator, "Token slug taken, aborting")
|
|
|
+ self.org:delete_process(self.id)
|
|
|
+ else
|
|
|
+ if self.config.consent then
|
|
|
+ -- TODO consent process, calling create_token
|
|
|
+ else
|
|
|
+ self:create_token()
|
|
|
+ end
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+function tokenomics:create_token()
|
|
|
+ if not self.org.tokens then self.org.tokens = {} end
|
|
|
+ self.org.tokens[slug] = self.config.token_variables
|
|
|
+ modpol.interactions.message_org(
|
|
|
+ self.initiator, self.org.id,
|
|
|
+ "Token "..self.config.token_slug.." created")
|
|
|
+ -- TODO need to add to persistent storage?
|
|
|
+ if result then result() end
|
|
|
+ -- call this wherever process might end:
|
|
|
+ self.org:delete_process(self.id)
|
|
|
+end
|
|
|
+
|
|
|
+-----------------------------------------
|
|
|
+-- Utility functions
|
|
|
+-- all need to account for the fact that some users may not yet have balances
|
|
|
+-- all need to write to persistent data
|
|
|
+-- amount can be positive or negative (except transfer)
|
|
|
+
|
|
|
+-- returns balance
|
|
|
+-- if no user, get treasury balance
|
|
|
+-- @field org Name (string) or id (num)
|
|
|
+-- @field token Slug (string)
|
|
|
+-- @field user Name (string)
|
|
|
+function tokenomics.balance(org, token, user)
|
|
|
+ local this_org = modpol.orgs.get_org(org)
|
|
|
+ if not this_org[token] then return nil, "Token not found" end
|
|
|
+ if not user then
|
|
|
+ return this_org[token].treasury
|
|
|
+ end
|
|
|
+ if not this_org[user] then
|
|
|
+ return nil, "User not found"
|
|
|
+ else
|
|
|
+ local user_balance = this_org[token].balances[user]
|
|
|
+ if user_balance then
|
|
|
+ return user_balance
|
|
|
+ else
|
|
|
+ return 0
|
|
|
+ end
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+function tokenomics.change_balance(org, token, user, amount)
|
|
|
+end
|
|
|
+
|
|
|
+function tokenomics.transfer(org, token, sender, recipient, amount)
|
|
|
+end
|
|
|
+
|
|
|
+function tokenomics.treasury_transfer(org, token, recipient, amount)
|
|
|
+end
|
|
|
+
|
|
|
+-- creates new tokens in the org treasury
|
|
|
+function tokenomics.issue(org, token, amount)
|
|
|
+end
|
|
|
+
|
|
|
+------------------------------------------
|
|
|
+
|
|
|
+--- (Required) Add to module table
|
|
|
+modpol.modules.tokenomics = tokenomics
|