From 0de05a853299641bdf379ae5d4d96c1793ff31e9 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Thu, 24 Jun 2021 15:05:31 +0200 Subject: [PATCH] Delegation Program Implemented --- .../Icons/Programs/delegation-program.png | Bin 0 -> 8071 bytes .../claim-votes-switch.png | Bin .../delegate-power-switch.png} | Bin .../{ => Switches}/token-power-switch.png | Bin .../user-profile-votes-switch.png | Bin .../{Votes => Switches}/votes-switch.png | Bin .../weight-votes-switch.png | Bin .../Governance/Icons/User/user-delegate.png | Bin 0 -> 1942 bytes .../Governance/Plugins/Pools/Superalgos.json | 20 +- .../Plugins/User-Profiles/Julian-Molina.json | 8 +- .../User-Profiles/Luis-Fernando-Molina.json | 436 +++++++++++++----- .../App-Schema/delegate-power-switch.json | 62 +++ .../App-Schema/delegation-program.json | 64 +++ .../App-Schema/token-power-switch.json | 15 + .../Schemas/App-Schema/user-delegate.json | 40 ++ .../user-vote-transfer.json | 2 +- .../Function-Libraries/DelegationProgram.js | 229 +++++++++ .../Function-Libraries/DistributionProcess.js | 5 + .../UI/Function-Libraries/VotingProgram.js | 40 +- Projects/ProjectsSchema.json | 5 + 20 files changed, 774 insertions(+), 152 deletions(-) create mode 100644 Projects/Governance/Icons/Programs/delegation-program.png rename Projects/Governance/Icons/{Votes => Switches}/claim-votes-switch.png (100%) rename Projects/Governance/Icons/{Votes/votes-distribution.png => Switches/delegate-power-switch.png} (100%) rename Projects/Governance/Icons/{ => Switches}/token-power-switch.png (100%) rename Projects/Governance/Icons/{Votes => Switches}/user-profile-votes-switch.png (100%) rename Projects/Governance/Icons/{Votes => Switches}/votes-switch.png (100%) rename Projects/Governance/Icons/{Votes => Switches}/weight-votes-switch.png (100%) create mode 100644 Projects/Governance/Icons/User/user-delegate.png create mode 100644 Projects/Governance/Schemas/App-Schema/delegate-power-switch.json create mode 100644 Projects/Governance/Schemas/App-Schema/delegation-program.json create mode 100644 Projects/Governance/Schemas/App-Schema/user-delegate.json create mode 100644 Projects/Governance/UI/Function-Libraries/DelegationProgram.js diff --git a/Projects/Governance/Icons/Programs/delegation-program.png b/Projects/Governance/Icons/Programs/delegation-program.png new file mode 100644 index 0000000000000000000000000000000000000000..9b3b41696452be84f1f39c1a00a502acdec773d9 GIT binary patch literal 8071 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 Power Switch->Delegation Program->" + }, + "propertyNameAtParent": "delegatePowerSwitch", + "childrenNodesProperties": [ + { + "name": "delegatePowerSwitch", + "type": "array", + "childType": "Delegate Power Switch", + "autoAdd": false + }, + { + "name": "userDelegates", + "type": "array", + "childType": "User Delegate", + "autoAdd": false + } + ] +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/delegation-program.json b/Projects/Governance/Schemas/App-Schema/delegation-program.json new file mode 100644 index 000000000..d5db7615c --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/delegation-program.json @@ -0,0 +1,64 @@ +{ + "type": "Delegation Program", + "menuItems": [ + { + "action": "Configure", + "actionFunction": "uiObject.configEditor.activate", + "label": "Configure", + "iconPathOn": "configuration", + "iconPathOff": "configuration" + }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "actionFunction": "payload.executeAction", + "label": "Add Delegate Power Switch", + "relatedUiObject": "Delegate Power Switch" + }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "tokensBonus", + "actionFunction": "payload.executeAction", + "label": "Add Tokens Bonus", + "relatedUiObject": "Tokens Bonus" + }, + { + "action": "Delete UI Object", + "actionProject": "Foundations", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "editors": { + "config": true + }, + "initialValues": { + "config": "{}" + }, + "attachingRules": { + "compatibleTypes": "->Token Power Switch->" + }, + "addLeftIcons": true, + "level": 1, + "propertyNameAtParent": "delegationProgram", + "childrenNodesProperties": [ + { + "name": "delegatePowerSwitch", + "type": "array", + "childType": "Delegate Power Switch", + "autoAdd": false + }, + { + "name": "tokensBonus", + "type": "node", + "childType": "Tokens Bonus", + "autoAdd": true + } + ] +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/token-power-switch.json b/Projects/Governance/Schemas/App-Schema/token-power-switch.json index 323b15701..a06248a63 100644 --- a/Projects/Governance/Schemas/App-Schema/token-power-switch.json +++ b/Projects/Governance/Schemas/App-Schema/token-power-switch.json @@ -62,6 +62,15 @@ "label": "Add Staking Program", "relatedUiObject": "Staking Program" }, + { + "action": "Add UI Object", + "actionProject": "Foundations", + "actionFunction": "payload.executeAction", + "disableIfPropertyIsDefined": true, + "propertyToCheckFor": "delegationProgram", + "label": "Add Delegation Program", + "relatedUiObject": "Delegation Program" + }, { "action": "Delete UI Object", "actionProject": "Foundations", @@ -121,6 +130,12 @@ "type": "node", "childType": "Staking Program", "autoAdd": true + }, + { + "name": "delegationProgram", + "type": "node", + "childType": "Delegation Program", + "autoAdd": true } ] } \ No newline at end of file diff --git a/Projects/Governance/Schemas/App-Schema/user-delegate.json b/Projects/Governance/Schemas/App-Schema/user-delegate.json new file mode 100644 index 000000000..fbf5c964a --- /dev/null +++ b/Projects/Governance/Schemas/App-Schema/user-delegate.json @@ -0,0 +1,40 @@ +{ + "type": "User Delegate", + "menuItems": [ + { + "action": "Configure", + "actionFunction": "uiObject.configEditor.activate", + "label": "Configure", + "iconPathOn": "configuration", + "iconPathOff": "configuration" + }, + { + "action": "Delete UI Object", + "actionProject": "Foundations", + "askConfirmation": true, + "confirmationLabel": "Confirm to Delete", + "label": "Delete", + "iconPathOn": "delete-entity", + "iconPathOff": "delete-entity", + "actionFunction": "payload.executeAction" + } + ], + "title": [ + "Use Reference Parent" + ], + "editors": { + "config": true + }, + "initialValues": { + "config": "{}" + }, + "addLeftIcons": true, + "level": 2, + "attachingRules": { + "compatibleTypes": "->Delegating Power Switch->" + }, + "referencingRules": { + "compatibleTypes": "->User Profile->" + }, + "propertyNameAtParent": "userDelegates" +} \ No newline at end of file diff --git a/Projects/Governance/Schemas/Docs-Nodes/U/User/User-Vote-Transfer/user-vote-transfer.json b/Projects/Governance/Schemas/Docs-Nodes/U/User/User-Vote-Transfer/user-vote-transfer.json index f4c0b3929..0084e1129 100644 --- a/Projects/Governance/Schemas/Docs-Nodes/U/User/User-Vote-Transfer/user-vote-transfer.json +++ b/Projects/Governance/Schemas/Docs-Nodes/U/User/User-Vote-Transfer/user-vote-transfer.json @@ -1,7 +1,7 @@ { "type": "User Profile Vote", "definition": { - "text": "This node allows users to transfer some of their voting power to other users, effectively creating a Liquid Democracy. Votes received by users are then flowed through the recipient user's token streams, increasing their size.", + "text": "This node allows users to transfer some of their voting power to other users, effectively creating a Delegation. Votes received by users are then flowed through the recipient user's token streams, increasing their size.", "updated": 1622989097099 }, "paragraphs": [ diff --git a/Projects/Governance/UI/Function-Libraries/DelegationProgram.js b/Projects/Governance/UI/Function-Libraries/DelegationProgram.js new file mode 100644 index 000000000..30c288612 --- /dev/null +++ b/Projects/Governance/UI/Function-Libraries/DelegationProgram.js @@ -0,0 +1,229 @@ +function newGovernanceFunctionLibraryDelegationProgram() { + let thisObject = { + calculate: calculate + } + + return thisObject + + function calculate( + pools, + userProfiles + ) { + + /* Bonus Calculation is here */ + UI.projects.governance.utilities.bonusProgram.run( + pools, + userProfiles, + "delegationProgram", + "Liquid-Democracy-Bonus" + ) + /* + We will first reset all the delegate power, and then distribute it. + */ + for (let i = 0; i < userProfiles.length; i++) { + let userProfile = userProfiles[i] + + if (userProfile.tokenPowerSwitch === undefined) { continue } + if (userProfile.tokenPowerSwitch.delegationProgram === undefined) { continue } + if (userProfile.tokenPowerSwitch.delegationProgram.payload === undefined) { continue } + + resetProgram(userProfile.tokenPowerSwitch.delegationProgram) + } + for (let i = 0; i < userProfiles.length; i++) { + let userProfile = userProfiles[i] + + if (userProfile.tokenPowerSwitch === undefined) { continue } + if (userProfile.tokenPowerSwitch.delegationProgram === undefined) { continue } + if (userProfile.tokenPowerSwitch.delegationProgram.payload === undefined) { continue } + + userProfile.tokenPowerSwitch.delegationProgram.payload.delegationProgram.programPower = userProfile.tokenPowerSwitch.delegationProgram.payload.tokenPower + + distributeProgram(userProfile.tokenPowerSwitch.delegationProgram) + } + + function resetProgram(programNode) { + if (programNode === undefined) { return } + if (programNode.payload === undefined) { return } + programNode.payload.delegationProgram = { + programPower: 0, + ownPower: 0 + } + } + + function distributeProgram(programNode) { + if (programNode.payload === undefined) { return } + + /* + Here we will convert Token Power into programPower. + As per system rules programPower = tokensPower + */ + let programPower = programNode.payload.tokenPower + /* + The Own Power is the power generated by the same User Profile tokens, not inherited from others. + */ + programNode.payload.delegationProgram.ownPower = programPower + distributeProgramPower(programNode, programPower) + } + + function distributeProgramPower(node, programPower, percentage) { + if (node === undefined) { return } + if (node.payload === undefined) { return } + if (node.payload.delegationProgram === undefined) {return} + + node.payload.delegationProgram.programPower = node.payload.delegationProgram.programPower + programPower + drawPower(node, node.payload.delegationProgram.programPower, percentage) + /* + When we reach certain node types, we will halt the distribution, because these are targets for + delegate power. + */ + if ( + node.type === 'User Profile' + ) { return } + /* + If there is a reference parent defined, this means that the delegate power is + transfered to it and not distributed among children. + */ + if ( + node.payload.referenceParent !== undefined && + node.type === 'User Delegate' + ) { + distributeProgramPower(node.payload.referenceParent, programPower) + return + } + /* + If there is no reference parent we will redistribute delegate power among children. + */ + let schemaDocument = getSchemaDocument(node) + if (schemaDocument === undefined) { return } + + if (schemaDocument.childrenNodesProperties !== undefined) { + /* + Before distributing the delegate power, we will calculate how the power + is going to be switched between all nodes. The first pass is about + scanning all sibling nodes to see which ones have a percentage defined + at their config, and check that all percentages don't add more than 100. + */ + let totalPercentage = 0 + let totalNodesWithoutPercentage = 0 + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + let property = schemaDocument.childrenNodesProperties[i] + + switch (property.type) { + case 'node': { + let childNode = node[property.name] + if (childNode === undefined) { continue } + if (childNode.type === 'Tokens Bonus') { continue } + let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') + if (percentage !== undefined && isNaN(percentage) !== true) { + totalPercentage = totalPercentage + percentage + } else { + totalNodesWithoutPercentage++ + } + } + break + case 'array': { + let propertyArray = node[property.name] + if (propertyArray !== undefined) { + for (let m = 0; m < propertyArray.length; m++) { + let childNode = propertyArray[m] + if (childNode === undefined) { continue } + if (childNode.type === 'Tokens Bonus') { continue } + let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') + if (percentage !== undefined && isNaN(percentage) !== true) { + totalPercentage = totalPercentage + percentage + } else { + totalNodesWithoutPercentage++ + } + } + } + break + } + } + } + if (totalPercentage > 100) { + node.payload.uiObject.setErrorMessage('Delegate Power Switching Error. Total Percentage of children nodes is grater that 100.') + return + } + let defaultPercentage = 0 + if (totalNodesWithoutPercentage > 0) { + defaultPercentage = (100 - totalPercentage) / totalNodesWithoutPercentage + } + /* + Here we do the actual distribution. + */ + for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { + let property = schemaDocument.childrenNodesProperties[i] + + switch (property.type) { + case 'node': { + let childNode = node[property.name] + if (childNode === undefined) { continue } + if (childNode.type === 'Tokens Bonus') { continue } + let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') + if (percentage === undefined || isNaN(percentage) === true) { + percentage = defaultPercentage + } + distributeProgramPower(childNode, programPower * percentage / 100, percentage) + } + break + case 'array': { + let propertyArray = node[property.name] + if (propertyArray !== undefined) { + for (let m = 0; m < propertyArray.length; m++) { + let childNode = propertyArray[m] + if (childNode === undefined) { continue } + if (childNode.type === 'Tokens Bonus') { continue } + let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') + if (percentage === undefined || isNaN(percentage) === true) { + percentage = defaultPercentage + } + distributeProgramPower(childNode, programPower * percentage / 100, percentage) + } + } + break + } + } + } + } + } + + function drawPower(node, programPower, percentage) { + + if (node.payload !== undefined) { + + if (node.type === 'Delegation Program') { + drawProgram(node) + + if (percentage !== undefined) { + node.payload.uiObject.setPercentage(percentage.toFixed(2)) + } + return + } + node.payload.uiObject.valueAngleOffset = 180 + node.payload.uiObject.valueAtAngle = true + node.payload.uiObject.percentageAngleOffset = 180 + node.payload.uiObject.percentageAtAngle = true + let voteType = 'Delegate Power' + + const programPowerText = parseFloat(programPower.toFixed(2)).toLocaleString('en') + ' ' + voteType + node.payload.uiObject.setValue(programPowerText) + + if (percentage !== undefined) { + node.payload.uiObject.setPercentage(percentage.toFixed(2)) + } + } + + function drawProgram(node) { + if (node.payload !== undefined) { + + const ownPowerText = parseFloat(node.payload.delegationProgram.ownPower.toFixed(2)).toLocaleString('en') + + node.payload.uiObject.statusAngleOffset = 0 + node.payload.uiObject.statusAtAngle = false + + node.payload.uiObject.setStatus(ownPowerText + ' Delegate Power') + } + } + } + } +} \ No newline at end of file diff --git a/Projects/Governance/UI/Function-Libraries/DistributionProcess.js b/Projects/Governance/UI/Function-Libraries/DistributionProcess.js index c279ceab2..8fd6d33a7 100644 --- a/Projects/Governance/UI/Function-Libraries/DistributionProcess.js +++ b/Projects/Governance/UI/Function-Libraries/DistributionProcess.js @@ -17,6 +17,11 @@ function newGovernanceFunctionLibraryDistributionProcess() { userProfiles ) + UI.projects.governance.functionLibraries.delegationProgram.calculate( + pools, + userProfiles + ) + UI.projects.governance.functionLibraries.votingProgram.calculate( pools, features, diff --git a/Projects/Governance/UI/Function-Libraries/VotingProgram.js b/Projects/Governance/UI/Function-Libraries/VotingProgram.js index 9a23718e0..73d3f52da 100644 --- a/Projects/Governance/UI/Function-Libraries/VotingProgram.js +++ b/Projects/Governance/UI/Function-Libraries/VotingProgram.js @@ -148,6 +148,8 @@ function newGovernanceFunctionLibraryVotingProgram() { function distributeProgramPower(node, votes, percentage) { if (node === undefined) { return } if (node.payload === undefined) { return } + if (node.payload.votingProgram === undefined) {return} + node.payload.votingProgram.votes = node.payload.votingProgram.votes + votes drawVotes(node, node.payload.votingProgram.votes, percentage) /* @@ -195,19 +197,16 @@ function newGovernanceFunctionLibraryVotingProgram() { for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { let property = schemaDocument.childrenNodesProperties[i] - if (node.type === 'User Profile' && property.name !== "votingProgram") { continue } - switch (property.type) { case 'node': { - if (node.type === 'User Profile' && property.name === "votingProgram") { - let childNode = node[property.name] - if (childNode === undefined) { continue } - let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') - if (percentage !== undefined && isNaN(percentage) !== true) { - totalPercentage = totalPercentage + percentage - } else { - totalNodesWithoutPercentage++ - } + let childNode = node[property.name] + if (childNode === undefined) { continue } + if (childNode.type === 'Tokens Bonus') { continue } + let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') + if (percentage !== undefined && isNaN(percentage) !== true) { + totalPercentage = totalPercentage + percentage + } else { + totalNodesWithoutPercentage++ } } break @@ -217,6 +216,7 @@ function newGovernanceFunctionLibraryVotingProgram() { for (let m = 0; m < propertyArray.length; m++) { let childNode = propertyArray[m] if (childNode === undefined) { continue } + if (childNode.type === 'Tokens Bonus') { continue } let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') if (percentage !== undefined && isNaN(percentage) !== true) { totalPercentage = totalPercentage + percentage @@ -243,19 +243,16 @@ function newGovernanceFunctionLibraryVotingProgram() { for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) { let property = schemaDocument.childrenNodesProperties[i] - if (node.type === 'User Profile' && property.name !== "votingProgram") { continue } - switch (property.type) { case 'node': { - if (node.type === 'User Profile' && property.name === "votingProgram") { - let childNode = node[property.name] - if (childNode === undefined) { continue } - let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') - if (percentage === undefined || isNaN(percentage) === true) { - percentage = defaultPercentage - } - distributeProgramPower(childNode, votes * percentage / 100, percentage) + let childNode = node[property.name] + if (childNode === undefined) { continue } + if (childNode.type === 'Tokens Bonus') { continue } + let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') + if (percentage === undefined || isNaN(percentage) === true) { + percentage = defaultPercentage } + distributeProgramPower(childNode, votes * percentage / 100, percentage) } break case 'array': { @@ -264,6 +261,7 @@ function newGovernanceFunctionLibraryVotingProgram() { for (let m = 0; m < propertyArray.length; m++) { let childNode = propertyArray[m] if (childNode === undefined) { continue } + if (childNode.type === 'Tokens Bonus') { continue } let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage') if (percentage === undefined || isNaN(percentage) === true) { percentage = defaultPercentage diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json index 9a134882c..fa8be55b1 100644 --- a/Projects/ProjectsSchema.json +++ b/Projects/ProjectsSchema.json @@ -973,6 +973,11 @@ "propertyName": "votingProgram", "functionName": "newGovernanceFunctionLibraryVotingProgram" }, + { + "name": "Delegation Program", + "propertyName": "delegationProgram", + "functionName": "newGovernanceFunctionLibraryDelegationProgram" + }, { "name": "Tokens", "propertyName": "tokens",