From 1cd90530e858ffdb9efad55b11946cc0eafbd6e9 Mon Sep 17 00:00:00 2001 From: Luis Fernando Molina Date: Wed, 18 Aug 2021 22:13:35 +0200 Subject: [PATCH] Governance: Reputation Concept Implemented --- .../UI/Function-Libraries/PluginsFunctions.js | 6 + .../User-Profiles/Luis-Fernando-Molina.json | 132 +++++++++--------- .../UI/Function-Libraries/VotingProgram.js | 45 +++--- Projects/Governance/UI/Globals/SaToken.js | 7 + .../Spaces/User-Profile-Space/UserProfile.js | 44 +++++- Projects/ProjectsSchema.json | 5 + 6 files changed, 153 insertions(+), 86 deletions(-) create mode 100644 Projects/Governance/UI/Globals/SaToken.js diff --git a/Projects/Foundations/UI/Function-Libraries/PluginsFunctions.js b/Projects/Foundations/UI/Function-Libraries/PluginsFunctions.js index 0f952609e..6ea796a76 100644 --- a/Projects/Foundations/UI/Function-Libraries/PluginsFunctions.js +++ b/Projects/Foundations/UI/Function-Libraries/PluginsFunctions.js @@ -215,6 +215,12 @@ function newFoundationsFunctionLibraryPluginsFunctions() { let pluginFolderNode = UI.projects.foundations.utilities.children.findChildByType(pluginProject, pluginForlderNodeType) let pluginFile = UI.projects.foundations.utilities.plugins.addMissingPluginFile(pluginFolderNode, node.name, pluginFolderName, node.type, true) node.isPlugin = true + + if (pluginFile === undefined) { + node.payload.uiObject.setErrorMessage('Plugin Not Saved because it already existed.') + return + } + UI.projects.foundations.utilities.plugins.savePluginFile(pluginFile) } } diff --git a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json index 13e4c12ea..ec67cd93c 100644 --- a/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json +++ b/Projects/Governance/Plugins/User-Profiles/Luis-Fernando-Molina.json @@ -1,7 +1,7 @@ { "type": "User Profile", "name": "Luis-Fernando-Molina", - "config": "{\"tokens\":10000000,\"signature\":{\"message\":\"Luis-Fernando-Molina\",\"messageHash\":\"0x443abf3389e332a62d21b84dd12e271cb428d334195d3aeb986ca85ee53cccb9\",\"v\":\"0x1b\",\"r\":\"0x90293b042c180aa21b05f0356f31688c597be4ff2df136f63a2b8a899c658eb0\",\"s\":\"0x42abf909024d34217430e42ebadc96b7834218cc86a4c295a2ae419ff2fca6e3\",\"signature\":\"0x90293b042c180aa21b05f0356f31688c597be4ff2df136f63a2b8a899c658eb042abf909024d34217430e42ebadc96b7834218cc86a4c295a2ae419ff2fca6e31b\"},\"codeName\":\"Luis-Fernando-Molina\"}", + "config": "{\"signature\":{\"message\":\"Luis-Fernando-Molina\",\"messageHash\":\"0x443abf3389e332a62d21b84dd12e271cb428d334195d3aeb986ca85ee53cccb9\",\"v\":\"0x1c\",\"r\":\"0x8645be85fd4b053c9102194be4d007b79d971ca27acd38a7f6abe2588cb2b1a3\",\"s\":\"0x55c5bff8b6d0a038ef53287fb5feffca4eb7002f521472091a0a0014dea4d23e\",\"signature\":\"0x8645be85fd4b053c9102194be4d007b79d971ca27acd38a7f6abe2588cb2b1a355c5bff8b6d0a038ef53287fb5feffca4eb7002f521472091a0a0014dea4d23e1c\"},\"codeName\":\"Luis-Fernando-Molina\"}", "project": "Governance", "tokenPowerSwitch": { "type": "Token Power Switch", @@ -127,12 +127,12 @@ "id": "f4d39b02-4324-438d-9f74-2bea2b7272ef", "savedPayload": { "position": { - "x": 30558.705098312483, - "y": 23576.33557568774 + "x": 30598.705098312483, + "y": 23595.335575687743 }, "targetPosition": { - "x": 30316, - "y": 23399.999999999996 + "x": 30356, + "y": 23419 }, "floatingObject": { "isPinned": false, @@ -516,12 +516,12 @@ "id": "b6e3c87d-a11b-4b2a-b6a6-edc96375f5da", "savedPayload": { "position": { - "x": 30408.705098312483, - "y": 23685.31695488854 + "x": 30448.705098312483, + "y": 23704.316954888545 }, "targetPosition": { - "x": 30316, - "y": 23399.999999999996 + "x": 30356, + "y": 23419 }, "floatingObject": { "isPinned": false, @@ -599,7 +599,7 @@ "Luis-Fernando-Molina", "User Profile", "Governance", - "148911b3-b2f3-44fb-8cb4-017991789132" + "a8de78f0-c3e4-4a2a-b7e8-f659073969db" ], [ "New Token Power Switch", @@ -682,7 +682,7 @@ "Luis-Fernando-Molina", "User Profile", "Governance", - "148911b3-b2f3-44fb-8cb4-017991789132" + "a8de78f0-c3e4-4a2a-b7e8-f659073969db" ], [ "New Token Power Switch", @@ -733,12 +733,12 @@ "id": "d69739f9-958e-480e-95e3-a72bb5f6ceab", "savedPayload": { "position": { - "x": 30622.604740762366, - "y": 24469.00664000841 + "x": 30662.604740762366, + "y": 24488.006640008414 }, "targetPosition": { - "x": 30421.865558854708, - "y": 24246.063192365193 + "x": 30461.865558854708, + "y": 24265.063192365196 }, "floatingObject": { "isPinned": false, @@ -12866,12 +12866,12 @@ "id": "1d398124-3f36-40a1-8b3b-6c77ad489b92", "savedPayload": { "position": { - "x": 30406.164771981825, - "y": 24545.652052791564 + "x": 30446.164771981825, + "y": 24564.652052791567 }, "targetPosition": { - "x": 30421.865558854708, - "y": 24246.063192365193 + "x": 30461.865558854708, + "y": 24265.063192365196 }, "floatingObject": { "isPinned": false, @@ -12892,12 +12892,12 @@ "id": "2b8d3ce7-515c-44ad-8d80-3c2be6d7736f", "savedPayload": { "position": { - "x": 30421.865558854708, - "y": 24246.063192365193 + "x": 30461.865558854708, + "y": 24265.063192365196 }, "targetPosition": { - "x": 30285.668408932845, - "y": 23978.761235108683 + "x": 30325.668408932845, + "y": 23997.761235108686 }, "floatingObject": { "isPinned": false, @@ -12920,12 +12920,12 @@ "id": "e9c0e495-7985-4381-bf75-865d87289038", "savedPayload": { "position": { - "x": 30269.96762205996, - "y": 24278.350095535054 + "x": 30309.96762205996, + "y": 24297.350095535057 }, "targetPosition": { - "x": 30285.668408932845, - "y": 23978.761235108683 + "x": 30325.668408932845, + "y": 23997.761235108686 }, "floatingObject": { "isPinned": false, @@ -12943,17 +12943,17 @@ "id": "d5ed432e-78bf-432e-be3b-8649932f7a65", "savedPayload": { "position": { - "x": 30285.668408932845, - "y": 23978.761235108683 + "x": 30325.668408932845, + "y": 23997.761235108686 }, "targetPosition": { - "x": 30223.294901687517, - "y": 23685.31695488854 + "x": 30263.294901687517, + "y": 23704.316954888545 }, "floatingObject": { "isPinned": false, "isFrozen": false, - "isCollapsed": true, + "isCollapsed": false, "angleToParent": 2, "distanceToParent": 3, "arrangementStyle": 0 @@ -13300,12 +13300,12 @@ "id": "796dd30f-c90d-4b8d-a63d-89867347407b", "savedPayload": { "position": { - "x": 30000.3514540443, - "y": 23886.0561367962 + "x": 30040.3514540443, + "y": 23905.056136796204 }, "targetPosition": { - "x": 30223.294901687517, - "y": 23685.31695488854 + "x": 30263.294901687517, + "y": 23704.316954888545 }, "floatingObject": { "isPinned": false, @@ -13323,17 +13323,17 @@ "id": "bb390957-b8a2-4a8a-9fbf-963ea20f6eaf", "savedPayload": { "position": { - "x": 30223.294901687517, - "y": 23685.31695488854 + "x": 30263.294901687517, + "y": 23704.316954888545 }, "targetPosition": { - "x": 30316, - "y": 23399.999999999996 + "x": 30356, + "y": 23419 }, "floatingObject": { "isPinned": false, "isFrozen": false, - "isCollapsed": true, + "isCollapsed": false, "angleToParent": 2, "distanceToParent": 3, "arrangementStyle": 0 @@ -13360,12 +13360,12 @@ "id": "928e9ccb-1e90-48a9-af77-b3089225fc4f", "savedPayload": { "position": { - "x": 29866, - "y": 24179.422863405995 + "x": 29829.25291584204, + "y": 24124.4628502733 }, "targetPosition": { - "x": 30016, - "y": 23919.615242270662 + "x": 29951.27390876478, + "y": 23850.39921298052 }, "floatingObject": { "isPinned": false, @@ -13704,17 +13704,17 @@ "id": "4f35322c-3e7d-49f8-9706-10bf71f0d420", "savedPayload": { "position": { - "x": 30073.294901687517, - "y": 23576.33557568774 + "x": 30113.294901687517, + "y": 23595.335575687743 }, "targetPosition": { - "x": 30316, - "y": 23399.999999999996 + "x": 30356, + "y": 23419 }, "floatingObject": { "isPinned": false, "isFrozen": false, - "isCollapsed": false, + "isCollapsed": true, "angleToParent": 2, "distanceToParent": 3, "arrangementStyle": 0 @@ -13727,12 +13727,12 @@ "id": "f8182a9c-f830-4ec1-a238-ac3a5efd69e6", "savedPayload": { "position": { - "x": 30316, - "y": 23399.999999999996 + "x": 30356, + "y": 23419 }, "targetPosition": { - "x": 30316, - "y": 23099.999999999996 + "x": 30356, + "y": 23119 }, "floatingObject": { "isPinned": false, @@ -13751,21 +13751,21 @@ "type": "Tokens Mined", "name": "New Tokens Mined", "project": "Governance", - "id": "ab419614-d76c-4820-ace3-970c8282daa6", + "id": "9870ca2a-cefc-484b-b7fc-206d62782ebc", "savedPayload": { "position": { - "x": 30016, - "y": 23099.999999999996 + "x": 30056, + "y": 23119 }, "targetPosition": { - "x": 30316, - "y": 23099.999999999996 + "x": 30356, + "y": 23119 }, "floatingObject": { "isPinned": false, "isFrozen": false, "isCollapsed": false, - "angleToParent": 2, + "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 }, @@ -13774,21 +13774,21 @@ } } }, - "id": "148911b3-b2f3-44fb-8cb4-017991789132", + "id": "a8de78f0-c3e4-4a2a-b7e8-f659073969db", "savedPayload": { "position": { - "x": 30316, - "y": 23099.999999999996 + "x": 30356, + "y": 23119 }, "targetPosition": { - "x": 30316, - "y": 23099.999999999996 + "x": 30356, + "y": 23119 }, "floatingObject": { "isPinned": false, "isFrozen": false, "isCollapsed": false, - "angleToParent": 2, + "angleToParent": 1, "distanceToParent": 3, "arrangementStyle": 0 }, diff --git a/Projects/Governance/UI/Function-Libraries/VotingProgram.js b/Projects/Governance/UI/Function-Libraries/VotingProgram.js index 8600cfe66..e69bbe127 100644 --- a/Projects/Governance/UI/Function-Libraries/VotingProgram.js +++ b/Projects/Governance/UI/Function-Libraries/VotingProgram.js @@ -59,7 +59,7 @@ function newGovernanceFunctionLibraryVotingProgram() { if (program === undefined) { continue } if (program.payload === undefined) { continue } - distributeProgram(program) + distributeProgram(program, userProfile) } /* Bonus Calculation is here */ @@ -181,24 +181,25 @@ function newGovernanceFunctionLibraryVotingProgram() { } } - function distributeProgram(programNode) { + function distributeProgram(programNode, userProfile) { if (programNode.payload === undefined) { return } /* Transform Token Power into Votes */ - let votes = programNode.payload.tokenPower + let votes = programNode.payload.tokenPower + userProfile.payload.reputation /* Set this initial votes as own power */ programNode.payload.votingProgram.ownPower = votes - distributeProgramPower(programNode, programNode, votes, undefined, 0) + distributeProgramPower(programNode, programNode, votes, undefined, 0, userProfile) function distributeProgramPower( currentProgramNode, node, votes, percentage, - generation + generation, + userProfile ) { if (generation >= MAX_GENERATIONS) { return @@ -212,7 +213,7 @@ function newGovernanceFunctionLibraryVotingProgram() { if (node.type === 'Voting Program') { node.payload.votingProgram.incomingPower = node.payload.votingProgram.votes - node.payload.votingProgram.ownPower } - drawVotes(node, node.payload.votingProgram.votes, percentage) + drawVotes(node, node.payload.votingProgram.votes, percentage, userProfile) /* When we reach certain node types, we will halt the distribution, because these are targets for voting power. @@ -240,7 +241,8 @@ function newGovernanceFunctionLibraryVotingProgram() { node.payload.referenceParent, votes / 10, undefined, - generation + 1 + generation + 1, + userProfile ) } return @@ -254,7 +256,8 @@ function newGovernanceFunctionLibraryVotingProgram() { program, votes, undefined, - generation + generation, + userProfile ) return } @@ -275,7 +278,8 @@ function newGovernanceFunctionLibraryVotingProgram() { node.payload.referenceParent, votes, undefined, - generation + generation, + userProfile ) return } @@ -357,7 +361,8 @@ function newGovernanceFunctionLibraryVotingProgram() { childNode, votes * percentage / 100, percentage, - generation + generation, + userProfile ) } break @@ -377,7 +382,8 @@ function newGovernanceFunctionLibraryVotingProgram() { childNode, votes * percentage / 100, percentage, - generation + generation, + userProfile ) } } @@ -389,7 +395,7 @@ function newGovernanceFunctionLibraryVotingProgram() { } } - function drawVotes(node, votes, percentage) { + function drawVotes(node, votes, percentage, userProfile) { if (node.payload !== undefined) { @@ -397,7 +403,7 @@ function newGovernanceFunctionLibraryVotingProgram() { return } if (node.type === 'Voting Program') { - drawProgram(node) + drawProgram(node, userProfile) if (percentage !== undefined) { node.payload.uiObject.setPercentage(percentage.toFixed(2)) @@ -447,7 +453,7 @@ function newGovernanceFunctionLibraryVotingProgram() { } const votesText = parseFloat(votes.toFixed(0)).toLocaleString('en') + ' ' + voteType - + node.payload.uiObject.valueAngleOffset = 0 node.payload.uiObject.valueAtAngle = true @@ -482,20 +488,21 @@ function newGovernanceFunctionLibraryVotingProgram() { } } - function drawProgram(node) { + function drawProgram(node, userProfile) { if (node.payload === undefined) { return } if (node.payload.votingProgram === undefined) { return } if (node.payload.votingProgram.ownPower === undefined) { return } if (node.payload.votingProgram.incomingPower === undefined) { return } + if (userProfile.payload.reputation === undefined) { return } - const ownPowerText = parseFloat(node.payload.votingProgram.ownPower.toFixed(0)).toLocaleString('en') + const ownPowerText = parseFloat((node.payload.votingProgram.ownPower - userProfile.payload.reputation).toFixed(0)).toLocaleString('en') const incomingPowerText = parseFloat(node.payload.votingProgram.incomingPower.toFixed(0)).toLocaleString('en') + const reputationPowerText = parseFloat(userProfile.payload.reputation.toFixed(0)).toLocaleString('en') node.payload.uiObject.statusAngleOffset = 0 node.payload.uiObject.statusAtAngle = false - node.payload.uiObject.setStatus(ownPowerText + ' Own Power' + ' + ' + incomingPowerText + ' Incoming Voting Power') - + node.payload.uiObject.setStatus(ownPowerText + ' Own Power' + ' + ' + incomingPowerText + ' Incoming Voting Power' + ' + ' + reputationPowerText + ' Reputation Power') } } } @@ -517,7 +524,7 @@ function newGovernanceFunctionLibraryVotingProgram() { ) { originNode.name = destinationNode.name + ' ' + destinationNode.type + ' ' + ' Vote' } else { - originNode.name = destinationNode.name + originNode.name = destinationNode.name } let schemaDocument = getSchemaDocument(destinationNode) diff --git a/Projects/Governance/UI/Globals/SaToken.js b/Projects/Governance/UI/Globals/SaToken.js new file mode 100644 index 000000000..fec31461a --- /dev/null +++ b/Projects/Governance/UI/Globals/SaToken.js @@ -0,0 +1,7 @@ +function newGovernanceGlobalsSaToken() { + let thisObject = { + SA_TOKEN_BSC_CONTRACT_ADDRESS: '0xfb981ed9a92377ca4d75d924b9ca06df163924fd', + SA_TOKEN_BSC_TREASURY_ACCOUNT_ADDRESS: '0x8d4d2557ce99f83f658adf61eef3e61e04c2ac2c' + } + return thisObject +} \ No newline at end of file diff --git a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js index 0166c361a..915e96603 100644 --- a/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js +++ b/Projects/Governance/UI/Spaces/User-Profile-Space/UserProfile.js @@ -24,6 +24,8 @@ function newGovernanceUserProfileSpace() { thisObject.githubWatchers = new Map() thisObject.githubForks = new Map() + let reputationByAddress = new Map() + return thisObject function initialize() { @@ -65,6 +67,45 @@ function newGovernanceUserProfileSpace() { return } + /* + Here we will setup the Reputation for each profile. + */ + timer = timer + 15000 + waitingForResponses++ + getTreasuryAccountTransactions() + + function getTreasuryAccountTransactions() { + const url = "https://api.bscscan.com/api?module=account&action=tokentx&address=" + UI.projects.governance.globals.saToken.SA_TOKEN_BSC_TREASURY_ACCOUNT_ADDRESS + "&startblock=0" + + fetch(url).then(function (response) { + return response.json(); + }).then(function (data) { + + let tokenTransfers = data.result + for (let i = 0; i < tokenTransfers.length; i++) { + let transfer = tokenTransfers[i] + + if (transfer.contractAddress !== UI.projects.governance.globals.saToken.SA_TOKEN_BSC_CONTRACT_ADDRESS) { continue } + if (transfer.from !== UI.projects.governance.globals.saToken.SA_TOKEN_BSC_TREASURY_ACCOUNT_ADDRESS) { continue } + + let currentReputation = Number(transfer.value) / 1000000000000000000 + let previousReputation = reputationByAddress.get(transfer.to) + let newReputation = previousReputation | 0 + currentReputation + reputationByAddress.set(transfer.to, newReputation) + } + if (tokenTransfers.length > 9000) { + console.log('[WARN] The total amount of BSC SA Token transfers is above 9000. After 10k this method will need pagination or otherwise users will not get their reputation calculated correctly.') + } + waitingForResponses-- + }).catch(function (err) { + const message = err.message + ' - ' + 'Can not access BSC SCAN servers.' + console.log(message) + waitingForResponses-- + }); + } + /* + Here we will help setup the Github Programs... + */ requestStars() function requestStars() { @@ -292,7 +333,7 @@ function newGovernanceUserProfileSpace() { function getBlockchainTokens(userProfile, blockchainAccount) { console.log('blockchainAccount ', blockchainAccount) - const url = "https://api.bscscan.com/api?module=account&action=tokenbalance&contractaddress=0xfb981ed9a92377ca4d75d924b9ca06df163924fd&address=" + blockchainAccount + "&tag=latest&apikey=YourApiKeyToken" + const url = "https://api.bscscan.com/api?module=account&action=tokenbalance&contractaddress=" + UI.projects.governance.globals.saToken.SA_TOKEN_BSC_CONTRACT_ADDRESS + "&address=" + blockchainAccount + "&tag=latest&apikey=YourApiKeyToken" fetch(url).then(function (response) { return response.json(); @@ -300,6 +341,7 @@ function newGovernanceUserProfileSpace() { console.log(data) userProfile.payload.uiObject.setInfoMessage(data) userProfile.payload.blockchainTokens = Number(data.result) / 1000000000000000000 + userProfile.payload.reputation = Math.min(reputationByAddress.get(blockchainAccount.toLowerCase()) | 0, userProfile.payload.blockchainTokens) waitingForResponses-- }).catch(function (err) { const message = err.message + ' - ' + 'Can not access BSC SCAN servers.' diff --git a/Projects/ProjectsSchema.json b/Projects/ProjectsSchema.json index 69eb196d4..35f199398 100644 --- a/Projects/ProjectsSchema.json +++ b/Projects/ProjectsSchema.json @@ -1065,6 +1065,11 @@ "name": "Reports", "propertyName": "reports", "functionName": "newGovernanceGlobalsReports" + }, + { + "name": "SA Token", + "propertyName": "saToken", + "functionName": "newGovernanceGlobalsSaToken" } ], "functionLibraries": [