good proposal that will reduce the entry barrier for new Dapps, helping DAO growth
While I do like most parts of the proposal I do also think youâre trying to solve problems that donât exist and would only lead to more issues.
This proposal will destroy a part of the value of the rare Mjolnir X-Nodes and will encourage buying endorsements points even more.
If you remove the part that requires 3 nodes to support a dapp and a mjolnir van only give 49 points to one dapp you have my vote because with all the other points you are improving the DAO. This specificpoint is not solving any issue. Itâs only creating issues.
If you think a self endorsed app is not acting to support the DAO a proposal can be made to remove the dapp from the DAO as we have proved worked in past. Youâre increasing the entry level for the DAO even more while your initial idea is to actually lower the barrier. Itâs contradicting.
Youâre also deciding for a Mjolnir that he canât put his full trust in a single dapp. Why are Mjolnir X Node holders punished? Let them decide for themselves what they do with their points => that is decentralization. Limiting and adding a bunch of rules is centralizing it.
I agree that underperforming dApps can be removed via proposal, but I think itâs important to recognize how much time, effort, and coordination that takes. Weâve only seen it happen once (GreenCommuter doesnât count), and it required a big push from the community. Thatâs a reactive measure - what this proposal is suggesting is a proactive safeguard.
Right now, dApps can be endorsed extremely easily, by a single node alone. Requiring three different node holders to endorse a dApp builds on the core concept of community consensus. It shouldnât be possible for one person to keep a dApp endorsed indefinitely - that isnât decentralization.
To me, this is less about restricting Mjolnirs and more about empowering the DAO to reflect genuine community support. One strong node should still have major influence, but not the ability to unilaterally decide which projects live or die.
I also recognize thereâs another challenge around paying for endorsement points in the pool, which deserves its own focused discussion at a later date, but if we tackle both of these issues I think it would go a long way toward strengthening the DAOâs fairness and quality.
Yes it happened once. And it didnât require a big push from the community. Once bad behavior is proven - itâs easy to rally up the support from the community - especially with the changes of this week where users will keep their voting power after supporting a proposal. Things already changed for the better.
What I donât understand is that you want a proactive safeguard for something that hasnât even occurred yet. Why?
The endorsement system is not a popularity vote. Itâs to show that dapps have the proper backing, either from community or from their own funds. The popularity vote already happens every week and is used for allocation.
Also - with the removal of the base allocation itâs simply not worth it anymore for a bad actor to self endorse and try to siphon the allocation. The DAO is already well protected against this now and in my opinion doesnât need that extra piece of governance.
More rules != B3TR (pun intended)
What I donât understand is that you want a proactive safeguard for something that hasnât even occurred yet. Why?
This is what proactive safeguards are for - stopping something before it happens.
Currently, Trashdash, Bye Bye Bites and Bite Gram are all endorsed by one single node each. We all know the many issues that each of these dApps have had. They have barely paid out for their submissions, and have only recently began to implement other safety measures. I have yet to discover anyone who genuinely enjoys any of these dApps. I have heard nothing but complaints from the community, yet they are all still endorsed.
The DAO is already well protected against this now and in my opinion doesnât need that extra piece of governance.
In total, these above three dApps have accumulated around 99,000 B3TR. These dApps wouldnât have been on the DAO for as long as they have been if not for their singular endorsers. In the grand scheme of things, this isnât a huge amount of B3TR, but it still shows that there is a flaw in this system that absolutely needs to be addressed.
You mentioned that requiring 3 nodes would cause more issues, but you havenât really talked about what they are except for insinuating that Mjolnir node holders wonât be happy and that you feel this will encourage people to buy more endorsement points. The latter has always been an option and a factor, and can be addressed in a future proposal.
Can you clarify what these issues are? Maybe we can address these issues directly if we know what they are.
I canât comment on those 3 dapps as I know more about them but I hope you can believe me when I say there is a very good and exciting reason for them to be endorsed and why they are not paying out at that much yet.
Believe me - the community will love it.
So just to get it straight. If someone has a budget that allows him to buy a Mjolnir X - that person most likely has the budget to buy other nodes as well to complete their endorsement.
Youâre adding a rule that will add an extra layer of complexity for development => which will cause delays in the overall implementation of the other great points of this proposal.
You will extract value from Mjolnir X holders - who are the biggest supporters of our ecosystem and have so much skin in the game.
Is the proactive safeguard really worth that much to you? Or can you focus on the points that really contribute? Iâve read almost all the comments in this thread and it looks like everyone except the creators of this proposal share the same same sentiment. All your points add value - except for this one.
The point of these guard rails is to add complexity to this dao. We need extra steps before dApps come on. And if a team or company wants to be here, then they shouldnât be excluded from engaging with the community because they can afford not to.
It would be nice to hear from anymore mjolnir xnodes because the intent of this proposal was not to punish them. Thereâs no extracting value because they still have 100 points to endorse many dApps. As weâre seeing, some dApps offer a certain percentage, others offer multipliers within their dApps. Because of this, Iâd say it adds value.
This notion that we are ruining the value of Mjolnir(X) nodes is unfounded. They still have 100 points but now have the ability to spread that to up to 100 different dApps and none of it will be wasted. We are giving these nodes even more value with widespread influence and power across the DAO.
One of the biggest complaints from users on the DAO has been that a random Mjolnir node holder can appear out of nowhere and dictate to the entire community that their chosen dApp is here to stay regardless of whether the rest of the community supports it. And if that dApp is not secure enough, it is incredibly hard to do anything about it. That is not decentralisation by any definition.
You claim this safeguard is for something that hasnât happened yet but it has. Green Commuter had to have their reputation dragged through the mud in order to call it a day. Nubila, even though itâs fine now, was solo endorsed and gathered thousands without a functioning product and even after it was launched it was still broken. We have had the Trash/Bite/ByeBye trio (regardless of their future and I donât love it) do nothing but drain thousands of B3TR, when they should be unendorsed until its sorted. There has been multiple dead or red flag dApps endorsed by one node like Eco Transit, VePets and Planty. These can be avoided in future with this change, protecting the integrity of the DAO.
This is VeBetterDAO, a community, where consensus and cooperation matter between dApps and users alike. Requiring at least 3 node holders to endorse a dApp not only shows the community that there is a better consensus among its endorsers, it removes some of the doubt and negativity that has surrounded the endorsement process for ages. This is sorely needed.
The amount of points in which a node holder endorses with does not reflect their level of trust in a dApp. Each point should represent complete trust or desire to want to see them improve. Giving the node holders the ability to spread their point how they wish within a fair framework is decentralisation. If someone wants to buy another Mjolnir node or 2 to circumvent the limitation, its an even heftier price to pay so I canât see it happening to the extent it is now but wouldnât that also a good thing for the overall ecosystem?
And I absolutely think those points are great and it adds a lot of value that Mjolnirs, and any other Node, can diversify their endorsement points. However, what I donât like is, is removing their choice to fully use it on a single dapp or split it amongst varies applications.
In my opinion, and we can of course disagree on that, dapps shouldnât be at the communities feet to be able to get listed. If we want to repel bad actors, there are other routes to take and ideas to explore. What we need is mass adoption and not more barriers for people outside our ecosystem to join, invest, and get in the DAO.
Capital Unlocked => Amazing and fosters mass adoption
Security Enhanced => Nice catch and needed
Buffer Added => No waste of endorsement points - which is very good
Decentralization Fostered => removes the most beautiful thing in the world: free choice
from the people that are the most invested in our BlockChain, and thatâs why I am not a fan. I understand why you want it, but I just donât think this is the area to do it.
I will leave it now at others to join the discussion
do with it what you want.
I get it and we did consider allowing them to continue to use all 100 on one dApp while retaining a minimum of 3 endorsers, but it would look awkward UX wise and made no real sense to entertain such high numbers. This would have also resulted in a lot of wasted points again that other dApps are desperate for. Their full vote would just be 49 now but essentially mean the same thing besides automatic endorsement.
Iâm sure there must be some Mjolnir node holders that would love to be able to endorse multiple of their favourite dApps. I think its also important to point out that while the VeBetterDAO resides within the Vechainthor blockchain, it is trying to be its own entity. If this was for example to enter the VeWorld itself outside of the DAO I would 100% agree with you. This DAO is an entirely different beast and should be treated as such.
One question: After the upgrade, maybe need to also consider what happen if a node gets upgraded to a higher tier?
Good point! In that case, any points already endorsed with remain with the dapp, and any ânewâ points earnt from the upgrade would be added to the node holderâs pool of available points to endorse with, just like any other unendorsed points.
@BreakingBallz will update the proposal here if possible, else we include it in the one going up for support.
Hello there! Here is a quick recap of the status of the execution of this proposal.
Changes to be performed
-
The single-dApp limit will be removed â Node holders will be able to split their points and distribute them across as many dApps as they wish.
-
If a node holder wishes to withdraw support, they can choose exactly how many points to remove.
-
A single node holder can use up to 49 endorsement points of their 100 total per dApp.
-
a cap of 110 total endorsement points per dApp will be implemented. The requirement for a dApp to be successfully endorsed remains at 100 points.
-
A one-time migration to update all the current endorsements
Blockers
Before even looking in how to execute this solution, the VeBetter core team would like to address an important issue/blocker regarding the following change: âOnly withdrawn points enter cooldown, not the entire nodeâs balanceâ.
Cooldown means that once a node endorse an app, it cannot switch endorsement for at least 1 week. This process was introduced to avoid endorsers to jump from one app to another and be able to âkeep aliveâ 2 or 3 apps at the same time, thanks to the âin grace periodâ taking 2 weeks.
The issue now is that with this new system, where an endorser can split his points and use on many apps, there is no way to track each single point (when it entered cooldown and when it ends) since the point is not a non fungible entity (aka: something that is not replaceable or interchangeable with another object of the same type, because it is unique; like an NFT with its own id) but just a number/counter. From our initial analysis, we were not able to find a scalable way to achieve cooldown on single points.
For this reason, we propose to remove such feature completely.
Implementation
This proposal impacts many functionalities, including smart contract changes, migration strategy and simulation, and frontend changes. For this reason, another more in-depth analysis is required which, with our current capacity and the current amount of work in progress, we are not able to perform immediately.
By our initial analysis we can see that, apart from the migration script and its simulation, heavy changes will be required in the X2EarnApps contract and the Check Endorsement Lambda. Finally, many changes will be required on the VeBetter dashboard to align with the new implementation.
X2EarnApps state changes
Current:
mapping(uint256 => bytes32) nodeToEndorsedApp; // Node can only endorse 1 app
mapping(bytes32 => uint256) appEndorsementScore; // Total score per app
New State Required:
// Track how many points each node has allocated to each app
mapping(uint256 nodeId => mapping(bytes32 appId => uint256 points)) nodeToAppEndorsement;
// Track total points used by a node across all apps
mapping(uint256 nodeId => uint256 totalPointsUsed) nodeTotalEndorsement;
// Track total endorsement points per app (keep existing but update logic)
mapping(bytes32 => uint256) appEndorsementScore;
// Track which nodes are endorsing each app (for iteration)
mapping(bytes32 appId => uint256[] nodeIds) appToEndorsingNodes;
// Track node index in appToEndorsingNodes for efficient removal
mapping(bytes32 appId => mapping(uint256 nodeId => uint256 index)) nodeIndexInAppEndorsers;
// New constants
uint256 public constant MAX_POINTS_PER_NODE_PER_APP = 49;
uint256 public constant MAX_TOTAL_ENDORSEMENT_POINTS = 110;
uint256 public constant ENDORSEMENT_THRESHOLD = 100; // Already exists
New functionality
Apart from updating the endorse() and unendorse() setters to support an additional points value, a new set of helper functions may be required, such as:
// Get all apps a node is endorsing
function getNodeEndorsedApps(uint256 nodeId) external view returns (bytes32[] memory);
// Get how many points a node has allocated to a specific app
function getNodePointsForApp(uint256 nodeId, bytes32 appId) external view returns (uint256);
// Get how many total points a node has used
function getNodeTotalPointsUsed(uint256 nodeId) external view returns (uint256);
// Get available points for a node
function getNodeAvailablePoints(uint256 nodeId) external view returns (uint256);
// Get all nodes endorsing an app with their point allocations
function getAppEndorsementBreakdown(bytes32 appId) external view returns (
uint256[] memory nodeIds,
uint256[] memory points
);
// Check if adding points would exceed caps
function canEndorseWithPoints(bytes32 appId, uint256 nodeId, uint256 points) external view returns (bool);
The outcome of those changes could also impact the currently emitted events, which means that all the indexers and products interacting with them will need to align as well.
Check Endorsement Process
Because of the nature of how smart contracts work and how Stargate NFTs work we periodically need to trigger a function in the X2EarnApps smart contract to check if the endorsement of such apps is still valid or if anything changed, for example a user unstaked and the NFT was burned.
Example of checks performed for each app
// Need to iterate through all endorsing nodes
// Check if node still exists
// Recalculate app's total score
// Check if app crosses threshold (100)
We need to be sure that this function will be scalable after all the changes since an app could have 110 nodes each endorsing with 1 point, creating out of gas issues.
Possible issues
To summarize, the following are a few concern we are currently having and that we will be able to give an answer, to some, only during implementation time, and that could lengthen the time of execution of this proposal.
-
Storage size: X2EarnApps contract is currently at 20.085 KiB (solidity limit is 25)
-
Check endorsement could exceed gas limits
-
Cooldown system with points
-
Proportional migration maths: we need to check the migration strategy very deeply, since we could have rounding errors and potentially we may need to manually manipulate some data
More updates will be given with our next iteration of the analysis. Would be nice to receive a feedback on the cooldown issue we exposed.
Thanks for all of that @Dan
Just a clarifier:
When talking about skipping the cooldown change, youâre talking specifically about each point having an internal cooldown, rather than the node, and not the entire system of splitting points up from the node itself, right?
We have briefly discussed this amongst the 4 of us who wrote the proposal but need a bit more time to come to a conclusive answer, so I just wanted this clarity first.
Sorry for the long delay in getting a response.
Yes, I meant âeach point having an internal cooldownâ, this is not technically doable.
It is easy with current system because itâs an atomic thing, so we add cooldown to the entire nft (and points have nothing to do with this since itâs âall or nothingâ). If we keep the same functionality it means it will add a cooldown on each operation with that node, which is not a great ux. But adding points in cooldown seems also a very difficult task to handle.
And we also really have to think on how to best optimize all of this because the contract size is already almost full (23/24 KiB), so this implementation will be a very delicate.
Hi Dan,
Thank you and the rest of the team for trying to figure this out. As Hayabusa is rolling out, weâre ready to keep pushing to make sure this proposal actually gets implemented.
Regarding the cool-down, we canât scrap splitting up the endorsement points. Itâs half the purpose of this proposal. Because of this, if the only way that this is possible is to keep the cool-down mechanism as it stands, then it would be something endorsers would have to accept. They still get the freedom of splitting their points, which we feel is a net positive.
For the contract size, weâre open to hearing what the team suggests. Could setting tiers or groups of endorsement points an endorser can use per dApp help ease the burden on the contract size? There would be some other things to consider if it could be an alternative, but not sure if it would help.
Thanks again
@Dan Have there been any status updates for this proposal?
thanks
Hi.
Bad news: I had to took over since the developer working on this is not working for vechain anymore, which means that I had to start the work over, since I was missing some context.
Good news: it seems like to me that I may have found a workaround on how to handle cool down and other points that were unclear. Proceeding with the development now.
Will keep you updated.
Hi everyone, Iâm finalizing the smart contract, which will have the changes you can read below.
Before finalizing the PR though, I would like to touch again about the cooldown discussion.
Here Proposal: Unlocking Endorsement Capital to Foster Growth and Protecting the VebetterDAO ecosystem - #58 by BreakingBallz we were saying that we could avoid the cooldown, because of the implementation difficulty it has.
In my PR though, I implemented a system where the cooldown is applied per endorsement per app, eg: I endorse cleanify with 10 points â those 10 points go into cooldown and I cannot unendorse; After 2 days I add 10 more points to cleanify â the cooldown is reset and now I have 20 points in cooldown.
After the cooldown passes and I unendorse, no cooldown is applied to those unendorsed points, and I can use them to endorse again.
I just want to be sure that the community is aligned with this decision, because the last thing we want is to have to create another proposal 1 month for now to change this logic again.
Iâll leave here the comment and wait for a few days for responses, otherwise I will try to implement the best solution I have.
Below you can see other changes to the contracts (those are more useful to other devs that integrate vebetter).
| Feature | Before (V7) | After (V8) |
|---|---|---|
| Endorsement | All-or-nothing (100% of node points) | Partial (specify points) |
| Apps per node | 1 | Unlimited (within limits) |
| Cooldown | Per node | Per app endorsement |
| Max per node per app | Unlimited | 49 points |
| Max per app | Unlimited | 110 points |
| Threshold | 100 points | 100 points (unchanged) |
Breaking Changes
1. Function Signatures Changed
Removed:
function endorseApp(bytes32 appId, uint256 nodeId) external;
function unendorseApp(bytes32 appId, uint256 nodeId) external;
Added:
function endorseApp(bytes32 appId, uint256 nodeId, uint256 points) external;
function unendorseApp(bytes32 appId, uint256 nodeId, uint256 points) external;
2. Functions Removed (No Replacement)
Removed:
// Was: returns single endorsed app, but nodes can now endorse multiple apps
function nodeToEndorsedApp(uint256 nodeId) external view returns (bytes32);
// Was: checks if node is in cooldown, but cooldown is now per-app-endorsement
function checkCooldown(uint256 nodeId) external view returns (bool);
Replacements:
nodeToEndorsedApp(nodeId)â UsegetNodeActiveEndorsements(nodeId)to get all endorsementscheckCooldown(nodeId)â UsecanUnendorse(nodeId, appId)for per-app cooldown check
3. Cooldown Model Changed
Before: Cooldown was per-node. After un-endorsing, the entire node was locked.
After: Cooldown is per-app-endorsement. When you endorse an app, those points are locked for the cooldown period. You cannot unendorse until cooldown expires.
4. Event Changes
Removed:
event AppEndorsed(bytes32 indexed appId, uint256 indexed nodeId, bool isNew);
Added:
event AppEndorsed(bytes32 indexed appId, uint256 indexed nodeId, address endorser, uint256 points);
event AppUnendorsed(bytes32 indexed appId, uint256 indexed nodeId, uint256 points);
event EndorsementsPausedUpdated(bool paused);
New Features
1. Partial Endorsements
Nodes can now split their points across multiple apps:
// Endorse cleanify with 49 points
x2EarnApps.endorseApp(cleanifyId, nodeId, 49);
// Endorse mugshot with 30 points
x2EarnApps.endorseApp(mugshotId, nodeId, 30);
// Remaining 21 points still available
2. Increase Endorsement
You can add more points to an existing endorsement (resets cooldown):
// Already endorsed with 20 points, add 10 more
x2EarnApps.endorseApp(cleanifyId, nodeId, 10);
// Now endorsing with 30 points, cooldown reset
3. Partial Un-endorsement
Remove specific points from an endorsement:
// Remove 10 points from cleanify (after cooldown)
x2EarnApps.unendorseApp(cleanifyId, nodeId, 10);
4. New Query Functions
// Get available points for a node
function getNodeAvailablePoints(uint256 nodeId) external view returns (uint256);
// Get all active endorsements for a node
function getNodeActiveEndorsements(uint256 nodeId) external view returns (Endorsement[] memory);
// Get all node IDs endorsing an app
function getEndorserNodes(bytes32 appId) external view returns (uint256[] memory);
// Check if can unendorse (cooldown expired)
function canUnendorse(uint256 nodeId, bytes32 appId) external view returns (bool);
// Get current caps
function maxPointsPerNodePerApp() external view returns (uint256);
function maxPointsPerApp() external view returns (uint256);
Integration Guide
For dApp Developers
- Update any calls to
endorseApp()andunendorseApp()to includepointsparameter - Use
canUnendorse()to check cooldown before attempting to unendorse - Use
getNodeAvailablePoints()to show users how many points they can allocate - Handle new errors in your UI
For Indexers/Analytics
- Update event listeners for new
AppEndorsedsignature (now includesendorseraddress andpoints) - Track
pointsfield in endorsement events - New events:
AppUnendorsed,EndorsementsPausedUpdated - Migration uses standard
AppEndorsedevent - no special handling needed
Example: Endorsing with the new system
// Before (V7)
await x2EarnApps.endorseApp(appId, nodeId);
// After (V8)
const pointsToEndorse = 49; // max per app
await x2EarnApps.endorseApp(appId, nodeId, pointsToEndorse);
Example: Checking available points
const available = await x2EarnApps.getNodeAvailablePoints(nodeId);
const maxPerApp = await x2EarnApps.maxPointsPerNodePerApp();
const pointsToUse = Math.min(available, maxPerApp);
PS: Work is still in progress, frontend still needs to be aligned to support such feature; same for our indexer.
Hi Dan!
Great news. Gonna talk this over with other community members. Thanks so much for the hard work. It seems like the original intention of the proposal has been saved.
Will reply in a day or two.