Merge pull request #1196 from Luis-Fernando-Molina/develop

Contribution: Refactoring Claims Program
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2021-06-22 08:15:46 -04:00
commit e5d3e2872c
7 files changed
+298 -117

No files matched your search

@@ -287,7 +287,7 @@
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"isCollapsed": true,
"angleToParent": 1,
"distanceToParent": 3,
"arrangementStyle": 0
@@ -313,7 +313,7 @@
{
"type": "Feature Claims Folder",
"name": "Data Mining Feature Class",
"config": "{}",
"config": "{\n \"percentage\": 70\n}",
"project": "Governance",
"featureClaimsFolders": [],
"featureContributionClaims": [
@@ -325,12 +325,12 @@
"id": "edf1a5c9-7802-4856-918c-3cd5a7a9caf7",
"savedPayload": {
"position": {
"x": 30339.990954013265,
"y": 24468.938639855496
"x": 30718.661945753065,
"y": 24284.862061411382
},
"targetPosition": {
"x": 30197.830355271366,
"y": 24204.759980298473
"x": 30463.457926046864,
"y": 24127.15693046823
},
"floatingObject": {
"isPinned": false,
@@ -352,12 +352,12 @@
"id": "ebad23ed-1a02-4edf-a9d7-fc4b2fd0dacb",
"savedPayload": {
"position": {
"x": 30197.830355271366,
"y": 24204.759980298473
"x": 30463.457926046864,
"y": 24127.15693046823
},
"targetPosition": {
"x": 30055.669756529467,
"y": 23940.58132074145
"x": 30208.253906340662,
"y": 23969.45179952508
},
"floatingObject": {
"isPinned": false,
@@ -387,12 +387,12 @@
"id": "e745f3cd-4cd9-421b-b9ab-f62650fb56f8",
"savedPayload": {
"position": {
"x": 30015.399776784172,
"y": 24237.866249271832
"x": 30322.02154513654,
"y": 24247.043089667277
},
"targetPosition": {
"x": 30055.669756529467,
"y": 23940.58132074145
"x": 30208.253906340662,
"y": 23969.45179952508
},
"floatingObject": {
"isPinned": false,
@@ -422,12 +422,12 @@
"id": "3ae7f0f9-be37-4e6c-b3b1-4343e51f80a9",
"savedPayload": {
"position": {
"x": 29848.350961833406,
"y": 24157.419779889668
"x": 30137.12979302601,
"y": 24260.89881101294
},
"targetPosition": {
"x": 30055.669756529467,
"y": 23940.58132074145
"x": 30208.253906340662,
"y": 23969.45179952508
},
"floatingObject": {
"isPinned": false,
@@ -457,12 +457,12 @@
"id": "d8ab7844-f98f-4ce1-a634-c0ff98af28ca",
"savedPayload": {
"position": {
"x": 29760.490879949877,
"y": 23994.148389181042
"x": 29979.405034781983,
"y": 24163.431679889818
},
"targetPosition": {
"x": 30055.669756529467,
"y": 23940.58132074145
"x": 30208.253906340662,
"y": 23969.45179952508
},
"floatingObject": {
"isPinned": false,
@@ -487,8 +487,8 @@
"id": "f8a482c4-dee0-475a-831b-7514fd255ba6",
"savedPayload": {
"position": {
"x": 30055.669756529467,
"y": 23940.58132074145
"x": 30208.253906340662,
"y": 23969.45179952508
},
"targetPosition": {
"x": 30185.834878264734,
@@ -498,7 +498,7 @@
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 1,
"angleToParent": 2,
"distanceToParent": 3,
"arrangementStyle": 0
},
@@ -514,6 +514,31 @@
}
],
"positionClaimsFolders": [],
"tokensAwarded": {
"type": "Tokens Awarded",
"name": "New Tokens Awarded",
"project": "Governance",
"id": "5011109c-3f87-471a-b786-5fd371f53853",
"savedPayload": {
"position": {
"x": 29937.963245969935,
"y": 23839.28667778981
},
"targetPosition": {
"x": 30185.834878264734,
"y": 23670.290660370723
},
"floatingObject": {
"isPinned": false,
"isFrozen": false,
"isCollapsed": false,
"angleToParent": 2,
"distanceToParent": 3,
"arrangementStyle": 0
},
"uiObject": {}
}
},
"id": "796dd30f-c90d-4b8d-a63d-89867347407b",
"savedPayload": {
"position": {
@@ -30,7 +30,7 @@ function newGovernanceActionSwitch() {
}
case 'Install Missing Claims':
{
UI.projects.governance.functionLibraries.claims.installMissingClaims(action.node, action.rootNodes)
UI.projects.governance.functionLibraries.claimsProgram.installMissingClaims(action.node, action.rootNodes)
break
}
case 'Build Profile':
@@ -1,4 +1,4 @@
function newGovernanceFunctionLibraryClaims() {
function newGovernanceFunctionLibraryClaimsProgram() {
let thisObject = {
calculate: calculate,
installMissingClaims: installMissingClaims
@@ -31,19 +31,30 @@ function newGovernanceFunctionLibraryClaims() {
resetClaims(positionsNode)
}
/* Reset this Program */
for (let i = 0; i < userProfiles.length; i++) {
let userProfile = userProfiles[i]
if (userProfile.tokenPowerSwitch === undefined) { continue }
if (userProfile.tokenPowerSwitch.claimsProgram === undefined) { continue }
if (userProfile.tokenPowerSwitch.claimsProgram.payload === undefined) { continue }
resetProgram(userProfile.tokenPowerSwitch.claimsProgram)
}
/* Claim Count Follows */
for (let i = 0; i < userProfiles.length; i++) {
let userProfile = userProfiles[i]
if (userProfile.payload === undefined) { continue }
if (userProfile.tokenPowerSwitch === undefined) { continue }
if (userProfile.tokenPowerSwitch.claimsProgram === undefined) { continue }
userProfile.payload.claims = {
userProfile.payload.claimsProgram = {
awarded: {
tokens: 0
},
count: 0
}
countForNode(userProfile.tokenPowerSwitch.claimsProgram)
countProgram(userProfile.tokenPowerSwitch.claimsProgram)
}
/* Claim Calculation Follows */
@@ -52,7 +63,7 @@ function newGovernanceFunctionLibraryClaims() {
if (userProfile.payload === undefined) { continue }
if (userProfile.tokenPowerSwitch === undefined) { continue }
if (userProfile.tokenPowerSwitch.claimsProgram === undefined) { continue }
calculateForNode(userProfile.tokenPowerSwitch.claimsProgram, userProfile)
distributeProgram(userProfile.tokenPowerSwitch.claimsProgram, userProfile)
}
function resetClaims(node) {
@@ -65,7 +76,7 @@ function newGovernanceFunctionLibraryClaims() {
node.type !== 'Position Class'
) {
if (node.payload.votes !== undefined) {
node.payload.claims = {
node.payload.claimsProgram = {
count: 0,
votes: 0
}
@@ -99,44 +110,19 @@ function newGovernanceFunctionLibraryClaims() {
}
}
function countForNode(node) {
function resetProgram(node) {
if (node === undefined) { return }
if (node.payload === undefined) { return }
if (
node.type !== 'Asset Claims Folder' &&
node.type !== 'Feature Claims Folder' &&
node.type !== 'Position Claims Folder' &&
node.type !== 'Claims Program'
) {
if (node.payload.claims === undefined) {
node.payload.claims = {
count: 0,
awarded: {
tokens: 0,
percentage: 0
},
share: {
count: 0,
percentage: 0
}
}
}
if (
node.payload.votes !== undefined &&
node.payload.votes > 0 &&
node.payload.referenceParent !== undefined &&
node.payload.referenceParent.payload !== undefined &&
node.payload.referenceParent.payload.votes !== undefined &&
node.payload.referenceParent.payload.votes > 0 &&
node.payload.referenceParent.payload.weight !== undefined &&
node.payload.referenceParent.payload.weight > 0 &&
node.payload.referenceParent.payload.claims.count !== undefined &&
node.payload.referenceParent.payload.claims.votes !== undefined
) {
node.payload.referenceParent.payload.claims.count++
node.payload.referenceParent.payload.claims.votes = node.payload.referenceParent.payload.claims.votes + node.payload.votes
node.payload.claimsProgram = {
count: 0,
awarded: {
tokens: 0,
percentage: 0
},
share: {
count: 0,
percentage: 0
}
}
@@ -149,7 +135,7 @@ function newGovernanceFunctionLibraryClaims() {
switch (property.type) {
case 'node': {
let childNode = node[property.name]
countForNode(childNode)
resetProgram(childNode)
}
break
case 'array': {
@@ -157,7 +143,7 @@ function newGovernanceFunctionLibraryClaims() {
if (propertyArray !== undefined) {
for (let m = 0; m < propertyArray.length; m++) {
let childNode = propertyArray[m]
countForNode(childNode)
resetProgram(childNode)
}
}
break
@@ -167,7 +153,7 @@ function newGovernanceFunctionLibraryClaims() {
}
}
function calculateForNode(node, userProfile) {
function countProgram(node) {
if (node === undefined) { return }
if (node.payload === undefined) { return }
@@ -178,7 +164,6 @@ function newGovernanceFunctionLibraryClaims() {
node.type !== 'Claims Program'
) {
if (
node.payload.claims !== undefined &&
node.payload.votes !== undefined &&
node.payload.votes > 0 &&
node.payload.referenceParent !== undefined &&
@@ -187,8 +172,83 @@ function newGovernanceFunctionLibraryClaims() {
node.payload.referenceParent.payload.votes > 0 &&
node.payload.referenceParent.payload.weight !== undefined &&
node.payload.referenceParent.payload.weight > 0 &&
node.payload.referenceParent.payload.claims.count !== undefined &&
node.payload.referenceParent.payload.claims.votes !== undefined
node.payload.referenceParent.payload.claimsProgram.count !== undefined &&
node.payload.referenceParent.payload.claimsProgram.votes !== undefined
) {
node.payload.referenceParent.payload.claimsProgram.count++
node.payload.referenceParent.payload.claimsProgram.votes = node.payload.referenceParent.payload.claimsProgram.votes + node.payload.votes
}
}
let schemaDocument = getSchemaDocument(node)
if (schemaDocument === undefined) { return }
if (schemaDocument.childrenNodesProperties !== undefined) {
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
let property = schemaDocument.childrenNodesProperties[i]
switch (property.type) {
case 'node': {
let childNode = node[property.name]
countProgram(childNode)
}
break
case 'array': {
let propertyArray = node[property.name]
if (propertyArray !== undefined) {
for (let m = 0; m < propertyArray.length; m++) {
let childNode = propertyArray[m]
countProgram(childNode)
}
}
break
}
}
}
}
}
function distributeProgram(programNode, userProfile) {
if (programNode === undefined || 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.claimsProgram.ownPower = programPower
distributeProgramPower(programNode, programPower, userProfile)
}
function distributeProgramPower(
node,
programPower,
userProfile,
percentage
) {
if (node === undefined) { return }
if (node.payload === undefined) { return }
if (
node.type !== 'Asset Claims Folder' &&
node.type !== 'Feature Claims Folder' &&
node.type !== 'Position Claims Folder' &&
node.type !== 'Claims Program'
) {
if (
node.payload.claimsProgram !== undefined &&
node.payload.votes !== undefined &&
node.payload.votes > 0 &&
node.payload.referenceParent !== undefined &&
node.payload.referenceParent.payload !== undefined &&
node.payload.referenceParent.payload.votes !== undefined &&
node.payload.referenceParent.payload.votes > 0 &&
node.payload.referenceParent.payload.weight !== undefined &&
node.payload.referenceParent.payload.weight > 0 &&
node.payload.referenceParent.payload.claimsProgram.count !== undefined &&
node.payload.referenceParent.payload.claimsProgram.votes !== undefined
) {
/*
We will use the concept of Vote Reward Claims Ratio for the situation in which the
@@ -196,69 +256,165 @@ function newGovernanceFunctionLibraryClaims() {
the Votes Rewards Claims Ratio will be used to redude the amount of tokens awarded
proportionally to how much was exeeded.
*/
let votesRatio = node.payload.referenceParent.payload.votes / node.payload.referenceParent.payload.claims.votes
let votesRatio = node.payload.referenceParent.payload.votes / node.payload.referenceParent.payload.claimsProgram.votes
if (votesRatio > 1) { votesRatio = 1 }
/*
Share Count means the amount to claims pointing to the same potential tokens reward.
*/
node.payload.claims.share.count = node.payload.referenceParent.payload.claims.count
node.payload.claims.share.percentage = node.payload.votes * 100 / node.payload.referenceParent.payload.claims.votes
node.payload.claims.awarded.tokens =
node.payload.claimsProgram.share.count = node.payload.referenceParent.payload.claimsProgram.count
node.payload.claimsProgram.share.percentage = node.payload.votes * 100 / node.payload.referenceParent.payload.claimsProgram.votes
node.payload.claimsProgram.awarded.tokens =
Math.min(
node.payload.votes / node.payload.referenceParent.payload.votes * node.payload.referenceParent.payload.tokens * votesRatio,
node.payload.votes
)
node.payload.claims.awarded.percentage = node.payload.claims.awarded.tokens / node.payload.referenceParent.payload.tokens * 100
node.payload.claimsProgram.awarded.percentage = node.payload.claimsProgram.awarded.tokens / node.payload.referenceParent.payload.tokens * 100
userProfile.payload.claims.awarded.tokens = userProfile.payload.claims.awarded.tokens + node.payload.claims.awarded.tokens
userProfile.payload.claims.count++
userProfile.payload.claimsProgram.awarded.tokens = userProfile.payload.claimsProgram.awarded.tokens + node.payload.claimsProgram.awarded.tokens
userProfile.payload.claimsProgram.count++
drawClaims(node, userProfile)
drawProgramPower(node, programPower, percentage)
}
} else {
if (node.type === 'Claims Program') {
drawProgram(node)
} else {
drawProgramPower(node, programPower, percentage)
}
}
let schemaDocument = getSchemaDocument(node)
if (schemaDocument === undefined) { return }
if (schemaDocument.childrenNodesProperties !== undefined) {
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
let property = schemaDocument.childrenNodesProperties[i]
switch (property.type) {
case 'node': {
let childNode = node[property.name]
calculateForNode(childNode, userProfile)
if (schemaDocument.childrenNodesProperties === undefined) { return }
/*
Before distributing the claim 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 }
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]
calculateForNode(childNode, userProfile)
}
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 }
let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage')
if (percentage !== undefined && isNaN(percentage) !== true) {
totalPercentage = totalPercentage + percentage
} else {
totalNodesWithoutPercentage++
}
}
break
}
break
}
}
}
if (totalPercentage > 100) {
node.payload.uiObject.setErrorMessage('Claim Power Switching Error. Total Percentage of children nodes is grater that 100.')
return
}
let defaultPercentage = 0
if (totalNodesWithoutPercentage > 0) {
defaultPercentage = (100 - totalPercentage) / totalNodesWithoutPercentage
}
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 }
let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage')
if (percentage === undefined || isNaN(percentage) === true) {
percentage = defaultPercentage
}
distributeProgramPower(childNode, programPower * percentage / 100, userProfile, 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 }
let percentage = UI.projects.foundations.utilities.nodeConfig.loadConfigProperty(childNode.payload, 'percentage')
if (percentage === undefined || isNaN(percentage) === true) {
percentage = defaultPercentage
}
distributeProgramPower(childNode, programPower * percentage / 100, userProfile, percentage)
}
}
break
}
}
}
}
function drawClaims(node, userProfile) {
let satatus =
new Intl.NumberFormat().format(node.payload.claims.awarded.tokens) +
let status =
new Intl.NumberFormat().format(node.payload.claimsProgram.awarded.tokens) +
' ' + 'SA Tokens Awarded' + ' - ' +
'From Reward: ' + node.payload.claims.awarded.percentage.toFixed(2) + '%' + ' - ' +
'Shared Between: ' + node.payload.claims.share.count + ' claims' + ' - ' +
'Share of Claims: ' + node.payload.claims.share.percentage.toFixed(2) + '%'
'From Reward: ' + node.payload.claimsProgram.awarded.percentage.toFixed(2) + '%' + ' - ' +
'Shared Between: ' + node.payload.claimsProgram.share.count + ' claims' + ' - ' +
'Share of Claims: ' + node.payload.claimsProgram.share.percentage.toFixed(2) + '%'
node.payload.uiObject.setStatus(satatus)
node.payload.uiObject.setStatus(status)
}
satatus = new Intl.NumberFormat().format(userProfile.payload.claims.awarded.tokens) +
' ' + 'SA Tokens Awarded' +
' from ' + userProfile.payload.claims.count + ' Claims'
function drawProgram(node) {
if (node.payload !== undefined) {
userProfile.payload.uiObject.setValue(satatus)
const ownPowerText = new Intl.NumberFormat().format(node.payload.claimsProgram.ownPower)
node.payload.uiObject.statusAngleOffset = 0
node.payload.uiObject.statusAtAngle = false
node.payload.uiObject.setStatus(ownPowerText + ' Claims Power')
}
if (node.tokensAwarded !== undefined && node.tokensAwarded.payload !== undefined) {
const tokensAwardedText = new Intl.NumberFormat().format(node.payload.claimsProgram.awarded.tokens)
node.tokensAwarded.payload.uiObject.valueAngleOffset = 0
node.tokensAwarded.payload.uiObject.valueAtAngle = false
node.tokensAwarded.payload.uiObject.setValue(tokensAwardedText + ' SA Tokens')
}
}
function drawProgramPower(node, programPower, percentage) {
const programPowerText = new Intl.NumberFormat().format(programPower) + ' ' + 'Claim Power'
if (node.payload !== undefined) {
node.payload.uiObject.valueAngleOffset = 180
node.payload.uiObject.valueAtAngle = true
node.payload.uiObject.percentageAngleOffset = 180
node.payload.uiObject.percentageAtAngle = true
node.payload.uiObject.setValue(programPowerText)
if (percentage !== undefined) {
node.payload.uiObject.setPercentage(percentage.toFixed(2))
}
}
}
}
@@ -56,7 +56,7 @@ function newGovernanceFunctionLibraryDistributionProcess() {
userProfiles
)
UI.projects.governance.functionLibraries.claims.calculate(
UI.projects.governance.functionLibraries.claimsProgram.calculate(
features,
assets,
positions,
@@ -129,14 +129,14 @@ function newGovernanceFunctionLibraryVotes() {
function distributeVotingProgram(votingProgram) {
if (votingProgram.payload === undefined) { return }
let votes = votingProgram.payload.votes
distributeVotes(votingProgram, votes)
distributeProgramPower(votingProgram, votes)
}
function distributeVotes(node, votes, switchPercentage) {
function distributeProgramPower(node, votes, percentage) {
if (node === undefined) { return }
if (node.payload === undefined) { return }
node.payload.votes = node.payload.votes + votes
drawVotes(node, node.payload.votes, switchPercentage)
drawVotes(node, node.payload.votes, percentage)
/*
When we reach certain node types, we will halt the distribution, because these are targets for
voting power.
@@ -161,7 +161,7 @@ function newGovernanceFunctionLibraryVotes() {
node.type !== 'Weight Votes Switch' &&
node.type !== 'User Profile Votes Switch'
) {
distributeVotes(node.payload.referenceParent, votes)
distributeProgramPower(node.payload.referenceParent, votes)
return
}
/*
@@ -241,7 +241,7 @@ function newGovernanceFunctionLibraryVotes() {
if (percentage === undefined || isNaN(percentage) === true) {
percentage = defaultPercentage
}
distributeVotes(childNode, votes * percentage / 100, percentage)
distributeProgramPower(childNode, votes * percentage / 100, percentage)
}
}
break
@@ -255,7 +255,7 @@ function newGovernanceFunctionLibraryVotes() {
if (percentage === undefined || isNaN(percentage) === true) {
percentage = defaultPercentage
}
distributeVotes(childNode, votes * percentage / 100, percentage)
distributeProgramPower(childNode, votes * percentage / 100, percentage)
}
}
break
@@ -164,8 +164,8 @@ function newFoundationsUtilitiesMandatoryProgram() {
function distributeProgram(programNode) {
if (programNode === undefined || programNode.payload === undefined) { return }
/*
Here we will convert Token Power into programPowerName.
As per system rules programPowerName = tokensPower
Here we will convert Token Power into programPower.
As per system rules programPower = tokensPower
*/
let programPower = programNode.payload.tokenPower
/*
+3 -3
View File
@@ -984,9 +984,9 @@
"functionName": "newGovernanceFunctionLibraryWeights"
},
{
"name": "Claims",
"propertyName": "claims",
"functionName": "newGovernanceFunctionLibraryClaims"
"name": "Claims Program",
"propertyName": "claimsProgram",
"functionName": "newGovernanceFunctionLibraryClaimsProgram"
},
{
"name": "Distribution Process",