Browse Source

Filled out tokenomics functions; still not tested

Nathan Schneider 2 years ago
parent
commit
0c59767ef7
2 changed files with 100 additions and 10 deletions
  1. 1 1
      modpol_core/modules/remove_org_consent.lua
  2. 99 9
      modpol_core/modules/tokenomics.lua

+ 1 - 1
modpol_core/modules/remove_org_consent.lua

@@ -31,7 +31,7 @@ function remove_org_consent:initiate(result)
            prompt = "Remove org " .. self.org.name .. "?",
            votes_required = #self.org.members
         },
-        function ()
+        function()
            self:complete()
         end
       )

+ 99 - 9
modpol_core/modules/tokenomics.lua

@@ -12,6 +12,7 @@ local tokenomics = {
 -- Variables that module uses during the course of a process
 -- Can be blank
 tokenomics.data = {
+   result = nil
 }
 
 --- (Required): config for module 
@@ -38,13 +39,24 @@ tokenomics.config = {
 -- @function initiate
 function tokenomics:initiate(result)
    -- TODO need to create a series of interactions to get the info from users
+   self.data.result = result
    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
+         self.org:call_module(
+            "consent",
+            self.initiator,
+            {
+               prompt = "Create token "..self.token_slug.."?",
+               votes_required = #self.org.members
+            },
+            function()
+               self:create_token()
+            end
+         )
       else
          self:create_token()
       end
@@ -58,7 +70,7 @@ function tokenomics:create_token()
       self.initiator, self.org.id,
       "Token "..self.config.token_slug.." created")
       -- TODO need to add to persistent storage?
-   if result then result() end
+   if self.data.result then self.data.result() end
    -- call this wherever process might end:
    self.org:delete_process(self.id)
 end
@@ -71,9 +83,9 @@ end
 
 -- returns balance
 -- if no user, get treasury balance
--- @field org Name (string) or id (num)
--- @field token Slug (string)
--- @field user Name (string)
+-- @param org Name (string) or id (num)
+-- @param token Slug (string)
+-- @param 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
@@ -92,21 +104,99 @@ function tokenomics.balance(org, token, user)
    end
 end
 
+-- @param org Org name (string) or id (number)
+-- @param token Token slug (string)
 function tokenomics.change_balance(org, token, user, amount)
-   self.org:record("Changed token balance",self.slug)
+   local this_org = modpol.orgs.get_org(org)
+   if not this_org then
+      return nil, "Cannot change balance: Org not found"
+   elseif not this_org.tokens then
+      return nil, "Cannot change balance: no tokens found"
+   elseif not this_org.tokens[token] then
+      return nil, "Cannot change balance: token not found"
+   elseif not this_org.members[user] then
+      return nil, "Cannot change balance: user not in org"
+   elseif not tonumber(amount) then
+      return nil, "Cannot change balance: invalid amount"
+   else
+      local old_balance = this_org.tokens[token].balances[user]
+      if not old_balance then old_balance = 0 end
+      local new_balance = old_balance + amount
+      this_org.tokens[token].balances[user] = new_balance
+      local msg = "Your balance of token "..token..
+         " changed from "..old_balance.." to "..new_balance
+      modpol.interactions.message(user, msg)
+      self.org:record(
+         "Changed token balance for "..user,self.slug)
+   end
 end
 
+-- @param amount Positive number
 function tokenomics.transfer(org, token, sender, recipient, amount)
-   -- use change_balance
+   local sender_balance = tokenomics.balance(org, token, sender)
+   local recipient_balance = tokenomics.balance(org, token, recipient)
+   if not sender_balance or recipient balance then
+      return nil, "Transfer failed, user not found"
+   else
+      sender_balance = sender_balance - amount
+      recipient_balance = recipient_balance + amount
+      local neg_spend = modpol.orgs.get_org(org).tokens[token].negative_spend
+      if sender_balance < 0 and not neg_spend then
+         return nil, "Transfer failed, negative spend not allowed"
+      else
+         tokenomics.change_balance(
+            org, token, sender, sender_balance)
+         tokenomics.change_balance(
+            org, token, recipient, recipient_balance)
+         return "Transfer complete"
+      end
+   end
 end
 
+-- @param amount Can be positive or negative, assumes flow from treasury to recipient
 function tokenomics.treasury_transfer(org, token, recipient, amount)
-   -- use change_balance
+   local this_org = modpol.orgs.get_org(org)
+   if not this_org then
+      return nil, "Cannot transfer treasury: Org not found"
+   elseif not this_org.tokens then
+      return nil, "Cannot transfer treasury: no tokens found"
+   elseif not this_org.tokens[token] then
+      return nil, "Cannot transfer treasury: token not found"
+   elseif not this_org.members[user] then
+      return nil, "Cannot transfer treasury: user not in org"
+   elseif not tonumber(amount) then
+      return nil, "Cannot change balance: invalid amount"
+   else
+      local new_treasury = this_org.tokens[token].treasury - amount
+      local new_recipient_balance = tokenomics.balance(org, token, recipient) + amount
+      if new_treasury < 0 and not this_org.tokens[token].negative_spend then
+         return nil, "Transfer failed, negative spend not allowed"
+      elseif new_recipient_balance < 0 and not this_org.tokens[token].negative_spend then
+         return nil, "Transfer failed, negative spend not allowed"
+      else
+         this_org.tokens[token].treasury = new_treasury
+         self.org:record("Treasury payment",self.slug)
+         tokenomics.change_balance(org, token, recipient, amount)
+      end
+   end
 end
 
 -- creates new tokens in the org treasury
 function tokenomics.issue(org, token, amount)
-   self.org:record("Issued tokes to treasury",self.slug)
+   local this_org = modpol.orgs.get_org(org)
+   if not this_org then
+      return nil, "Cannot transfer treasury: Org not found"
+   elseif not this_org.tokens then
+      return nil, "Cannot transfer treasury: no tokens found"
+   elseif not this_org.tokens[token] then
+      return nil, "Cannot transfer treasury: token not found"
+   elseif not tonumber(amount) then
+      return nil, "Cannot change balance: invalid amount"
+   else
+      this_org.tokens[token].treasury =
+         this_org.tokens[token].treasury + amount
+      self.org:record("Issued tokes to treasury","tokenomics")
+   end
 end
 
 ------------------------------------------