Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Address: 0x5ef79995FE8a89e0812330E4378eB2660ceDe699
B3TR is the incentive token of VeBetter. Its functions include:
General incentive token for VeBetter, including VeBetter Treasury Management
Value carrier and monetization mechanism for active participants and innovative enterprise models
Incentive token for sustainability applications
Back VOT3 tokens 1:1, the token required for VeBetter governance
The total supply of B3TR is capped at 1,000,000,000 tokens, with a weekly issuance schedule carried out over 12 years.
Address: 0x76Ca782B59C74d088C7D2Cce2f211BC00836c602
VOT3 is the governance token of VeBetter. Its functions include:
Required to take part in governance
Convertible, 1:1 between B3TR and VOT3
You can convert back and forth between B3TR and VOT3 whenever you want, with the only limitation that you cannot convert VOT3 tokens sent to you by other wallets into B3TR, just the amount you originally converted.
The parameters related to emissions are adjustable; however, modifying them without careful consideration could negatively impact the overall emissions. It is crucial to maintain these settings as stable as possible.
Our DAO has multiple roles, each with its admin powers, which presents a potential vector for attack. We acknowledge this risk and have implemented best practices for securing the private keys associated with these roles. These measures are crucial in protecting our system from unauthorized access and potential security breaches.
We are committed to gradually transitioning to a fully decentralized system. This transition aims to reduce the reliance on centralized admin powers, thereby enhancing the security and robustness of our governance structure. The move towards decentralization is a deliberate process to ensure stability and maintain trust as we shift control from centralized figures to the DAO members.
The pool’s purpose is to finance sustainable apps that join the VeBetter ecosystem. The purpose of the apps is to use those tokens to reward and incentivize sustainable actions through their applications.
Distribution of B3TR from the x-allocation pool to the apps happens in cycles, which we will refer to from now on as rounds. Each round will last 1 week, and funds will be distributed once the round ends.
Apps receive B3TR tokens based on the support that they receive from the VOT3 holders through voting.
All unallocated funds of that round are sent to the Treasury contract.
You have two testing environments: testnet and an instance of the blockchain running locally (a ).
Testing your app on testnet is more straightforward since all contracts are already deployed by us and you can use our testnet dApp to add apps, interact with smart contracts, and manage reward distribution.
Testing on solo will be a bit more complicated because you will need to deploy some mocked VeBetter contracts by yourself, but we tried to make that easy as well.
Use our testnet environment, running on vechain testnet network, to create apps, interact with smart contracts, and manage reward distribution.
This ruleBook is a proposal based application, to protect the sustainability and fairness of the ecosystem.
To preserve fair distribution of weekly allocation and prevent gaming of the system, the following are prohibited for any App seeking or receiving B3TR incentives. For more context, please refer to this update:
Apps must not use their own rewards to incentivize behaviors already directly compensated by protocol-level Vote2Earn incentives (e.g., proposal voting). Rewarding user to
To enhance the transparency of the VeBetter platform and x2earn apps, following also the , we have developed a centralized reward distributor contract. This contract must be used by the apps to ensure that every transfer of a B3TR token related to a sustainable action is publicly tracked and accessible to the community.
You need to call this contract to distribute the rewards.
The Personhood Check refers to a function provided by the contract to determine whether a particular wallet belongs to a real person or not.
The contracts currently calling this function are those related to governance voting in VeBetter, such as XallocationVoting and B3TRGovernor. When this function is called, the VePassport contract checks the following criteria:
If the address (representing the user) has delegated their passport, their personhood is not considered, meaning they will not be regarded as a person;
If the address is whitelisted, it will be considered a person;
To better increase the interoperability across the VeBetter ecosystem VePassport offers the possibility to link multiple addresses under a single passport. All sustainable actions performed with the linked accounts will help increment the score of the passport and better represent your onchain identity.
A passport is the primary identity of the user (often a user's main VeWorld Wallet), and entities are additional wallet addresses that a user can attach to their passport. Users can link multiple entities (e.g., hardware wallets, account abstraction wallets, regular wallets) to a single passport. Once an entity is attached, its interactions, scores, and other attributes (e.g. whitelisted, bot signals etc.) are aggregated into the passport, reflecting the combined activity.
Currently, there is a limitation of a maximum of 5 entities per passport.
When linking a wallet, the scores are not immediately transferred. Instead, once the link is established, all of the linker’s scores, from the time of the link, are credited to the linked account. After the wallet addresses are linked, only the main account — the passport address — retains the right to vote.
Every app receives B3TR from weekly allocation rounds in a contract called X2EarnRewardsPool and those rewards are now configurable by the app admin. In fact, you can split allocated tokens between distributable rewards pool for your user and a treasury pool, withdrawal for operational needs. You also have the possibility to pause distribution anytime, this won't affect the reward pool unless you move funds to the app balance.
This dual-pool mechanism allows you to have more control over your distribution funds.
You can manage these configurations directly from the app admin dashboard in the VeBetter app. Or by interacting with our X2EarnRewardsPool contract.
Only the app admin can set this
The black-and-white list functions provide the DAO, or other trusted projects, a mechanism to blacklist or whitelist certain accounts. For example, certain accounts may not have a way to prove they are legitimate other than being whitelisted. On the flip side we can use the blacklist to block all known Sybil accounts providing a strong deterrent for this type of behavior.
Other apps or contracts can interact with this module through the following functions of the VePassport contract:
Apps must not reward users for interacting with another incentivized App when:
The action is already subject to B3TR allocation.
The behavior results in redundant compensation for the same activity.
This includes:
Wrapping or mirroring existing Apps to farm additional incentives.
Stacking reward layers for a single on-chain action.
Reciprocal arrangements between Apps that loop rewards for shared behaviors.
Splitting functionalities into multiple Apps for the purpose of inflating total allocations is not allowed. Interdependent or co-deployed Apps may be evaluated as a unit.
Rewarding users for promoting, relaying, or proxying already-incentivized actions (e.g., vote sharing or vote proxying) is disallowed if the base action is already rewarded by the protocol.
TLDR;
Rewarding users beyond the App action-based incentives is strictly prohibited.
No extra rewards for actions already incentivized by VeBetter are allowed.
Ownership of a GM NFT with a level above Earth should be sufficient to prove personhood. The capital outlay to achieve these NFTs should be enough to discourage their usage in Sybil attacks and prove the investment deployed for better action to VeBetter.
The GM ownership is snapshotted at the beginning of each round to prevent potential attacks.
If the address is blacklisted, they will not be considered a person;
If an address has been flagged multiple times by one or more apps as a bot or as an account involved in a Sybil attack, it will not be considered a person;
If the address has used apps enough in previous rounds, or in the current one, to exceed the participation threshold, they will be considered a person;
If the user holds a GM NFT with a level of 2 or higher, they will be considered a person;
If none of the above happens, the user will not be considered a person.
Not all of the previously listed checks are enabled. Those checks can be enabled or disabled as desired, and currently, only the delegation and Proof of Participation checks are enabled.
At the moment the checks can be enabled by the VeBetter team, but in the future, this option will also be open to the DAO itself.
The rules governing how this method works can be adjusted over time.
In addition to determining whether a wallet is considered a person at the current moment, it is also possible to verify if a wallet is considered a person at a specific block in the past. This function is particularly used by the governance contracts of VeBetter during voting, where it checks if a user was considered a person at the start of the round.
Not all checks support this functionality though. Currently only the Delegation and Proof of Investment support this. All other checks, such as whitelisting, blacklisting, bot signaling, and participation, are analyzed based on the current block.
interface IVeBetterPassport {
...
function whitelist(address _user) external;
function isWhitelisted(address _user) external view returns (bool);
function removeFromWhitelist(address _user) external;
function blacklist(address _user) external;
function isBlacklisted(address _user) external view returns (bool);
function removeFromBlacklist(address _user) external;
...
} interface IVeBetterPassport {
...
function linkEntityToPassportWithSignature(address entity, uint256 deadline, bytes memory signature) external;
function linkEntityToPassport(address passport) external;
function acceptEntityLink(address entity) external;
function removeEntityLink(address entity) external;
function denyIncomingPendingEntityLink(address entity) external;
function cancelOutgoingPendingEntityLink() external;
function isPassport(address user) external view returns (bool);
function isPassportInTimepoint(address user, uint256 timepoint) external view returns (bool);
function isEntity(address user) external view returns (bool);
function isEntityInTimepoint(address user, uint256 timepoint) external view returns (bool);
...
}interface IVeBetterPassport {
...
function isPerson(address user) external view returns (bool person, string memory reason);
function isPersonAtTimepoint(
address user,
uint48 timepoint
) external view returns (bool person, string memory reason)
...
}Voting Token: The token used for voting is VOT3.
Voting Frequency: Each round of voting lasts one week, though this period could change in the future.
Voting Eligibility: To be able to vote, users must be verified as real persons. Each user needs to prove they have completed 3 better actions within the last 12 rounds. These actions are subject to decay over time. A "better action" is defined as receiving a reward from an app for performing a sustainability-related activity. Learn more here.
Votes Snapshot: The VOT3 holdings and better action are snapshotted at the start of each round. VOT3 tokens acquired and better action done after that moment won't be considered when casting the vote.
Voting Flexibility: Within each round, users can vote only once but have the flexibility to allocate their votes among multiple apps. For example, a user with 100 VOT3 might assign 30 VOT3 to app #1, 20 VOT3 to app #2, and 50 VOT3 to app #3.
Resetting Votes: At the beginning of each round, all previous votes are reset, requiring users to cast their votes again. This design encourages the community to return and vote regularly, hence the introduction of a "vote-2-earn" mechanism, where users are rewarded for voting.
Allocation Shares: At the end of each round, the smart contract calculates the ranking and determines the distribution of funds among the apps.
Quorum Requirements: To ensure broad community involvement, each round must meet a specific quorum to validate the results. If the quorum is not reached, the distribution still occurs but is based on the percentages from the last valid round.
Each emission distribution starts a new allocation round for x2earn applications.
At the start of each round, a snapshot of the VOT3 holdings is made. This snapshot includes both the token held in their wallet balance and any tokens they have deposited to support proposals (if applicable).
There can be only two possible outcomes of a round: it succeeds or fails. To succeed the only requirement is that the quorum, which is currently 1% of total VOT3 supply, is reached.
A user can cast his votes only when the round is active and only one time per round, by passing an array of x-application IDs and the fraction of votes he wants to allocate to each.
Allocation Structure: The distribution from the X-Allocation Pool to the apps is:
100% based on the percentage of votes each app receives since Monday 19th 2025 proposal execution.
Cap on Allocation: To prevent any one project from dominating, there's a cap on how much each app can receive from the 70% pool. This cap ensures that at least six projects participate in the voting each week.
Redistribution: Any leftover funds from the X-Allocation Pool will be sent to the Treasury and can be redistributed through DAO voting.
Both the minimum and maximum caps can be changed by the governance.
When the quorum is not reached during an allocation voting round, it can impact the distribution process. Let's assume we have 2 rounds, where the first one succeeded and the second one did not, here is how it would work:
Total Funding for Current Round: The total amount for distribution is derived from the current round, regardless of what happened in previous rounds.
Example: If Round 1 had 90,000 B3TR to distribute, but Round 2 had 80,000, the allocations in Round 2 will use the 80,000 units as the funding pool.
Base Allocation: Every application in the current round receives a minimum allocation from the total funding pool, even if the quorum isn't met. This is calculated based on the current round's funding amount.
Variable Allocation: This additional funding is determined by the voting results from the last successful round (e.g., if Round 1 succeeded, the votes from that round influence allocations in Round 2).
If quorum fails in the current round, variable allocations calculation will rely on the last successful round votes.
New applications in a failed round, with no previous votes to draw from, will only receive the base allocation.
Distributions are not automatically sent by the contract but need to be triggered. The claim function is public and anyone can claim the allocation for the apps. The VeBetterDAO team however created a scheduler service to execute this action at the start of each new round.
Quadratic Funding (QF) is a mechanism used by VeBetter DAO to amplify available resources and democratize fund allocation.
In this system, the proportion of the emissions pool allocated to each project is calculated by squaring the sum of the square roots of individual votes for the project and then normalizing this by the square of the total votes across all projects
where j indexes the voters for each project
where j indexes the voters, and k indexes all projects considered in the QF model for the round.
This formula ensures that the allocation is heavily influenced by the number of distinct supporters rather than the sum of their votes alone. As a result, projects that have broader community support, regardless of the size of individual votes, receive a more significant portion of the emissions pool.
This funding model emphasizes community consensus, ensuring that projects with the widest appeal, rather than those with the most concentrated VOT3 backing, receive the greatest B3TR allocation.
By default, QF is enabled for all voting rounds. However, admins have the option to disable QF. If QF is disabled, linear voting will be used, where the allocation is directly proportional to the number of votes received.
Important Note: If QF is disabled by an admin in the middle of a round, the change will only take effect starting from the following round.
The following properties can be updated by the governance:
Voting Period: currently this equals Emission's cycles, and can never be higher than it.
Quorum: percentage of VOT3 / Total supply participating in allocation voting.
Base Allocation Percentage: percentage of round allocations to be divided among the apps each round, currently set at 0%.
Allocation Cap: the maximum amount of votes (in percentage) that an app can receive, currently set at 20%.

Add an app
Now you will need to get some B3TR tokens: claim them from the Faucet
Deposit the B3TR tokens to your app balance so you can distribute them: go to your managed app page, and click "Deposit" in the app balance section
To allow your contract to distribute the rewards you need to click the cogs icon to enter the Settings section of your app and add the address of your contract (that will call the distributeReward function) as a "Reward Distributor".
That's it, you are all set and can distribute rewards through your backend or smart contract.
If you need to simulate allocation rounds, go to the Admin section and press the "Start round" button. In testnet rounds last 10 minutes, but apart from this everything else is the same as mainnet.
Testnet contracts addresses:
Testing on the solo node (aka: local node running on your computer simulating VeChain blockchain) is a bit more complicated than testing on testnet, since you will need to deploy the VeBetter contracts locally and interact with them to create your app, obtain the APP_ID, start an allocation round, vote, start round again, and add the reward distributor.
We recommend following the testnet path, but if you need to do it on the solo network you will need to mock a few VeBetter contracts:
B3TR token mock: you need a fake token to distribute
X2EarnApps mock: you need a contract where to add your app, generate an APP_ID and add a reward distributor
X2EarnRewardsPool mock: you need a contract to distribute the rewards
While the X2EarnRewardsPoolMock contract can be the exact same contract deployed on mainnet and testnet, the other two can be customized in order to have only the essential logic needed for running tests.
You can take a look at the mocked contracts in the X-App-Template repository, under the contracts/mocks folder.
After you added the mock contracts to your repository you should adjust the deploy script in a way that you will deploy and configure the mocked contracts only if you are deploying to the vechain_solo network.
Your script should look something like this:
That's it, you can now deploy your contracts locally/run tests where you simulate the VeBetter contracts, your app added to the ecosystem, and tokens distribution.
VeBetter distributes the B3TR token via a long-term emission schedule designed to incentivize sustainable behavior and community participation in governance. Emissions are distributed weekly and are split across several key allocation pools.
As a result of an approved governance proposal, the following updates were implemented:
The Treasury allocation was reduced from 20% to 15% for each cycle starting from cycle 46.
The remaining 5% was reallocated to a new GM Rewards Pool, exclusively for Galaxy Member (GM) NFT holders who actively participate in governance voting
These changes ensure more direct rewards for active and engaged members of the community.
B3TR token has ~1 billion total supply, that will be emitted weekly over a period of 634 weeks or 12 years.
N.B. We will use the term cycle instead of week when referring to the emissions schedule.
The Emissions smart contract contains parameters for the emissions scheduling.
Emissions need some sort of trigger, as it is not possible for a smart contract to invoke itself. There is a public function that can be triggered by any account. In addition to this, the foundation automatically triggers the emissions, if this operation fails, any other user can trigger it.
If you want to create an x2earn app it needs to have the following features:
Be able to distribute B3TR tokens on the VeChain blockchain
Be able to submit a proof (in JSON format) of the sustainable action the user was rewarded for
Bonus:
Allow the user to connect with their to your app
This guide provides instructions for setting up a project within the VeBetter ecosystem. Your app will participate in weekly allocation rounds, receive B3TR tokens at the beginning of each round, and distribute these
Use our to create a test app running in the VeBetter ecosystem.
Get some B3TR tokens on testnet, add a reward distributor then connect a smart contract or a backend and distribute rewards to your users.
Every time you reward a user you also need to specify the reason, the proof of the user's action and the sustainability impact it had.
Have doubts? Check our additional resources specifically picked for you to speed up your development.
When your app is ready submit it to VeBetter and join the movement!
Before going live be sure to go through our along the . Make sure to apply security measures to your app, avoiding hacks and farmers.
As of the start of November the VeChain node holders, referred to as "endorsers," are serving as the primary decision-makers in determining which XApps are admitted to the VeBetter ecosystem. Developers and innovators can engage with the ecosystem and submit their X2Earn applications through a structured process that includes community endorsement and voting.
To submit an app to the VeBetter ecosystem, every project must first acquire a Creator NFT, which verifies the creator and allows them to participate in the endorsement process. Here’s how it works:
Acquiring the Creator NFT
Application Process: XApp creators begin by filling out a form on the VeBetter platform, which initiates a background check to verify the team and the app’s legitimacy.
Alternative Paths: Creators can also apply for a grant through the . If successful, they will receive funding as well as a Creator NFT, which validates their project within the ecosystem.
On-Chain XApp Submission After receiving the Creator NFT, XApp creators can submit their app on-chain for consideration. This official submission registers the app on the VeBetter platform, allowing it to seek endorsements from VeChain node holders.
Connecting with Endorsers Upon acquiring the Creator NFT, XApp creators gain access to the VeBetter XApps Creators Discord server, where they can network with VeChain node holders who may endorse their app. This community platform provides opportunities for creators to present their app, build relationships with potential endorsers, and gain the necessary endorsement score to enter allocation rounds.
Endorsement and Funding Eligibility Once an app is submitted and endorsed with a cumulative score of 100, it will officially be added to the VeBetter ecosystem. It will be eligible to be weekly funded with B3TR tokens as a result of the : you will compete against other apps to receive as many B3TR tokens as possible, with holders of the token that will vote for the app they think deserves it the most.
When submitting your app to VeBetter you will need to provide 2 important information:
Treasury address: this is the address where B3TR tokens will be sent in case you will need to withdraw some tokens from the received weekly allocations (eg: you need some B3TR for marketing, team shares, etc.). This address can be a multi-sig or a simple EOA, it's up to you.
Admin address: this is the address that has superpowers for your app; it can update any details of the app, change the Treasury address, or move the ownership to another wallet. You can use the same wallet you use for the Treasury, another multi-sig, or a simple EOA as well.
Once your app is added you will obtain an APP_ID that VeBetter and other projects will use to recognize your app. You will also need to use your Admin address to add a Reward Distributor to distribute your rewards to the users. This is a simple address and it should belong to the contract or wallet that you will use to distribute the rewards. Be aware that this address can also withdraw funds, so protect its access correctly.
You will receive your first B3TR tokens at least one week after joining VeBetter, following the completion of at least one voting round. Therefore, you will need to address the scenario where people might see your app in VeBetter and attempt to use it before you are able to distribute rewards.
When submitting your app, you can select up to 2 categories that best describe its purpose and functionality. These categories help VeBetter filter and organize apps effectively, ensuring users can easily discover relevant app.
Categories in your App Metadata are stored using their id value, while the name is simply how the category will appear inside VeBetterDAO during the submission or the metadata modification process.
Every person and contract can interact with VePassport to check if an address can be considered a person. Additionally, modules can be called separately, allowing a certain amount of flexibility to implement custom personhood checks.
In the following pages, you can browse each module's endpoints and learn how the VePassport personhood check is performed.
The up-to-date interface of the VePassport contract can be found here.
VePassport is a system that allows Apps on VeChain to determine whether a wallet belongs to a bot or a real person. The Apps using this technology include, first and foremost, VeBetter, which verifies the authenticity of wallets during voting. Other Apps within the VeBetter ecosystem, often facing issues with fake accounts and Sybil attacks, can also access this information.
This decentralized identification framework enables a secure, Sybil-resistant environment that drives participation and promotes a more transparent, sustainable ecosystem.
There are several modules that VePassport uses to determine if a wallet is a bot or if it belongs to a real user:
Proof of Participation in the VeBetter Ecosystem
Proof of Investment
Proof of Identity
Whitelisting and Blacklisting
In the current implementation to determine if a wallet is legitimate, several factors are considered: whether it is on the whitelist or blacklisted, and the number of actions performed within a specific time range, while Proof of Investment and Identity will be integrated with the next releases.
Apps can interact with VePassport to check if a user is a person (now or in a specific block number) or can call each module separately to only get the participation score, or if the user is KYCed, or if it's whitelisted, blackilsted or signaled as a bot by other apps.
VePassport is designed to be expanded in the future with new modules.
Users need to complete 3 Better actions within a 12-week period to be considered a person. This requirement encourages greater participation in the ecosystem and ensures users are active contributors to the DAO.
An action is defined as a reward that you receive from an app (e.g., receiving a reward for drinking coffee in a sustainable cup with Mugshot).
Every time a user engages with an app and receives a reward their passport accumulates points. The amount of points is determined by the security level of the app he interacted with. An app with a low security score is worth 100 points, medium is 200, high is 400, and none is 0.
Another way to verify a wallet’s legitimacy is through the GM NFT level that the wallet holds. If the address holds a GM NFT with a level higher than 1 then it indicates that the owner has made a significant investment, since upgrading levels on that NFT is not free, suggesting that the wallet is more likely to be genuine.
X2earn apps can also flag a wallet as a bot or suspicious user. If a wallet receives enough signals to exceed a certain threshold, it will not be considered a real person.
Additionally, some authorized entities can blacklist or whitelist a wallet. Blacklisting might occur if a wallet is found to be part of a network of fake accounts. If a wallet is mistakenly blacklisted, it can request to be reinstated.
Similarly, a wallet can be added to the whitelist, especially if the user has completed a KYC (Know Your Customer) process, thereby ensuring that the account is legitimate.
Various levels of KYC (Know Your Customer) can be applied in the future, ranging from linking social profiles to full identity verification. This feature will remain optional, and will instantly provide layers of security and trust for user identities.
This proof is not implemented yet.
To better increase the interoperability across the VeBetter and VeChain ecosystem, VePassport offers the possibility to delegate your passport to other addresses.
You can even customize your passport by attaching to it other accounts you own.
To obtain B3TR tokens on testnet, whether you need to use them to distribute rewards with your app you have 2 options:
1) Claim from the faucet;
2) Get B3TR tokens from allocation rounds.
Go to https://dev.testnet.governance.vebetterdao.org/, connect your wallet, click the "Claim" button in the "Faucet" card on the sidebar. Now that you own some B3TR go to your app's page and click "Deposit" in the "Balance" card in the sidebar.
If you want to try the full flow (very similar to production) you can start a new allocation round (in production those are started automatically each Monday and last a week, in testnet you need to manually trigger them, and they last 10 minutes), wait 10 minutes, then distribute the rewards to your app (done automatically in production, but you need to manually trigger on testnet).
You can access those functionalities from the "Admin" tab.
Remember that to actually distribute rewards you will need to add your wallet as a reward distributor in your app's settings. Read more in the .
To aid in the development process, we've created several valuable resources:
Play with our test environment Utilize our testnet environment to add apps to the ecosystem, interact with smart contracts, and manage reward distribution. Detailed information about the test environment can be found in its dedicated section, providing you with a sandbox to refine and test your applications before going live.
VeChain Kit: an all-in-one javascript library for building VeChain applications.
Read the Integration and the Sustainability Proofs sections to understand how to distribute B3TR tokens
X-App-Template () This template serves as a foundational guide to help you code your app and interact effectively with VeBetter. It's a demo of an app where you can scan grocery receipts and be rewarded if you buy sustainably.
Documentation of everything you need to know about vechain and blockchain technology to create a decentralized app.
A package containing all the smart contracts used in mainnet. You can also install this repository as a dependency in your project and use it to access the ABIs of the contracts and their addresses.
The following are the roles available in the VePassport contract, with their functionality and current assignees.
Role Name
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
Grants or revokes roles; Set decay rates for proof of participation and thresholds.
Admin Wallet
UPGRADER_ROLE
Update the contract implementation address
Admin Wallet
ROLE_GRANTER
Allow an address to signal users on behalf of an app. Grants or revokes roles;
Admin Wallet
This page documents the legacy VeChain node system which was used before the StarGate upgrade. Legacy nodes are no longer the active participation mechanism and have been replaced by StarGate staking NFTs.
If you still hold a legacy node, you must migrate to continue earning rewards and participating:
StarGate Migration Guide:
VeBetter is a decentralized autonomous organization (DAO) fostering sustainability through the B3TR token. VOT3 governs the DAO, allowing community-driven decisions.
VeBetter is a decentralized autonomous organization (DAO) platform built on that empowers its community through a suite of smart contracts designed for governance, incentive distribution, and asset management. The key components of the platform include:
B3TR Token: The incentive ERC-20 token with a 1 billion cap, used within the ecosystem for rewards and governance.
Governance System:
Delegation allows a user to delegate their passport personhood to another address to allow more versatility and app interoperability. A delegator can have only one delegatee, and a delegatee can have only one delegator.
When delegating your passport, the delegatee must accept the delegation first. When a delegatee accepts the delegation his passport will become unused, giving priority to the delegated passport, regardless of the personhood check outcome.
Since by delegating the passport, the personhood check will not work anymore for the original wallet, the delegator will also lose the eligibility to vote. However, he will still need to use X2Earn apps, upgrade his GM NFT, or do whatever is needed in order for his passport to be considered a person, allowing the delegatee to vote.
An example use case for using the delegation is VeDelegate: you can have your VeWorld that you use to interact with apps with a valid Passport, that you delegate to the TBA created by VeDelegate where you deposit your B3TR tokens and automatize voting.
The X2Earn Creator NFTs are integral to VeBetter’s process for managing and validating new XApp submissions. These NFTs serve as an access key for creators, enabling them to submit their applications on-chain and engage with the VeBetter endorsement process through VeChain node holders.
Purpose: X2Earn Creator NFTs are used within VeBetter to authorize new XApp submissions and provide access to the endorsers (VeChain node holders). These NFTs ensure that only vetted and verified creators can submit apps for consideration.
An overview of how VeChain moved from legacy nodes to StarGate including what migration means for participation and VeBetterDAO.
VeChain previously used a node-based system to enable network participation, rewards, and governance-related functions. This system has now been replaced by StarGate, VeChain’s current staking and participation framework.
This page explains what changed, what legacy node holders need to do, and how this affects participation within VeBetterDAO.
"B3TR": "0xbf64cf86894Ee0877C4e7d03936e35Ee8D8b864F",
"B3TRGovernor": "0xDF5E114D391CAC840529802fe8D01f6bdeBE41eC",
"Emissions": "0x148d21032F4a7b4aeF236E2E9C0c5bF62d10f8EB",
"GalaxyMember": "0xCf73039913e05aa1838d5869E72290d2b454C1E8",
"TimeLock": "0x30ee94F303643902a68aD8A7A6456cA69d763192",
"Treasury": "0x039893EBe092A2D22B08E2b029735D211bfF7F50",
"VOT3": "0xa704c45971995467696EE9544Da77DD42Bc9706E",
"VoterRewards": "0x2E47fc4aabB3403037fB5E1f38995E7a91Ce8Ed2",
"X2EarnApps": "0xcB23Eb1bBD5c07553795b9538b1061D0f4ABA153",
"X2EarnRewardsPool": "0x5F8f86B8D0Fa93cdaE20936d150175dF0205fB38",
"XAllocationPool": "0x9B9CA9D0C41Add1d204f90BA0E9a6844f1843A84",
"XAllocationVoting": "0x5859ff910d8b0c127364c98E24233b0af7443c1c",
"B3TRFaucet": "0x5e9c1F0f52aC6b5004122059053b00017EAfB561"import { ethers, network } from "hardhat";
import { Challenges, Cleanify, RolesManager } from "../../typechain-types";
import { networkConfig } from "@repo/config";
import { deployProxy } from "../helpers/upgrades";
import { faker } from "@faker-js/faker";
let REWARD_TOKEN_ADDRESS = "0xE5FEfcB230364ef7f9B5B0df6DA81B227726612b"; // mainnet address
export async function deploy(): Promise<{
mySustainableContractAddress: string;
}> {
console.log(
`Deploying on ${network.name} (${networkConfig.network.defaultNodeUrl})...`
);
console.log(`Deploying my app contract...`);
const MySustainableContract = await ethers.getContractFactory("MySustainableContract");
const mySustainableContract = await MySustainableContract.deploy();
await mySustainableContract.waitForDeployment();
console.log(`Sustainable Contract deployed to ${await mySustainableContract.getAddress()}`);
if (network.name === "vechain_solo") {
console.log(`Deploying mock RewardToken...`);
const RewardToken = await ethers.getContractFactory("B3TR_Mock");
const rewardToken = await RewardToken.deploy();
await rewardToken.waitForDeployment();
REWARD_TOKEN_ADDRESS = await rewardToken.getAddress();
console.log(`RewardToken deployed to ${REWARD_TOKEN_ADDRESS}`);
console.log("Deploying X2EarnApps mock contract...");
const X2EarnApps = await ethers.getContractFactory("X2EarnAppsMock");
const x2EarnApps = await X2EarnApps.deploy();
await x2EarnApps.waitForDeployment();
console.log(`X2EarnApps deployed to ${await x2EarnApps.getAddress()}`);
console.log("Deploying X2EarnRewardsPool mock contract...");
const X2EarnRewardsPool = await ethers.getContractFactory(
"X2EarnRewardsPoolMock"
);
const x2EarnRewardsPool = await X2EarnRewardsPool.deploy(
deployer.address,
REWARD_TOKEN_ADDRESS,
await x2EarnApps.getAddress()
);
await x2EarnRewardsPool.waitForDeployment();
console.log(
`X2EarnRewardsPool deployed to ${await x2EarnRewardsPool.getAddress()}`
);
console.log("Adding app in X2EarnApps...");
await x2EarnApps.addApp(deployer.address, deployer.address, "MySustainableApp");
const appID = await x2EarnApps.hashAppName("MySustainableApp");
console.log(`Funding contract...`);
await rewardToken.approve(
await x2EarnRewardsPool.getAddress(),
ethers.parseEther("10000")
);
await x2EarnRewardsPool.deposit(ethers.parseEther("2000"), appID);
console.log("Funded");
console.log("Add MySustainableContract as distributor...");
await x2EarnApps.addRewardDistributor(
appID,
await mySustainableContract.getAddress()
);
console.log("Added");
console.log(
"Set APP_ID and X2EarnRewardsPool address in Challenges contract..."
);
await mySustainableContract.setVBDAppId(appID);
await mySustainableContract.setX2EarnRewardsPool(
await x2EarnRewardsPool.getAddress()
);
console.log("Set");
}
return {
mySustainableContract: await mySustainableContract.getAddress()
};
}Standard: Creator NFTs are non-transferable tokens compliant with the ERC721 standard, implemented using the OpenZeppelin (OZ) library.
Minting Authority: Only the X2Earn App Review Panel has the authority to mint Creator NFTs. The panel grants these NFTs if they deem the app suitable, legitimate, and ready for the endorsement process within VeBetter.
Non-Transferability: Creator NFTs are non-transferable, meaning they cannot be sold or transferred to another user, ensuring that only the verified creator retains access.
Submission Access: Once an app creator have granted a Creator NFT, they can submit their XApp on-chain for endorsement. This submission formally registers the app within the VeBetter ecosystem, allowing it to seek endorsements from node holders.
Additional NFT for Team member: After the initial submission, the XApp admin (creator) can add up to two additional creators, for a maximum of three creators per application. Each additional creator will receive their own Creator NFT.
Single NFT Limitation: Users are limited to holding only one Creator NFT at any given time. If a user wishes to contribute to another application, they must either revoke their current Creator NFT from the xapp admin or use a separate account.
Blacklisting Policy: If an XApp is blacklisted for any reason, and the creator is not associated with any other active XApp, their Creator NFT will be burned. This prevents creators of non-compliant or blacklisted apps from submitting new projects without re-approval.
NFT Burn: The burning mechanism ensures that blacklisted creators cannot bypass VeBetter’s review process by holding onto their Creator NFT. This policy enhances the integrity of the ecosystem by holding creators accountable for their submissions.
Token Standard: ERC721 (non-transferable)
Minting Authority: X2Earn App Review Panel
Max NFTs per User: One NFT per user, regardless of the number of XApps
Additional NFTs: Admin have the ability to mint up to two extra NFTs for team members. These additional creators will be restricted to their assigned app only and cannot use their creator NFTs to submit new apps.
Single Creator Association: Each creator is assigned to exactly one app.
Before StarGate, participation in the VeChain ecosystem was based on holding a legacy node. These nodes provided benefits such as VTHO generation, participation rights, and eligibility for certain ecosystem features.
This system is now deprecated and is no longer the active participation mechanism on VeChain.
Legacy node documentation is still available in this section for historical reference, but it does not apply to the current network.
StarGate is VeChain’s active staking system.
Instead of nodes, users now participate by staking VET to mint a staking NFT. This staking NFT represents the user’s participation and can be delegated within the StarGate system.
All rewards, participation rights, and future governance mechanisms are based on staking NFTs rather than legacy nodes.
Legacy VeChain nodes must be migrated to StarGate to remain active. Migration converts a legacy node into a StarGate staking NFT, which is required for continued participation and rewards.
SETTINGS_MANAGER_ROLE
Toggle personhood checks, update thresholds, and other personhood parameters.
Admin Wallet
WHITELISTER_ROLE
Whitelist or blacklist addresses
Admin Wallet
ACTION_REGISTRAR_ROLE
Register that a user performed an action
X2EarnRewardsPool contract
ACTION_SCORE_MANAGER_ROLE
Administrates the proof of participation settings
Admin Wallet
SIGNALER_ROLE
Signal users
Admin Wallet
Personhood Check
Proof of Participation
Proof of Investment
Bot Signaling
Blacklisting and Whitelisting





GM Rewards
4%
5% of weekly emissions, reallocated from the original 20% Treasury share
No decay as pegged to the other emission
1 week
Yes
X-Allocations decay rate
4%
Yes
X-Allocations decay frequency
every 12 cycles
Yes
Vote2earn decay rate
20%
Yes
Vote2earn decay frequency
every 50 cycles
Yes
Treasury % allocation
15% of total emissions for the cycle (updated via proposal)
Yes
Gm Pool % Allocation
5% of total emissions for the cycle (added via proposal)
Yes
Pool
% of total supply
Initial emissions
Decay Rate
X-Allocations
53%
2,000,000
4% every 12 cycles
Vote2earn
27%
Follows the X-Allocation emissions but with an additional decay rate applied
20% of x-allocations emissions every 50 cycles
Treasury
16%
25% of total allocation for X-Allocations and Vote2earn
No decay as pegged to the other emission
Param
Value
Upgradeable
X-Allocations address
0x4191776F05f4bE4848d3f4d587345078B439C7d3
Yes
Vote2earn address
0x838A33AF756a6366f93e201423E1425f67eC0Fa7
Yes
Treasury address
0xD5903BCc66e439c753e525F8AF2FeC7be2429593
Yes
Total supply
1B
No

Emissions frequency (cycle length)
To avoid users misusing this feature when voting in the VeBetterDAO governance contracts the delegation will be checked upon the block number when the round starts, so new delegations will be taken into account by the B3TR governance system only after the next round starts.
interface IVeBetterPassport {
...
function delegateWithSignature(address delegator, uint256 deadline, bytes memory signature) external;
function delegatePassport(address delegatee) external;
function acceptDelegation(address delegator) external;
function denyIncomingPendingDelegation(address delegator) external;
function cancelOutgoingPendingDelegation() external;
function revokeDelegation() external;
function getDelegatee(address delegator) external view returns (address);
function getDelegator(address delegatee) external view returns (address);
function isDelegator(address user) external view returns (bool);
function isDelegatee(address user) external view returns (bool);
function isDelegatorInTimepoint(address user, uint256 timepoint) external view returns (bool);
function isDelegateeInTimepoint(address user, uint256 timepoint) external view returns (bool);
...
}[
{ "id": "others", "name": "Others" },
{ "id": "education-learning", "name": "Learning" },
{ "id": "fitness-wellness", "name": "Lifestyle" },
{ "id": "green-finance-defi", "name": "Web3" },
{ "id": "green-mobility-travel", "name": "Transportation" },
{ "id": "nutrition", "name": "Food & Drinks" },
{ "id": "plastic-waste-recycling", "name": "Recycling" },
{ "id": "renewable-energy-efficiency", "name": "Energy" },
{ "id": "sustainable-shopping", "name": "Shopping" },
{ "id": "pets", "name": "Pets" }
]
B3TRGovernor: Facilitates decentralized governance where any community member can create proposals. Proposals require a deposit of VOT3 tokens to become active, and successful proposals are executed via the TimeLock contract.
TimeLock: Ensures a time delay in the execution of governance decisions for security and transparency.
Incentive Mechanisms:
Emissions: Manages the periodic distribution of B3TR tokens to various allocations including XAllocation, Vote2Earn, and Treasury.
VoterRewards: Rewards voters based on their voting power and Galaxy Member NFT level.
X2Earn Apps and Rewards: Supports x-2-earn applications by managing the insertion, management, and eligibility of apps for B3TR allocation rounds. Rewards users for sustainable actions within these apps through the X2EarnRewardsPool.
User Privileges and Rewards:
GalaxyMember: An upgradeable NFT system that determines user privileges and B3TR token rewards based on the NFT level.
Asset Management:
Treasury: Holds all DAO assets, including various ERC-20 and ERC-721 tokens. Asset transfers are governed by community proposals.
Voting and Allocation:
XAllocationPool: Distributes weekly B3TR emissions for x2earn apps.
XAllocationVoting: Manages voting for x2Earn application support, using a "Quadratic Funding" formula to calculate voting power based on VOT3 holdings.
VeBetter leverages these contracts to create a robust and democratic ecosystem where community members can actively participate in governance, earn rewards, and contribute to the platform's growth.
You can find the smart contracts repository at this GitHub url. Use that repo to generate ABIs and Typechain Types to interact with the contracts.
Read more about our smart contracts and what they do in the Smart Contracts section.
Contracts have been deployed on the vechain mainnet at the following addresses.
B3TR
0x5ef79995FE8a89e0812330E4378eB2660ceDe699
B3TRGovernor
0x1c65C25fABe2fc1bCb82f253fA0C916a322f777C
Emissions
0xDf94739bd169C84fe6478D8420Bb807F1f47b135
GalaxyMember
0x93B8cD34A7Fc4f53271b9011161F7A2B5fEA9D1F
TimeLock
0x7B7EaF620d88E38782c6491D7Ce0B8D8cF3227e4
Treasury
0xD5903BCc66e439c753e525F8AF2FeC7be2429593

// Option 1: Refill your rewards pool with additional funds
// @param amount The amount of tokens to add to your rewards pool
X2EarnRewardsPool.increaseRewardsPoolBalance(bytes32 appId, uint256 amount)
// Option 2: Toggle rewards functionality on/off
// @param enable Set to false to disable rewards, true to enable
X2EarnRewardsPool.toggleRewardsPoolBalance(bytes32 appId, bool enable)X2Earn Apps should consider implementing necessary security measures to guard against farmers unfairly obtaining b3tr tokens.
Single Person, Single Wallet -> In this scenario the attacker is a single person using a single wallet address. They try to repeat the same claim for b3tr rewards multiple times for the same wallet address. If the dApp is using AI for image validation, they could attempt to use a fake image over and over again.
Single Person, Multiple Wallets -> In this scenario the attacker is a single person but now using multiple wallet addresses. For example they might submit a claim for a reward, then logout of the dApp then login with a different wallet address in VeWorld and repeat the same claim. The attacker then repeats this exercise switching between different accounts to make multiple claims for rewards.
Scripts (aka Bots) -> This is where the attacker has coded a script that submits a claim for rewards. The script might try a single wallet or use multiple wallets to submit the claim for a reward. If the dApp is using AI for image verification, the script might generate a new image or adjust a previously created image.
Multiple Collaborating People, Multiple Wallets -> In this scenario a group of attackers are collaborating together, they may share the same wallet, share social login details. As they are collaborating together they are collecting rewards for the group, which they can share between the group later.
Exploiting Vulnerabilities -> In this scenario the attacker exploits vulnerabilities in smart contracts or back-end API services to create Bots or manually bypass the front-end of the dApp.
Certificate based authentication -> For example if there is a /account endpoint this should be secured with the signed certificate the user signs in VeWorld. The back-end can then validate the certificate, and use the signed address in from the certificate to identify the users wallet.
Captcha verification -> For example if there is a /claim endpoint this should be secured with a ReCaptcha. This is to protect against scripted/bot attacks, as it ensures that the back-end APIs can only be used from the front-end of the dApp.
CORS domains -> This is to ensure that the back-end API's can only be called with a request from the same domain. For example if the API is running at
AI based validation -> The prompts used to validate an image should be thoroughly tested to ensure that the AI is validating as expected. If the AI is used to extract data out of an image (e.g. A receipt) it should be tested to ensure that hallucinations are not occurring. The AI should be asked to produce a confidence score, if that is below a threshold the image could be flagged for manual verification.
No unique identifier -> To verify a sustainable action there should be some indisputable evidence of it. For example a social media post, data from an external system, a receipt as proof of purchase or a date-time stamp. In the case of AI image verification, the AI should be prompted to recognise relevant data in the image that can be used for a uniqueness check.
Apps should have the means to identify suspicious behaviour within their dApp, for example rewards being paid every 10 seconds to accounts that have no other transaction history. Apps should have the means to ban accounts or entire devices from using their service.
The distributor account private key should be secure within the dApp and not be able to be sniffed in the traffic the dApp generates. If the dApp is using back-end contracts or APIs to sign the reward transaction these should have a secure way of storing the private keys.
Farmers might attempt to install VeWorld (or your native app), multiple times on the same device, and use a different wallet per instance of the app. This is especially true of Android devices, where software exists to allow multiple instances of an app to be installed. A dApp should consider using tools such as FingerprintJS (or its paid version), to identify a users device, and ban the device rather than just the users account(s). If developing a native dApp, protections against multiple installs should be built into the dApp.
Management of funds -> The allocation the dApp receives from the DAO on a weekly basis is at risk if there are vulnerabilities within the dApp. The dApp owner if concerned about farmers should reduce the b3tr balance of the dApp by withdrawing funds to their treasury account and drip feeding it back to the dapp when needed. Once the concerns are alleviated this strategy can end. The dApp owner can also mitigate this risk by setting a portion of the weekly allocation for distribution and another portion as treasury funds. Treasury funds can be withdrawn at any time.
Identify verification -> Apps can also offer login methods other to VeWorld, for example Google, Facebook, Twitter. In these cases dApp owners should consider validation of the users social media profiles, for example does the facebook profile have a complete profile, was the google account created in last 30mins. Apps could also consider sending verification emails.
Progressive unlocking -> A new account in the dApp might have tigher rate limits and lower rewards. As the user continues to use the dApp they progressively unlock higher rate limits and higher rewards. This means an attacker has to spend more efforts to reach the higher rewards slowing their progress.
Stopping farmers is a difficult task and in some scenarios very difficult to achieve without impacting genuine users. Often the approach is to slow the farmers progress so that their effort/reward ratio is no longer worth it.
To help Apps tackle many of the challenges described above, we recommend evaluating a service called — a modern, enterprise-grade fraud detection and risk assessment platform.
Guardian was built from real-world experience fighting the exact pain points outlined in this document: bot activity, multi-wallet farming, VPN/proxy abuse, device spoofing, browser tampering, and coordinated fraud attempts. It provides accurate detection signals and behavioural risk scoring that can be integrated directly into front-end or back-end flows, making it especially valuable for ecosystems like VeBetter, where protecting reward integrity is critical.
This is not a paid advertisement; Guardian is simply a tool that aligns well with the needs of sustainability-focused applications.
For projects interested in trying it, a 50% discount is available using the code VEBETTER50 at checkout.
Guardian Website:
Guardian Docs:
The Treasury is the beating heart of any DAO, representing the store of wealth and source of funds for the ecosystem. Adhering to the core principles of Web3, the VeBetter DAO Treasury will be transparent, fiscally efficient, and auditable.
Treasury management follows the rules and protocols defined in VeBetter Governance. The uncompromising principle of the Treasury Pool is that tokens will only be used for expanding and building the VeBetter ecosystem, making the world better in the process.
Treasury will hold all assets belonging to the DAO. Such assets include VET, VTHO, B3TR
Proof of Participation is a module of VePassport that allows tracking the amount of times an address has used the apps of VeBetter. For every action, a score (from 0 to 400 based on the app security level) is attributed to the user interacting with the X2Earn App.
The points are then summed, generating a cumulative score for the user and if it exceeds a certain threshold, the wallet can be considered a person.
Only the X2EarnRewardsPool contract can call the registerAction function, this means that if an app is not using the X2EarnRewardsPool contract to distribute their rewards then that action is never taken into account.
In this example, we assume that you are building a smart contract where users can submit some sustainable action that is being approved/rejected by some moderator. If the action is approved the user can claim his rewards. No backend is involved.
Your contract should look like this:
The address of this contract must be set as a distributor of your APP in order to move funds from the X2EarnRewardsPool contract.
VOT3
0x76Ca782B59C74d088C7D2Cce2f211BC00836c602
VoterRewards
0x838A33AF756a6366f93e201423E1425f67eC0Fa7
X2EarnApps
0x8392B7CCc763dB03b47afcD8E8f5e24F9cf0554D
X2EarnRewardsPool
0x6Bee7DDab6c99d5B2Af0554EaEA484CE18F52631
XAllocationPool
0x4191776F05f4bE4848d3f4d587345078B439C7d3
XAllocationVoting
0x89A00Bb0947a30FF95BEeF77a66AEdE3842Fe5B7
VeBetter Passport
0x35a267671d8EDD607B2056A9a13E7ba7CF53c8b3
X2EarnCreator
0xe8e96a768ffd00417d4bd985bec9EcfC6F732a7f
NodeManagement
0xB0EF9D89C6b49CbA6BBF86Bf2FDf0Eee4968c6AB
GrantsManager
0x055d20914657834c914d7c44bf65b566ab4b45a2
Dynamic Base Allocations Pool
0x98c1d097c39969bb5de754266f60d22bd105b368
Relayers Rewards Pool (Auto-voting)
0x34b56f892c9e977b9ba2e43ba64c27d368ab3c86
api.myapp.comapi.fakeapp.comRate limiting -> Depending on the design of the dApp a user will only be allowed to make a limited number of claims for rewards per day, per week. There are different strategies here, for example:
Inspecting the date-time when the users address last received a reward, and not allowing more claims for a time period after that. For example a user can't make another claim until 24hrs after their previously paid reward. This can be implemented in the back-end database or by reading the last reward event on-chain.
Determining the current round (week) and how many claims the user has submitted in that timeframe. Thus limiting the user to a fixed number of claims per week.
Using device identification techniques to uniquely identify the mobile device the user is using, and limiting the number of claims for rewards not just on address but also on device.
Scaling Rewards by Demand -> This is a strategy to scale down user rewards in peek demands and scale them back up at quiet times. The goal is to make the weekly allocation a dApp received last the full week, but also guard against spikes in users (or bots) claiming rewards. One way to do this is to compute the average rewards per second since the start of the week, and project it forward to the end of the week, and see if above/below the Apps weekly budget. If above budget, the dApp can then scale down users rewards until back on track.

VOT3ERC-20ERC-721Tokens can only be transferred from the Treasury to another address via a governance proposal. The same goes for converting to B3TR/ VOT3 .
Token balances can be viewed by anyone by calling one of the balance functions.
In the case that the Treasury needs to stop all transactions, the smart contract can be paused.
This contract cannot transfer tokens out that are non-native or non ERC-721 or ERC-20.
Function
Access Control
Description
pause()
Contract Admin
Pause contract so no transfers can be carried out
upgradeToAndCall()
Upgrader Role
Upgrade implementation contract
transferVTHO()
Governance
Withdraw VTHO from treasury
transferB3TR()
Governance
Withdraw B3TR from treasury
Each token has a transfer limit in place to avoid moving huge sums of money in a single operation. Those limits can be updated by governance and are token-specific.
Current limits are:
200,000 VET
200,000 B3TR
3,000,000 VTHO
50,000 VOT3
VeBetterPassport (Mainnet Address): 0x35a267671d8EDD607B2056A9a13E7ba7CF53c8b3
Other apps and smart contracts can interact with the Bot Signaling module through these key functions in the VeBetterPassport contract:
Checking Signals:
You can query signal counts for users through the following methods:
signaledCounter: Returns the total number of times a user has been signaled across all applications
appSignalsCounter: Returns the number of times a user has been signaled by a specific application
Apps are free to decide how they interpret this number.
Threshold for Personhood:
When using the isPerson function, a user's flagged count is compared to a set threshold.
If an address has been flagged more than the threshold amount, it will fail the personhood check.
The following is a snippet of how to signal addresses by using the VeChain SDK.
If you need access to bot signaling functions, please reach out to us.
If you are the app admins, you can self-assign the required roles using the following functions:
Granting or revoking SIGNALER_ROLE:
Note: App admins are responsible for managing their team's permissions correctly.
When an action is registered a score is being assigned to the user based on the security level of the app. The VeBetter team will be responsible for initially analyzing apps and setting the security score for each app and will open this power to the entire DAO in the future.
There are 4 security levels:
NONE = 0 points
LOW = 100 points
MEDIUM = 200 points
HIGH = 400 points
Currently, all apps are assigned a security score of type "LOW", therefore, for any app used, a user will receive 100 points for each action.
Per each account, a score is calculated based on the points he gathered until now.
The formula to calculate the score takes into account 2 arguments:
Amount of rounds to use: currently set to 12, which means that the contract will sum all the points gathered during the last 12 weeks;
Decay percentage: currently set to 0, which reduces the points of previous rounds (eg: if set to 20%, the score calculated until the previous round will be reduced by 20% in the next, in a linear fashion).
This approach ensures that a person must continue to participate in the VeBetter ecosystem and use the apps to maintain eligibility for voting.
The following is the current implemented formula to calculate the cumulative score of the user in the last t amount of rounds:
a is the total scores, r is the rate of decay, t is number of rounds)The threshold an address must meet to be considered a person is 300 points accumulated during the last 12 rounds.
Other apps or contracts can interact with the Proof of Participation module through the following functions of the VePassport contract:
Read more about the proof standard and how we expect you to provide it in the Sustainability Proofs and Impacts section.
To be able to distribute the rewards you will need to add the PUBLIC ADDRESS of the wallet calling the distributeRewards function as a Reward Distributor of your app.
To do so, you need to:
1) Connect with your app's admin wallet to the governance dapp
2) Go to your app's page
3) Click the cogs button to enter the settings page
4) Scroll down to the "Reward Distributors" section, and add the public address as a reward distributor
5) Save changes
The Rewards Metadata feature allows applications to enrich reward distributions with additional contextual information. This is facilitated through the distributeRewardWithProofAndMetadata function, which accepts a JSON-formatted string as metadata.
The provided metadata is then emitted via the RewardMetadata event, enabling off-chain services to efficiently index, analyze, and utilize the data for tracking and reporting purposes.
To maintain consistency across applications, it's recommended to follow a standardized metadata structure. Below is an example of a JSON-formatted metadata string:
Keep in mind that including location metadata may require updating your privacy policy and terms of service.
To provide metadata you need to distribute the rewards through the X2EarnRewardsPool contract with the following function:
RewardMetadataUpon successful execution of the distributeRewardWithProofAndMetadata function, the RewardMetadata event is emitted with the following parameters:
amount (uint256): The distributed reward amount.
appId (bytes32): The application identifier.
receiver (address): The address receiving the reward.
This event allows off-chain systems to listen for and process reward distributions along with their associated metadata.
Optional Usage: The metadata is optional. If your application doesn't require additional context, you can continue using the existing distributeRewardWithProof function.
Standardization: Adhere to the suggested metadata structure to ensure consistency and facilitate seamless data integration across the ecosystem.
Data Validation: Implement validation checks to ensure the metadata JSON is correctly formatted and contains relevant information before invoking the distribution function.
Setup a lambda function or an endpoint that will send the B3TR tokens to the user, providing also a proof and impacts of the rewarding action.
We will use @vechain/sdk-network and @vechain/vebetterdao-contracts to interact with VeBetter's X2EarnRewardsPool contract to distribute the rewards.
Run the following command to install the packages:
To distribute the rewards you will need 2 information:
Node URL
Your APP_ID on VeBetter: create app to obtain the APP_ID.
Now you can distribute the reward like this:
Read more about the proof standard and how we expect you to provide it in the section.
To be able to distribute the rewards you will need to add the PUBLIC ADDRESS of the wallet calling the distributeRewards function as a Reward Distributor of your app.
To do so, you need to:
1) Connect with your app's admin wallet to the governance dapp
2) Go to your app's page
3) Click the cogs button to enter the settings page
The ‘X’ in X-2-Earn refers to the mathematical concept of the unknown variable. ‘X’ can be applied to any kind of sustainability ecosystem with an earn mechanism. For example, ‘Plant-2-Earn', for an ecosystem that rewards tree planting. Sweat-2-Earn, for Apps that reward working out, and so on. B3TR tokens distributed to X-2-Earn Apps are, in part, intended as a source of incentivization for users. They may serve other purposes, such as encouraging builders, or for marketing and sponsorships etc. B3TR reward distribution plans are at the discretion of projects and the voting community who will approve or disapprove of a project’s reward proposals through voting.
As of the beginning of November, VeBetter allows apps to join the ecosystem through the endorsement of VeChain node holders. This shift from admin-controlled app selection to vechain community-based endorsement reflects the DAO’s commitment to decentralization.
interface IVeBetterPassport {
...
function signalingThreshold() external view returns (uint256);
function signaledCounter(address _user) external view returns (uint256);
function appSignalsCounter(bytes32 _app, address _user) external view returns (uint256);
function appTotalSignalsCounter(bytes32 app) external view returns (uint256);
function signalUserWithReason(address _user, string memory reason) external;
function resetUserSignalsByAppWithReason(address user, string memory reason) external;
...
}import {
ThorClient,
ProviderInternalBaseWallet,
VeChainProvider,
} from '@vechain/sdk-network';
import { ErrorDecoder } from 'ethers-decode-error';
import passportAbi from './passport.json' assert { type: 'json' };
// get passport contract with signer from a helper function
const passport = await getPassportContract();
// what to signal
const addressToSignal = '0x0000000000000000000000000000000000000000';
const reason = 'test';
console.log('Address to signal is', addressToSignal, 'for', reason);
// log current signal count
const [counter] = await passport.read.signaledCounter(addressToSignal);
console.log('Signals received for address are', counter);
// send a signal
const tx = await passport.transact.signalUserWithReason(
addressToSignal,
reason
);
console.log('Signal sent in tx', tx.id);
async function getPassportContract() {
// config sender
const privateKey =
'0x09b76a9e3c0f154ca2c6f9b9580ad5f6771493866553df98b10c38ddce987847';
const address = '0x00351f449190a9C2A41e6989c98fe5fC5eB50000';
const wallet = new ProviderInternalBaseWallet([
{ privateKey: Buffer.from(privateKey.slice(2), 'hex'), address },
]);
// connect to network
const thor = ThorClient.at('https://mainnet.vechain.org');
const provider = new VeChainProvider(
// Thor client used by the provider
thor,
// Internal wallet used by the provider (needed to call the getSigner() method)
wallet,
// Enable fee delegation
false
);
const signer = await provider.getSigner(address);
// contract config
const passport = thor.contracts.load(
// VePassport address
'0x35a267671d8EDD607B2056A9a13E7ba7CF53c8b3',
// the interface definition
passportAbi,
// origin signing transactions
signer
);
return passport;
}assignSignalerToAppByAppAdmin(bytes32 app, address user)
removeSignalerFromAppByAppAdmin(bytes32 app, address user)interface IVeBetterPassport {
...
function getCumulativeScoreWithDecay(address user, uint256 lastRound) external view returns (uint256);
function userRoundScore(address user, uint256 round) external view returns (uint256);
function userTotalScore(address user) external view returns (uint256);
function userAppTotalScore(address user, bytes32 appId) external view returns (uint256);
function thresholdPoPScore() external view returns (uint256);
function roundsForCumulativeScore() external view returns (uint256);
function securityMultiplier(PassportTypes.APP_SECURITY security) external view returns (uint256);
function appSecurity(bytes32 appId) external view returns (PassportTypes.APP_SECURITY);
...
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;
// can find here: https://github.com/vechain/vebetterdao-contracts/tree/main/contracts/interfaces
import "./interfaces/IX2EarnRewardsPool.sol";
/**
* Example contract with key functionality to interact with the x2Earn rewards pool
* and distribute rewards.
* You can customize this contract in the way
*/
contract MySustainableAppContract {
IX2EarnRewardsPool public x2EarnRewardsPool;
bytes32 public VBD_APP_ID;
// a dummy mapping pretending you have a way to track and
// validate user actions on chain.
mapping(uint256 actionId => ActionStruct) public sustainableActions;
mapping(uint256 actionId => bool) public rewardsClaimed;
// You will need to setup the address of the X2EarnRewardsPool contract
// and your APP_ID on VeBetterDAO
constructor(IX2EarnRewardsPool _x2EarnRewardsPool, bytes32 _VBD_APP_ID) {
x2EarnRewardsPool = _x2EarnRewardsPool;
VBD_APP_ID = _VBD_APP_ID;
}
/**
* @notice A function that allows a user to claim a reward for a specific
* sustainable action that they performed.
*
* IMPORTANT: the address of this contract must be set as a distributor
* of your APP in order to move funds from the X2EarnRewardsPool contract.
* You can set this on the VeBetterDAO governance app.
*/
function claimReward(uint256 _actionId) external {
// ... some code to check if the action is valid and user can claim
// If distributeReward fails, it will revert
x2EarnRewardsPool.distributeReward(
VBD_APP_ID,
actions[_actionId].rewardAmount,
msg.sender, // this is the user calling the claimReward function
"" // proof and impacts not provided
);
rewardClaimed[_actionId] = true;
emit RewardClaimed(_actionId, msg.sender);
}
}{
"location": {
"city": "Berlin",
"country": "Germany",
"region": "EU"
},
"referral_source": "social_media",
"campaign_id": "earth_day_2025"
}
yarn add @vechain/sdk-network @vechain/vebetterdao-contractsTESTNET: https://testnet.vechain.org
MAINNET: https://mainnet.vechain.orgYou can check the current threshold amount by calling signalingThreshold
👉 If you still hold a legacy node, you must migrate to continue participating:
The Node Management feature within VeBetter empowers VeChain node holders with greater flexibility and control over their participation in the ecosystem. As a node holder, you can manage your nodes, delegate your endorsement rights to others, and even consolidate multiple nodes within a single account—all through an intuitive UI.
Delegation of Endorsement Rights As a VeChain node holder, you have the option to delegate your endorsement rights to another individual within VeBetter. By doing so, you allow this delegatee to manage the endorsement of XApps on your behalf.
Control: You remain in control of your node’s delegation status and can revoke or assign endorsement rights as needed.
Flexibility: Delegation allows you to have someone else manage your endorsement activities if you are unavailable or prefer a more hands-off approach.
Managing Multiple Nodes If you hold more than one VeChain node, the Node Management feature allows you to manage all your nodes in one place. This simplifies the process of endorsing XApps, as you can easily allocate endorsements across multiple nodes without needing separate accounts.
Streamlined Management: Control multiple nodes through a single interface, allowing you to maximize your influence within the VeBetter ecosystem.
Unified Dashboard: View and manage all nodes and endorsements from a centralized dashboard for easy oversight.
Revoking Delegation If you delegate your endorsement rights, you can revoke them at any time. This option allows you to reassert control over your node’s endorsement activities or reassign delegation to someone else as your needs change.
Immediate Control: Take back management rights instantly through the UI whenever you decide.
Adaptable Partnerships: Adjust delegation to fit your preferred level of involvement in VeBetter at any time.
Transfer and Reassignment Protocol Should you decide to sell or transfer your VeChain node, the Node Management system makes the transition seamless. If your node is currently delegated, the new owner will need to revoke the existing delegation through the UI to assume full endorsement rights.
Clear Reassignment: Ensure the new owner can take full control, maintaining alignment with VeBetter’s endorsement policies.
Transparent Process: The UI provides clear instructions for both the current owner and the new owner to manage the transition smoothly.
Important Update:
Legacy node mechanics have been replaced by StarGate staking NFTs.
Learn how staking, delegation, and participation work now:
transferVOT3()
Governance
Withdraw VOT3 from treasury
transferVET()
Governance
Withdraw VET from treasury
transferTokens()
Governance
Withdraw any erc-20 token from treasury, address needs to be passed in so that contract can be interacted with
transferNFT()
Governance
Withdraw any NFT from treasury address needs to be passed in so that contract can be interacted with
convertB3TR()
Governance
Converts B3TR for VOT3
convertVOT3()
Governance
Converts VOT3 to B3TR



metadata (string): The JSON-formatted metadata string.
distributor (address): The address initiating the distribution.
import { ProviderInternalHDWallet, ThorClient, VeChainProvider, VeChainSigner } from "@vechain/sdk-network";
import { X2EarnRewardsPool } from "@vechain/vebetterdao-contracts";
const thor = ThorClient.fromUrl("https://mainnet.vechain.org");
const provider = new VeChainProvider(
thor,
new ProviderInternalHDWallet("your space separated mnemonic".split(" "))
);
const rootSigner = await provider.getSigner();
// Define metadata as an object
const metadata = {
"location": {
"city": "Berlin",
"country": "Germany",
"region": "EU"
},
"referral_source": "social_media",
"campaign_id": "earth_day_2025"
};
// Call the method
const x2EarnRewardsPoolContract = thor.contracts.load(
X2EarnRewardsPool.address.mainnet,
X2EarnRewardsPool.abi,
rootSigner as VeChainSigner
);
const tx = await x2EarnRewardsPoolContract.transact.distributeRewardWithProofAndMetadata(
APP_ID,
amount,
receiverAddress,
["link", "image"],
["https://link-to-proof.com", "https://link-to-image.com/1.png"],
["waste_mass"],
[100],
"User performed a sustainable action on my app",
JSON.stringify(metadata) // Convert metadata object to JSON string
);
await tx.wait();
5) Save changes

import {
ProviderInternalHDWallet,
ThorClient,
VeChainProvider,
VeChainSigner,
} from "@vechain/sdk-network";
import { X2EarnRewardsPool } from "@vechain/vebetterdao-contracts";
function rewardUser() {
// To transfer B3TR we first need to connect to the blockchain with
// a wallet capable of signing and broadcastisting transactions
const thor = ThorClient.at(process.env.NODE_URL || "");
const provider = new VeChainProvider(
thor,
new ProviderInternalHDWallet(
process.env.REWARD_SENDER_MNEMONIC?.split(" ") || []
)
);
const rootSigner = await provider.getSigner();
// Call the VeBetterDAO smart contract
const x2EarnRewardsPoolContract = thor.contracts.load(
process.env.X2EARN_REWARDS_POOL_ADDRESS || "",
X2EarnRewardsPool.abi,
rootSigner as VeChainSigner
);
const tx =
await x2EarnRewardsPoolContract.transact.distributeRewardDeprecated(
process.env.VEBETTERDAO_APP_ID || "",
10,
address,
JSON.stringify({
version: 2,
description: "User refilled water from a sustainable source",
proof: {
image: "https://image.png",
link: "https://twitter.com/tweet/1",
},
impact: {
carbon: 100,
water: 200
}
})
);
await tx.wait();
}
import "./interfaces/IX2EarnRewardsPool.sol";
contract MyContract {
function sendRewardWithMetadata() onlyAdmin {
// this declaration is needed because solidity has
// an issue with dynamic vs fixed-size arrays
string[] memory proofTypes = new string[](1);
proofTypes[0] = "link";
string[] memory proofUrls = new string[](1);
proofUrls[0] = action.proofUrl;
string[] memory impactTypes = new string[](1);
impactTypes[0] = "waste_mass";
uint256[] memory impactValues = new uint256[](1);
// let's pretend you have another function that calculates your impact
impactValues[0] = calculateWasteMass(
challenge.litterSize,
challenge.litterCount
);
IX2EarnRewardsPool x2EarnRewardsPool = IX2EarnRewardsPool(x2EarnRewardsPoolAddress);
// Constructing metadata JSON string
string memory metadata = '{"location":{"city":"Berlin","country":"Germany","region":"EU"},"referral_source":"social_media","campaign_id":"earth_day_2025"}';
// If distributeReward fails, it will revert
x2EarnRewardsPool.distributeRewardWithProofAndMetadata(
VBD_APP_ID,
rewardAmount,
receiver,
proofTypes,
proofUrls,
impactTypes,
impactValues,
"User participated in a solo cleanup",
metadata
);
}
}
import {
ProviderInternalHDWallet,
ThorClient,
VeChainProvider,
VeChainSigner,
} from "@vechain/sdk-network";
import { X2EarnRewardsPool } from "@vechain/vebetterdao-contracts";
const PRIVATE_KEY = ""
const ACCOUNT_ADDRESS_OF_PK = ""
function rewardUser() {
// To transfer B3TR we first need to connect to the blockchain with
// a wallet capable of signing and broadcastisting transactions
const thor = ThorClient.at(process.env.NODE_URL || "");
const wallet = new ProviderInternalBaseWallet(
[
{
privateKey: Buffer.from(
PRIVATE_KEY.slice(2),
'hex',
),
address: ACCOUNT_ADDRESS_OF_PK,
},
],
);
const provider = new VeChainProvider(
thor,
wallet,
false,
);
const signer = await provider.getSigner(
ACCOUNT_ADDRESS_OF_PK,
);
// Call the VeBetterDAO smart contract
const x2EarnRewardsPoolContract = thor.contracts.load(
process.env.X2EARN_REWARDS_POOL_ADDRESS || "",
X2EarnRewardsPool.abi,
rootSigner as VeChainSigner
);
const tx =
await x2EarnRewardsPoolContract.transact.distributeRewardDeprecated(
process.env.VEBETTERDAO_APP_ID || "",
10,
address,
JSON.stringify({
version: 2,
description: "User refilled water from a sustainable source",
proof: {
image: "https://image.png",
link: "https://twitter.com/tweet/1",
},
impact: {
carbon: 100,
water: 200
}
})
);
await tx.wait();
}
Background Check and Creator NFT Requirement: XApp creators begin by filling out a form on the VeBetter platform to initiate the process. If they pass the screening, they are minted a Creator NFT, which verifies them for participation in the endorsement process.
On-Chain XApp Submission: Once they have received the Creator NFT, XApp creators can submit their XApp on-chain for endorsement consideration. This submission officially registers the XApp on VeBetter platform, pending endorsements from VeChain node holders.
Connecting with Endorsers: After receiving the Creator NFT, XApp creators gain access to VeBetter Discord server, where they can connect with VeChain node holders who may endorse their XApp. This community platform allows them to build relationships with potential endorsers and formally submit their XApp for consideration on VeBetter platform.
XApp Endorsement: XApps must accumulate an endorsement score of 100 to become eligible for allocation rounds. Achieving this threshold enables an XApp to participate in weekly rounds to receive a share of the B3TR allocation pool.
VeChain node holders are key decision-makers in the X2Earn endorsement process. Each type of VeChain node, represented by an NFT in the holder’s wallet, has an assigned endorsement score based on its level. These scores determine the impact each endorsement has on an XApp’s eligibility.
Strength
2
Thunder
13
Mjolnir
50
VeThorX
3
StrengthX
9
ThunderX
35
A wallet can only hold one of these VeChain Node NFTs at a time, and to obtain a node, users must maintain a specific amount of VET in their wallet (see vechain nodes for more info). The cumulative endorsement scores from nodes determine an XApp’s eligibility to join VeBetter and participate in allocation rounds.
Once an XApp is endorsed, reaching a cumulative endorsement score of 100, it becomes eligible to receive funds in the allocation rounds. This eligibility can be adjusted by VeChain node holders based on the app's performance and compliance.
An XApp is officially considered endorsed when it accumulates an endorsement score of 100. This score is the sum of all VeChain node endorsements for the app. Upon reaching this threshold, the XApp automatically qualifies for the next XAllocation Voting round and will continue participating in future rounds as long as its score remains at or above 100.
Endorsement Limitations: Each VeChain Node NFT can endorse only one XApp at a time. Similarly, each account can endorse only one XApp unless it leverages the NodeManagement contract to delegate multiple VeChain nodes.
Endorsement Cap: Once an XApp reaches the endorsed status with a score of 100, it cannot receive additional endorsements from other nodes.
Node holders have the authority to withdraw their endorsement if they no longer wish to support a specific XApp. If an XApp’s score falls below the 100-point threshold, it enters a grace period. During this time, the XApp has a limited opportunity to regain endorsements and restore its score to 100. If it fails to meet this requirement before the grace period ends, it will be removed from the XAllocation voting round.
Retention of Past Allocations: Although the XApp is removed from future allocation rounds, it still retains any allocations received from previous rounds. The XApp may rejoin allocation rounds if it regains the necessary endorsement score of 100.
To ensure the consistency and validity of endorsements, VeBetter conducts periodic checks on endorsing nodes.
When your app is submitted to the contract an appId is generated by hashing the app name. This id cannot be updated in the future, even if you change the name of your app.
Authorized apps can report addresses they have banned, such as looters, bots or scammers. This helps VeBetter and other apps detect and defend against harmful activity across the ecosystem.
If an address is flagged by mistake, VeBetter or selected app admins can review the case and reset its signal counter.
Community Dashboard: https://vechain-energy.github.io/vebetterdao-signal-admin/ Build by the community, this dashboard shows all signaled wallets.
When an app is added the following information is saved on-chain:
name: the name of the app, cannot change once it's added.
app ID: is the hash of the name of the app (from the previous point) and it's used as a unique identifier across all the smart contracts; once the app is added and this ID is generated it cannot be updated.
receiver address: this is the address where the app will receive the allocation funds, also addressed to as "Treasury address".
creation timestamp: the timestamp when the app was added.
metadata URI: the IPFS CID containing all the information of the app, which will be used by the frontend to display the app details.
moderators: a list of addresses that can update the metadataURI of an app.
admin: this address can add/remove moderators, change the receiver address, transfer ownership to another admin, and update the metadata URI of the app.
The metadata URI needs to follow the following standard:

As a VeChain node holder within the VeBetter ecosystem, you play a vital role in selecting and supporting new XApps. Your endorsement not only enables promising applications to join the ecosystem but also allows you to influence the distribution of B3TR tokens through weekly allocation rounds. This guide will help you understand how endorsement works, the influence of your node type, and how you can manage endorsements effectively.
Endorsement is the process by which VeChain node holders support XApps (applications within the VeBetter ecosystem) for inclusion and funding eligibility. Each node holder can endorse one XApp at a time, and each endorsement carries a score based on the type of node held. Once an XApp accumulates enough endorsement points, it qualifies to join the VeBetter ecosystem and participate in weekly allocation rounds for B3TR tokens.
The influence of your endorsement depends on the type of VeChain node you hold. Each node type has a unique endorsement score, which contributes to an XApp’s cumulative endorsement score. Here is a breakdown of endorsement scores by node type:
VeChain Node Type
Endorsement Score
Strength
2
Thunder
13
Mjolnir
50
VeThorX
3
StrengthX
9
ThunderX
35
Note: These scores determine the weight of your endorsement. For example, a MjolnirX node endorsement contributes 100 points towards an XApp’s endorsement total, while a Strength node contributes 2 points.
Choose an XApp: Review the list of submitted XApps within the VeBetter platform. These XApps are seeking endorsements to qualify for entry into the ecosystem.
Endorse with Your Node: Select one XApp to endorse. Your endorsement adds the score of your node to the XApp’s cumulative endorsement score.
Qualification for Allocation Rounds: Once an XApp reaches a cumulative endorsement score of 100, it qualifies to join the VeBetter ecosystem and participate in weekly allocation rounds. This threshold ensures that only well-supported XApps gain access to ecosystem resources.
Node Cooldown Period: From Round 26, after endorsing an XApp, your VeChain node will enter a cooldown period during which you cannot change or withdraw your endorsement.
For mainnet, the cooldown period is set to 1 round. For example, if you endorse an XApp in Round 23, you will only be able to change your endorsement in Round 24.
Weekly Allocation Rounds: Endorsed XApps can participate in weekly allocation rounds, where they compete to receive B3TR tokens based on community voting. As an endorser, your influence supports the XApp’s eligibility for these rewards.
Using the VeBetter’s UI, you can easily manage your endorsements:
View Current Endorsements: Check which XApp you are currently endorsing and its current endorsement score.
Switch Endorsements: If you wish to change your endorsement, you can do so through the UI. Simply withdraw your current endorsement and select a new XApp to support.
Monitor XApp Progress: Track the cumulative endorsement scores of different XApps to see how close they are to reaching the 100-point threshold.
Track Cooldown Status: Monitor the cooldown status of your node through the UI to see when you will be eligible to make a new endorsement.
Single Endorsement Limit: Each node can endorse only one XApp at a time. If you wish to support another XApp, you must first remove your current endorsement.
Influence of Node Type: The endorsement score of your node directly impacts the XApp’s ability to qualify for the ecosystem. Higher-level nodes like MjolnirX provide more influence.
Endorsement Lock: Once an XApp reaches the 100-point threshold and joins the ecosystem, it cannot.
Node Cooldown Period: After endorsing an XApp, your node enters a cooldown period (1 round on mainnet). You cannot change or withdraw endorsements during this time. Within the cooldown period, app creators retain the ability to remove any node's endorsement from their XApp.
Important Update:
Legacy node mechanics have been replaced by StarGate staking NFTs.
Learn how staking, delegation, and participation work now:
Learn how to automate your weekly voting and reward claiming. A relayer service handles all transactions for you with a 10% fee (capped at 100 B3TR) to cover gas costs.
MVP Phase: Automation is currently in its MVP phase. Features, requirements, and fee structures are subject to change based on user feedback and operational requirements.
This feature allows you to automate your weekly voting and reward claiming process. Once enabled, a relayer service will automatically cast your votes and claim your rewards on your behalf each week.
Navigate to the page
Ensure you meet all eligibility
Select your preferred apps for auto-voting
Toggle-on Auto-voting & claim
To use this service, you must meet all of the following criteria at the time of snapshot:
Hold at least 1 VOT3 token in your wallet
Complete 3 sustainable actions before the snapshot
Not be flagged as a bot by any App owner
Have selected at least one eligible app for voting
If you enable automation during the current round, the service will kick in from the next round onwards.
What this means:
You’ll still need to manually claim your rewards when the current round ends.
Snapshot: At the start of each voting round, a snapshot is taken to determine eligible participants
Auto-Voting: The service automatically casts votes based on your selected app preferences
Auto-Claiming: After the round ends, your rewards are automatically claimed and deposited to your wallet
To cover the gas costs of automating your transactions, a 10% fee is applied to your weekly claimed rewards.
Fee Details:
Rate: 10% of your weekly rewards
Cap: Maximum fee of 100 B3TR per week
Benefit: You don't pay any gas fees directly. The service handles all transactions for you
Fee Example:
Your automation can be automatically disabled if any of the following occurs:
1. App Ineligibility
If all the apps you've selected for auto-voting become ineligible (removed or suspended), your automation will be turned off
Action required: Update your app selections to include eligible apps, then re-enable auto-voting
2. VOT3 Balance
If your VOT3 balance drops below 1 token at the time of snapshot
Action required: Ensure you maintain at least 1 VOT3 in your wallet
3. Stops Performing Sustainable Actions
If your drops below the threshold
Action required: Continue to perform sustainable actions to maintain your eligibility
4. Bot Detection
If you are flagged as a bot by any app owner during the snapshot
Action required: File an appeal and complete the KYC flow. Then you need to come back to the page to setup your automation again.
💡 Tip: Regularly check your automation status and app selections to ensure uninterrupted automation.
When auto-voting is active, you cannot vote or claim rewards manually. The service handles everything automatically.
Manual Claiming After 5 Days (Exception):
If the service hasn't claimed your rewards within 5 days after a round ends, you can claim them manually
This 5-day window ensures the automation service has enough time to process all auto-claims
Your rewards are always protected. You'll never lose them
⚠️ Remember: Once automation is active, sit back and let the service do its job. Manual claiming is only available as a backup after 5 days.
Your automation status will show one of three states the allocations page:
What it means: You just enabled auto-voting, but automation hasn't started yet
What happens:
Current round: You need to vote manually (if you haven't already)
Next round: Automation will automatically kick in
What it means: Auto-voting is fully active and working
What happens: The service automatically votes and claims rewards for you every week
No action needed: Sit back and relax. Everything is handled automatically
What it means: Auto-voting is now disabled
Why:
You just toggled-off the automation. It will be deactivated from the next round onwards
It's been toggled-off because you failed to maintain .
💡 Tip: Visit the DAO regularly to ensure automation remains active.
Need Help? If you have questions about auto-voting or encounter any issues, please contact our support team.
X2Earn Apps that send captured photos for image analysis to AI should consider adding specific tasks in their AI prompts to detect:
Image quality
Doctored or Unrealistic modifications
Photo of a computer screen
Watermarks
Painted or hand-drawn text replacing real data
... or other unrealistic items that a "fake" photo could capture.
In this example we are assuming that we are taking a photo from a dApp runs inside VeWorld and so the photo will be captured by the users mobile camera.
The backend of the app would like the AI to return a json structure giving:
Where:
We can use a multi-stage prompt to guide the AI through these tasks:
Anyone holding VOT3 is a member of VeBetter and can take part in voting events. VOT3 is the VeBetter’s governance token, required to vote, and obtained by swapping from B3TR at a 1:1 ratio. All members can vote on proposals, participate in governance discussions, and access the Treasury, with the only minimum requirement of holding at least 1 VOT3 token. This ensures we can foster an inclusive, engaging environment for everyone.
The proof will be stored on-chain in the form of an emitted event and will have the following JSON format:
You will provide this proof as a parameter when calling the distribute rewards function in the X2EarnRewardsPool contract.
proofTypes: an array with the proof types that you are providing. Eg:
B3TR tokens are distributed weekly through VeBetter’s emissions system and sent to two separate reward pools:
Vote2Earn Pool: Incentivizes all users to participate by rewarding them based on their VOT3 token balance
GM Rewards Pool (New: ): Provides additional rewards to users who hold a GM NFT and vote during the cycle, with rewards based on the reward weight of their GM NFT level
To earn from either pool, you must cast a valid vote in a governance or allocation round during the cycle.
{
"name":"My sustainable app",
"description":"Run and get rewarded",
"external_url":"https://openseacreatures.io/3",
"logo":"https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png",
"header_image":"https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png",
"screenshots":[
"https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png",
"https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png",
"https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png"
],
"social_urls":[
{
"name":"YouTube",
"url":"https://www.youtube.com/@DLoaw"
},
{
"name":"Instagram",
"url":"https://www.instagram.com/@DLoaw"
}
],
"app_urls":[
{
"code":"play_store",
"url":"https://www.playstore.com/@DLoaw"
},
{
"code":"apple_store",
"url":"https://www.applestore.com/@DLoaw"
},
{
"code":"web_app",
"url":"https://www.myapp.com"
}
],
"tweets": [],
"categories": ["nutrition", "education-learning"]
}MjolnirX
100
MjolnirX
100
That's it! Your votes and rewards will be handled starting from next week onwards.
✅ Full gas paid
Why the delay: Auto-voting activates at the beginning of the next round to ensure a clean start with the snapshot
500 B3TR
50 B3TR
450 B3TR
✅ Full gas paid
1,500 B3TR
100 B3TR*
1,400 B3TR
✅ Full gas paid
5,000 B3TR
100 B3TR*
4,900 B3TR

evaluation_feasible
True if the quality of the image is sufficient to perform other checks, False if the quality is poor and other checks could be unreliable
doctored_unrealistic_score doctored_unrealistic_reasons
A score between 0-1 if the AI has detected doctored or unrealistic items in the image. The reasons array will be populated with a summary
screen_capture_score screen_capture_reasons
A score between 0-1 if the AI has detected that the image was taken from a computer screen. The reasons array will be populated with a summary
watermark_score watermark_reasons
A score between 0-1 if the AI has detected that the image contains watermarks.
The reasons array will be populated with a summary
painted_text_score painted_text_reasons
A score between 0-1 if the AI has detected user drawn text in the image. The reasons array will be populated with a summary
final_label final_score
A final classification label of:
clean
doctored_unrealistic
screen_capture
watermarked
handdrawn
multiple_flags
inconclusive
A final score between 0-1 as the level of confidence in the classification
["link", "image"]proofValues: an array with the values of the types provided in the previous array. Eg: ["https://twitter.com/tweet/1233121231", "https://whatever.com/image.png"]
impactCodes: an array with the codes of impacts you are providing. Eg:
["water", "timber"]
impactValues: an array with the values of the impacts provided in the previous array. Eg:
[1000, 23]
description: you can attach also a description to your action, it's optional.
When calling this function it is mandatory to provide at least proof or impact, if none of them is provided then the transaction will revert.
The transaction will revert also if something is wrong with the data you pass.
To provide proofs and impacts you need to distribute the rewards through the X2EarnRewardsPool contract with the following function:
You can attach proof of the user's sustainable action when you distribute the reward. The proof can be a link, video, photo, and text. You can provide more than one proof (eg: a photo and a link).
The current proof types supported are:
Determining the environmental impact of each sustainable action will require the development of a set of criteria and metrics for each type of action.
Warning: the impact values MUST be a number and the unit is considered the default minimum (so milliliters, grams, wh, etc.). So if you saved 1 litter of water then you should put it as an impact of "water" : "1000".
Carbon Footprint Reduction
Key: carbon
Description: Measures the decrease in greenhouse gas emissions.
Metric: Grams (g) of CO2 equivalent reduced or removed.
Resource Conservation
Key: water (for water conservation), energy (for electricity conservation)
Description: Assesses the reduction in the use of natural resources like water, electricity, and raw materials.
Metric: Milliliters (ml) of water saved, watt-hours (Wh) of electricity saved.
Waste Reduction
Key: waste_mass
Description: Evaluates the decrease in waste generated and improves waste management.
Metric: Grams (g) of waste diverted from landfills, number of items recycled.
Timber Conservation
Key: timber
Description: Measures the reduction in the use or waste of timber resources.
Metric: Grams (g) of timber saved.
Plastic Reduction
Key: plastic
Description: Evaluates the decrease in the use or waste of plastic materials.
Metric: Grams (g) of plastic saved or reduced.
Education Time
Key: education_time
Description: Measures the amount of time a user spends learning about a sustainability topic.
Metric: Seconds spent learning.
Trees Planted
Key: trees_planted
Description: Tracks the number of trees planted as part of sustainability efforts.
Metric: Number of trees planted.
Calories Burned
Key: calories_burned
Description: Measures the energy expenditure from physical activity or exercise, promoting health and sustainability.
Metric: Calories (kcal) burned.
Sleep Quality
Key: sleep_quality_percentage
Description: Assesses the quality of sleep as a percentage, encouraging better health and productivity.
Metric: Percentage (%) of sleep quality improvement.
Clean Energy Production
Key: clean_energy_production_wh
Description: Measures the amount of clean energy produced, contributing to sustainable energy solutions.
Metric: Watt-hours (Wh) of clean energy generated.
The following are the impact codes you will need to use:
If no "version" field is found in the the json proof then you should consider it as version 1.
Deprecated impacts:
If you want to store additional data beyond impacts or proofs, you might consider using the reward metadata function, which allows you to include other meaningful extra information. Go to Reward Metadata Docs
{
"evaluation_feasible": true,
"doctored_unrealistic_score": 0.0,
"doctored_unrealistic_reasons": [],
"screen_capture_score": 0.0,
"screen_capture_reasons": [],
"watermark_score": 0.0,
"watermark_reasons": [],
"watermark_text": "",
"painted_text_score": 0.0,
"painted_text_reasons": [],
"final_label": "clean",
"final_confidence": 0.0
}Mobile Photo Authenticity Check — Multi-Stage Prompt
Objective:
Given a photo provided by a mobile device, evaluate it through multiple analytical stages to determine:
1. If the photo has been doctored or altered in an unrealistic way.
2. If the photo has been taken from a computer screen rather than being an original capture of a real-world scene.
3. If the photo contains visible or partially obscured watermarks.
Instructions:
You must progress through the stages in sequence. At each stage, clearly indicate whether the photo passes or fails, and explain the reasoning.
Output:
Return only the final JSON object in the specified schema—no extra text.
---
STAGE 1 — Quick Triage (visibility & quality):
1. Is the content visible and in focus enough to evaluate?
2. Are there heavy obstructions, extreme blur, or tiny resolution?
3. If evaluation is not feasible, mark `evaluation_feasible=false` and explain briefly.
---
STAGE 2 — “Doctored / Unrealistic” Screening:
Check for visual signs of synthetic or manipulated content. Consider:
- Physics & geometry: inconsistent shadows, impossible reflections, mismatched perspective/vanishing points, warped straight lines near edits.
- Material cues: plastic-like skin, repeated textures, smeared hair/eyelashes, “melting” edges, duplicated fingers/ears.
- Edge artifacts: halos, cut-out borders, fringing, mismatched depth of field.
- Compression anomalies: localized blockiness/quality shifts suggesting pasted regions.
- Lighting: inconsistent color temperature or specular highlights vs. environment.
- Text & patterns: deformed text/logos, repeated tiling.
- Context coherence: scale mismatches, impossible combinations.
Output:
- `doctored_unrealistic_score` (0–1)
- `doctored_unrealistic_reasons` (bullet list)
---
STAGE 3 — “Photo of a Screen” Screening:
Evidence the subject was displayed on a digital screen and re‑photographed:
- Screen structure: visible pixel grid/subpixels, scanlines, PWM/refresh bands, moiré.
- Device clues: bezels, notch, status bar, window chrome, cursor, taskbar, scroll bars.
- Optical clues: rectangular glare, Newton rings, rainbowing consistent with glass.
- Focus/parallax: focus on flat screen surface; keystone perspective of a monitor.
- White point/gamut: uniform backlight glow, overly blue/green whites.
Output:
- `screen_capture_score` (0–1)
- `screen_capture_reasons` (bullet list)
---
STAGE 4 — Watermark / Overlay Detection:
Detect watermarks or ownership/stock overlays that may indicate non-original content or re-use:
- Typical forms: semi-transparent text/logos (“Getty Images”, “Shutterstock”, “Adobe Stock”, creator handles), diagonal repeating patterns, corner logos, date/time stamps that appear composited.
- Visual traits: consistent alpha translucency, uniform repetition across the frame, crisp overlay unaffected by scene lighting/perspective, different resolution/sharpness vs. underlying image.
- Placement: along edges/corners/center diagonals; multiple repeats; patterned tiling.
- Edge cases: legitimate **camera UI overlays** (e.g., timestamp) vs. stock watermarks—distinguish when possible.
- Context: if a watermark is present, note its content (if legible) but **do not identify a person**.
Output:
- `watermark_score` (0–1)
- `watermark_reasons` (bullet list)
- If confidently recognized, add a short `watermark_text` string (e.g., `"Shutterstock"`, `"creator handle @name"`); otherwise empty.
---
STAGE 5 - Detect Hand-Drawn or Painted-On Text:
Detect if the image has text that was manually added using a paint or drawing program, rather than being part of the original scene:
- Look for uneven, non font based handwriting or shapes inconsistent with printed text
- Identify brush strokes, smudging, or digital pen artifacts in the text
- Detect text blending poorly with the image background or overlapping objects unnaturally
- Check for consistent resolution between the text and the rest of the image
Output:
- `painted_text_score` (0-1)
- `painted_text_reasons` (bullet list)
---
STAGE 6 — Final Decision & Confidence:
- `evaluation_feasible`: boolean.
- `final_label`: one of `"clean"`, `"doctored_unrealistic"`, `"screen_capture"`, `"watermarked"`, `handdrawn`, `"multiple_flags"`, `"inconclusive"`.
- `final_confidence` (0–1): overall confidence in `final_label`.
- Keep reasoning concise; cite visible cues only.
---
OUTPUT — JSON Schema (return only this):
{
"evaluation_feasible": true,
"doctored_unrealistic_score": 0.0,
"doctored_unrealistic_reasons": [],
"screen_capture_score": 0.0,
"screen_capture_reasons": [],
"watermark_score": 0.0,
"watermark_reasons": [],
"watermark_text": "",
"painted_text_score": 0.0,
"painted_text_reasons": [],
"final_label": "clean",
"final_confidence": 0.0
}import { ProviderInternalHDWallet, ThorClient, VeChainProvider, VeChainSigner } from "@vechain/sdk-network"
import { X2EarnRewardsPool } from "@vechain/vebetterdao-contracts"
const thor = ThorClient.fromUrl("https://mainnet.vechain.org")
const provider = new VeChainProvider(
thor,
new ProviderInternalHDWallet("your space separated mnemonic".split(" ")),
)
const rootSigner = await provider.getSigner()
// Call the method
const x2EarnRewardsPoolContract = thor.contracts.load(X2EarnRewardsPool.address.mainnet, X2EarnRewardsPool.abi, rootSigner as VeChainSigner)
const tx = await x2EarnRewardsPoolContract.transact.distributeRewardWithProof(
APP_ID,
amount,
receiverAddress,
["link", "image"],
["https://link-to-proof.com", "https://link-to-image.com/1.png"],
["waste_mass"],
[100],
"User performed a sustainable action on my app",
)
await tx.wait()import "./interfaces/IX2EarnRewardsPool.sol";
contract MyContract {
function sendReward() onlyAdmin {
// this declaration is needed because solidity has
// an issue with dynamic vs fixed-size arrays
string[] memory proofTypes = new string[](1);
proofTypes[0] = "link";
string[] memory proofUrls = new string[](1);
proofUrls[0] = action.proofUrl;
string[] memory impactTypes = new string[](1);
impactTypes[0] = "waste_mass";
uint256[] memory impactValues = new uint256[](1);
// let's pretend you have another function that calculates your impact
impactValues[0] = calculateWasteMass(
challenge.litterSize,
challenge.litterCount
);
IX2EarnRewardsPool x2EarnRewardsPool = IX2EarnRewardsPool(x2EarnRewardsPoolAddress);
// If distributeReward fails, it will revert
x2EarnRewardsPool.distributeRewardWithProof(
VBD_APP_ID,
rewardAmount,
receiver,
proofTypes,
proofUrls,
impactTypes,
impactValues,
"User participated in a solo cleanup"
);
}
}
{
version: 2,
description: 'The description of the action',
proof: {
image: 'https://image.png',
link: 'https://twitter.com/tweet/1'
},
impact: {
carbon: 100,
water: 200
}
}"image"
"link"
"text"
"video""carbon"
"water"
"energy"
"waste_mass"
"education_time",
"timber"
"plastic"
"trees_planted"
"calories_burned"
"sleep_quality_percentage"
"clean_energy_production_wh"{
"app_name": "cleanify",
"action_type": "litter_picking",
"proof": {
"proof_type": "link",
"proof_data": "https://x.com/TengMab95659/status/1814152547202195788"
},
"metadata": {
"description": "@TengMab95659 picked up 8 small pieces of litter.",
"additional_info": ""
},
"impact": {
"waste_mass": "300",
"biodiversity": "1"
},
}waste_items
people
biodiversityAt launch, VeBetter will adhere to an initial set of governance rules until it has run for one year without any technical interruptions. The Stabilization Period is critical for ensuring the long-term efficacy and viability of VeBetter. To prevent exploits during the Stabilization Period, VeChain Foundation maintains the ability to pause & restart B3TR token minting, only in the case of an exploit or other major issue. Once the requirements of the Stabilization Period have been met, community stakeholders can maintain or deprecate this functionality through governance.
Proposals are the backbone of any DAO, and the community is a key part of the proposal process. VeBetter will maintain a forum for proposal submission, discussion, and voting. The forum will feature a dashboard detailing voting results, historical records, and proposal details. For a proposal to reach the final stages and be implemented, it must go through a predefined process, including initial forum-based community discussion, and a community ‘temperature check,’ before on-chain voting and implementation.
Every time a proposal is created, a deposit threshold of VOT3 tokens—calculated as a percentage of the total supply of B3TR—must be met for the proposal to become active. This deposit acts as a temperature check: if the community believes the proposal is worth considering, members can contribute VOT3. If the threshold is reached before the end of the waiting period, the proposal becomes active; otherwise, it is automatically cancelled.
Users can withdraw their VOT3 deposits once the proposal is cancelled or the voting period starts. While tokens are locked for supporting a proposal, they cannot be transferred or used to support other proposals during that time.
However, these locked VOT3 are still included in the allocation snapshot and grant the holder additional voting power in allocation rounds. This means that if we are in Round #2 and you support a proposal that will start in Round #4, your locked tokens will still count toward your allocation voting power in Rounds #3 and #4, even though you cannot redeploy them elsewhere.
The governance process is the following: propose → vote → execute if succeeded.
Let's break it down:
Hold a GM Moon NFT
Upgrade your Earth GM NFT to a GM Moon NFT, or purchase one.
If you don’t hold an Earth GM NFT, you must participate in at least one vote to earn eligibility.
Create a Discourse Thread
Open a discussion about your proposal on the VeChain Discourse forum at least 3 days before submitting it.
This ensures community feedback before the proposal goes live.
When drafting a proposal, include:
Description: Explain what you want to achieve.
Action: They are 2 type of actions possible to pass DAO proposal, Actionnable proposal ( transfer funds from the treassury for a specific purpose, and non-actionable, but propositions.
They are 2 type of governance proposals :
There are two types of DAO proposals:
Actionable Proposals
Trigger an on-chain action, usually involving the treasury or contract calls.
Non-Actionable Proposals
Express ideas or directions without immediate on-chain execution.
Even if approved, this requires off-chain development or coordination before being implemented.
Trigger an on-chain action, usually involving the treasury or contract calls.
During this waiting period, there is a temperature check and the community must fund the proposal with VOT3 tokens. Each deposits made by the user are counted into the allocation voting as more voting power.
Each proposal has a deposit threshold to reach, and if this threshold is not reached, then the proposal gets automatically cancelled. The proposal can be cancelled by the user who created it or by an admin of the DAO.
Once the proposal is active, a snapshot of the total supply of VOT3 tokens and balances of each VOT3 holder is taken and used to calculate individual voting power, and VOT3 holders can vote AGAINST/YES/ABSTAIN for that proposal. Each proposal will remain active for the duration of the round. When you cast your vote, all 100% of your voting power will be used.
Quorum is 30% of the total supply of VOT3. All types of votes (yes, no and abstain) are considered when calculating if quorum is reached.
Voting rewards are distributed regardless of what type of vote was cast.
If a quorum is not reached then the proposal is considered defeated.
If a quorum is reached then "yes" and "no" votes are counted, if "yes" votes are more than "no" votes then the proposal is considered succeeded.
Voting rewards are distributed regardless of the vote outcome.
The VeBetter's Governance contract can execute actions on all contracts deployed on the VeChainThor blockchain, provided the respective contracts permit those actions.
We added a timelock to governance decisions, this allows users to exit the system if they disagree with a decision before it is executed. We are using OpenZeppelin’s TimelockController in combination with the GovernorTimelockControl module to achieve this. To execute a proposal, it first needs to be queued to Timelock contract and wait a specified amount of time before being able to execute it.
Initially, only selected admins will be able to execute proposals.
For DAOs that use the Governor contract (as we do), only delegated tokens can participate in voting. What does this mean for you, a token holder?
You must set up delegation if you want to participate in governance votes. This includes delegating to others or voting yourself.
If you wish to vote on proposals directly, delegate your voting power to your own address. Or, you can delegate your voting power to another community member and let them vote on your behalf.
Currently, we have an auto-delegation feature in our smart contract that will automatically delegate to you when you convert B3TR to VOT3 or someone sends you VOT3 tokens. However, this auto-delegation feature is not enabled for smart contracts, so if you are writing a smart contract that wants to receive VOT3 tokens and participate in governance you will need to manually delegate. This needs to be done only once.
Quadratic Voting (QV) is a method used to re-calibrate voting power within VeBetter, specifically for the B3TR Governance model. Unlike traditional voting mechanisms that may disproportionately empower large token holders, QV modifies this by determining voting power based on the square root of the number of VOT3 tokens held. This approach ensures that while voting power increases with more tokens, it does so at a diminishing rate.
The formula shown below reduces the influence larger stakeholders might have, promoting a more balanced and fair decision-making process.
Each voter casts their vote as FOR, AGAINST, or ABSTAIN on proposals, with the effective weight of these votes directly linked to their recalculated voting power. This structure not only aligns with standard quadratic voting practices but also ensures governance is more reflective of the wider community preferences.
By default, QV is enabled for all voting rounds. However, governance and admins can choose to disable QV, switching to linear voting. In linear voting, voting power is directly proportional to the number of VOT3 tokens a user holds.
Important Note: If QV is disabled by an admin during an ongoing round, the change will only take effect starting from the next round.
The following parameters can be updated by governance:
Quorum: currently set at 30% of total VOT3 supply
Deposit Threshold: percentage of the total supply of B3TR tokens that need to be deposited in VOT3 to create a proposal, currently set at 2%
Voting Threshold: the minimum amount of tokens needed to cast a vote, currently set at 1
Minimum Voting Delay: the minimum delay a proposal must be in a PENDING state before voting can start, currently set at 3 days
Timelock Minimum Delay: time to wait before a proposal can be executed after it was queued
Voting Period: While this value can be updated in the governance contract, it must be equal to or shorter than the Emissions Cycle. To extend the Voting Period beyond the current cycle, you must first update the Emissions Cycle duration.
Enable / Disable Functions Restrictions: if disabled there isn't any restriction on what contracts and functions can be called when creating a proposal
Whitelist Functions: if function restrictions are enabled then whitelist a target and function
VeBetter uses an upgradeable NFT system called the Galaxy Member (GM) NFT to reward committed community members. By holding a GM NFT and voting in a cycle, you become eligible to receive a portion of the GM Rewards Pool, which distributes 5% of weekly B3TR emissions.
The higher your GM NFT level, the greater your reward weight, determining your share of the GM pool during that voting cycle.
There are two ways to upgrade your GM NFT:
Level
Name
B3TR Required
Reward Weight
2
Moon
5,000 B3TR
1.1
3
Mercury
12,500 B3TR
1.2
4
Venus
25,000 B3TR
1.5
Maximized Rewards:
Higher GM NFT levels increase your reward weight in the GM Rewards Pool — earn more B3TR when you vote.
Flexibility:
Use B3TR for upgrades or enjoy free upgrades as a VeChain Node holder.
Dynamic Participation:
Play an active role in VeBetter and get rewarded for your engagement across both governance proposals and XAllocation votes.
By upgrading your GM NFT and participating in governance (via voting on governance proposal or XAllocation vote), you unlock enhanced rewards through the GM Rewards Pool, which distributes 5% of weekly B3TR emissions. This not only boosts your personal rewards but also reinforces your long-term role in shaping the VeBetter ecosystem.
After a successful DAO proposal the rewards earned by participating in VeBetter governance are linear (instead of quadratic) starting from round 23, which means that you earn rewards proportionally to your VOT3 holdings at the time of the snapshot.
Where
= VOT3 balance of user i when voting on proposal v
= all proposals (Governance and XAllocation Voting) in the cycle the user participated in
= all users who voted on any proposal during the cycle
= total Vote2Earn reward pool for the cycle
Total participants: 1,000 voters
Vote2Earn Emissions: 1,000,000 B3TR
User’s VOT3 snapshot for cycle: 10,000
Total VOT3 across all voters and all proposals in the cycle: 5,300,000
User voted on 1 proposal
Calculation:
This voter’s 10,000 VOT3 represents 0.1887% of the total VOT3 submitted during the cycle, earning them 1,886.79 B3TR from the Vote2Earn reward pool.
The GM Rewards Pool was introduced via a successful DAO proposal in April 2025. It distributes 5% of weekly B3TR emissions to Galaxy Member (GM) NFT holders (Moon tier and above) who vote during a cycle.
Participation includes both governance proposals and XAllocation votes — all voting items within a cycle count.
Rewards are calculated using a linear model based on the user's GM NFT level and the number of votes you cast during the cycle. The higher your NFT level — and the more proposals you vote on — the greater your share of the GM Rewards Pool.
Where
= reward weight of user i when voting on proposal v (based on GM NFT level)
= all proposals (Governance and XAllocation Voting) in the cycle the user participated in
= all users who voted with a GM NFT during the cycle
= 5% of total B3TR emissions for the cycle
Scenario:
GM Rewards Pool this cycle: 50,000 B3TR
User A: Neptune-level GM (reward weight = 10), votes on 2 proposals
User B: Mars-level GM (reward weight = 2), votes on 2 proposals
User C: Galaxy-level GM (reward weight = 25), votes on 1 proposal
Total Reward Weight in the Cycle:
User A:
User B:
User C:
Total Weight:
Reward Calculations:
User A: Reward = B3TR
User B: Reward = B3TR
User C: Reward = B3TR
Quadratic Rewarding (QR) in VeBetter is the approach used for distributing voting rewards. Under QR approach, the rewards a user receives will be determined by the square root of their VOT3 token holdings. This method ensures that while users with more tokens still receive higher rewards, the rate of increase in rewards does not grow linearly with the number of tokens held. Instead, it rises at a decreasing rate, promoting a fairer distribution of rewards and helping to close the wealth gap within our community.
5
Mars
50,000 B3TR
2
6
Jupiter
125,000 B3TR
2.5
7
Saturn
250,000 B3TR
3
8
Uranus
1,250,000 B3TR
5
9
Neptune
2,500,000 B3TR
10
10
Galaxy
12,500,000 B3TR
25




List and description of all smart contracts of VeBetter.
Contracts can be found at the following repository: https://github.com/vechain/vebetterdao-contracts
The VeBetter smart contracts have undergone a comprehensive audit by Hacken.
Putting it all together we get a picture of the connections of all smart contracts with hierarchies and usages between each other.
The following is the list of all smart contracts listed alphabetically:
This contract governs the issuance and management of B3TR fungible tokens within the VeBetter ecosystem, allowing for minting under a capped total supply.
Extends ERC20 Token Standard with capping, pausing, and access control functionalities to manage B3TR tokens in the VeBetter ecosystem.
Address: 0x5ef79995FE8a89e0812330E4378eB2660ceDe699
This contract implements an upgradeable proxy for all of our upgradeable contracts. It is upgradeable because calls are delegated to an implementation address that can be changed. This address is stored in storage in the location specified by https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the implementation behind the proxy.
Forked from Openzeppelin.
This contract is the main governance contract for the VeBetter ecosystem. Anyone can create a proposal to both change the state of the contract, to execute a transaction on the timelock or to ask for a vote from the community without performing any on-chain action. In order for the proposal to become active, the community needs to deposit a certain amount of VOT3 tokens. This is used as a heath check for the proposal, and funds are returned to the depositors after vote is concluded. Votes for proposals start periodically, based on the allocation rounds (see xAllocationVoting contract), and the round in which the proposal should be active is specified by the proposer during the proposal creation.
A minimum amount of voting power is required in order to vote on a proposal. The voting power is calculated through the quadratic vote formula based on the amount of VOT3 tokens held by the voter at the block when the proposal becomes active.
Once a proposal succeeds, it can be executed by the timelock contract.
The contract is upgradeable and uses the UUPS pattern.
Manages the governance process for the VeBetter ecosystem, allowing users to create and vote on proposals with VOT3 token deposits. This contract leverages OpenZeppelin's AccessControl and UUPSUpgradeable libraries for role-based access control and upgradeability. The core functionality, including proposal management, voting mechanisms, quorum calculations, and deposit logic, is modularly organized in external libraries, ensuring maintainability, flexibility, and ease of upgrades.
Address: 0x1c65C25fABe2fc1bCb82f253fA0C916a322f777C
This contract is responsible for the scheduled distribution of emissions based on predefined cycles and decay settings.
Manages the periodic distribution of B3TR tokens to XAllocation, Vote2Earn, and Treasury allocations. This contract leverages openzeppelin's AccessControl, ReentrancyGuard, and UUPSUpgradeable libraries for access control, reentrancy protection, and upgradability.
Address: 0xDf94739bd169C84fe6478D8420Bb807F1f47b135
This contract manages the unique assets owned by users within the Galaxy Member ecosystem.
Extends ERC721 Non-Fungible Token Standard basic implementation with upgradeable pattern, burnable, pausable, and access control functionalities.
Address: 0x93B8cD34A7Fc4f53271b9011161F7A2B5fEA9D1F
This contract is part of the legacy node system. Active participation now uses StarGate staking NFTs.
This contract acts as a proxy between VeChain Node Contracts and VeBetter, enabling node holders to delegate and manage multiple nodes within a single account.
Address: 0xB0EF9D89C6b49CbA6BBF86Bf2FDf0Eee4968c6AB
This contract is used to perform the actions of the B3TRGovernor contract with a time delay. The proposers and executors roles should be assigned only to the B3TRGovernor contract.
Address: 0x7B7EaF620d88E38782c6491D7Ce0B8D8cF3227e4
This contract is designed to manage all assets owned by the VeBetter
This contract handles the receiving and transferring of assets, leveraging upgradeable, pausable, and access control features.
Address: 0xD5903BCc66e439c753e525F8AF2FeC7be2429593
This contract governs the issuance and management of VOT3 tokens, which are the tokens used for voting in the VeBetter Ecosystem.
Extends ERC20 Fungible Token Standard basic implementation with upgradeability, pausability, ability for gasless transactions and governance capabilities.
Address: 0x76Ca782B59C74d088C7D2Cce2f211BC00836c602
This contract handles the rewards for voters in the VeBetter ecosystem. It calculates the rewards for voters based on their voting power and the level of their Galaxy Member NFT.
The contract is
upgradeable using UUPSUpgradeable.
using AccessControl to handle the admin and upgrader roles.
using ReentrancyGuard to prevent reentrancy attacks.
using Initializable to initialize the contract.
Address: 0x838A33AF756a6366f93e201423E1425f67eC0Fa7
This contract handles the x-2-earn applications of the VeBetter ecosystem. The contract allows the insert, management, and eligibility of apps for the B3TR allocation rounds.
The contract is using AccessControl to handle the admin and upgrader roles. Only users with the DEFAULT_ADMIN_ROLE can add new apps, set the base URI, and set the voting eligibility for an app. Admins can also control the app metadata and management. Each app has a set of admins and moderators (built without using AccessControl) that can manage the app metadata and management.
Address: 0x8392B7CCc763dB03b47afcD8E8f5e24F9cf0554D
This contract is designed to manage new XApp submissions within VeBetter, ensuring only verified creators can enter the ecosystem. This contract supports Creator NFTs, non-transferable ERC721 tokens, to grant creators access to the endorsement process.
Extends ERC721 Non-Fungible Token Standard basic implementation with upgradeable pattern, pausable, and access control functionalities.
Address: 0xe8e96a768ffd00417d4bd985bec9EcfC6F732a7f
This contract is used by x2Earn apps to reward users that performed sustainable actions. The XAllocationPool contract or other contracts/users can deposit funds into this contract by specifying the app that can access the funds.
Admins of x2Earn apps can withdraw funds from the rewards pool, which are sent to the team wallet address. The contract is upgradeable through the UUPS proxy pattern and UPGRADER_ROLE can authorize the upgrade.
Address: 0x6Bee7DDab6c99d5B2Af0554EaEA484CE18F52631
This contract receives B3TR tokens from the Emissions contract and distributes them to the rewards pool contract and x2earn apps based on the allocation round outcome. Funds can be claimed at the end of each allocation round.
Interacts with the Emissions contract to get the amount of B3TR available for distribution in each round, and the x2EarnApps contract to check app existence and receiver address. The contract is using AccessControl to handle roles for upgrading the contract and external contract addresses.
Address: 0x4191776F05f4bE4848d3f4d587345078B439C7d3
This contract handles the voting for the most supported x2Earn applications through periodic allocation rounds. The user's voting power is calculated on his VOT3 holdings at the start of each round, using a "Quadratic Funding" formula.
Rounds are started by the Emissions contract. Interacts with the X2EarnApps contract to get the app data (eg: app IDs, app existence, eligible apps for each round). Interacts with the VotingRewards contract to save the user from casting a vote. The contract is using AccessControl to handle roles for admin, governance, and round-starting operations.
Address: 0x89A00Bb0947a30FF95BEeF77a66AEdE3842Fe5B7
The B3TR Multisig contract facilitates multisignature operations for enhanced security and collaborative management of the wallet. This contract requires approvals from multiple stakeholders before any transaction can be executed, ensuring that all actions are transparent and consensual.
This contract is not upgradable.
This contract receives surplus B3TR allocations from XAllocationPool, and was created to execute the following proposal:
Initially acts as a wallet/treasury where the VeBetter team can manually distribute surplus allocations to eligible apps.
Address: 0x98c1d097c39969bb5de754266f60d22bd105b368
This contract manages the reward distribution system for relayers who facilitate auto-voting functionality in the VeBetter ecosystem. Relayers perform voting actions on behalf of users who have enabled auto-voting, and earn proportional rewards based on their completed voting actions.
The pool accumulates fees collected from voter rewards when users participate through the auto-voting mechanism. Relayers can claim their proportional share of rewards based on the number of weighted voting actions they successfully complete during each round.
Address: 0x34b56f892c9e977b9ba2e43ba64c27d368ab3c86
Some contracts (eg: B3TRGovernor) store their logic inside libraries to optimize the contract size. The following is the list of libraries we created and the addresses they are deployed to.
Library for managing the clock logic as specified in EIP-6372, with fallback to block numbers.
This library interacts with the IVOT3 interface to get the clock time or mode.
Library for managing the configuration of a Governor contract.
This library provides functions to set and get various configuration parameters and contracts used by the Governor contract.
Library for managing deposits related to proposals in the Governor contract.
This library provides functions to deposit and withdraw tokens for proposals, and to get deposit-related information.
Library for managing function restrictions within the Governor contract.
This library provides functions to whitelist or restrict functions that can be called by proposals.
Library for managing proposals in the Governor contract.
This library provides functions to create, cancel, execute, and validate proposals.
Library for managing quorum numerators using checkpointed data structures.
Library for Governor state logic, managing the state transitions and validations of governance proposals.
Library for handling voting logic in the Governor contract.
We are using UUPS proxy for our upgradeable contracts. You can read more about it here:.
In B3TRGovernor, we are utilising libraries inside some of the modules. To upgrade the functionalities inside these libraries the following steps must be done.
Update library
Deploy new library
Deploy new implementation contract connecting updated library with new library address
Upgrade the proxy to use this new implementation smart contract using the upgradeToAndCall function .
following the ERC-7201 standard for storage layout.
Yes
UPGRADER_ROLE
NodeManagement (legacy)
Yes
UPGRADER_ROLE
Timelock
Yes
UPGRADER_ROLE
Treasury
Yes
UPGRADER_ROLE
VOT3
Yes
UPGRADER_ROLE
VoterRewards
Yes
UPGRADER_ROLE
X2EarnApps
Yes
UPGRADER_ROLE
X2EarnCreators
Yes
UPGRADER_ROLE
X2EarnRewardsPool
Yes
UPGRADER_ROLE
XAllocationPool
Yes
UPGRADER_ROLE
XAllocationVoting
Yes
UPGRADER_ROLE
B3TR Multisig
No
GrantsManager
Yes
UPGRADER_ROLE
RelayersRewardsPool
Yes
UPGRADER_ROLE
DynamicBaseAllocationPool
Yes
UPGRADER_ROLE
RelayerRewardsPool
Yes
UPGRADER_ROLE
Contract
Upgradable
Authoriser
B3TR
No
B3TRProxy
No
B3TRGovernor
Yes
Governance OR DEFAULT_ADMIN
Emissions
Yes
UPGRADER_ROLE
GalaxyMember
👉 Learn how staking NFTs work in StarGate:
As a VeChain Node holder, you have unique opportunities to enhance your participation in the ecosystem. By linking your VeChain Node to a Galaxy Member (GM) NFT, you can unlock additional rewards, boost your GM NFT level, and significantly increase your influence in governance.
This guide explains how VeChain Node holders can link their nodes to GM NFTs, the benefits of doing so, and the steps to get started.
Following the April 2025 governance proposal, major changes were made to strengthen the GM system and incentivize voter participation.
Linking your VeChain Node to a GM NFT provides multiple advantages:
Unlock Free Level Upgrades:
Your node's type determines the free upgrade level of your GM NFT.
Higher levels increase your voter rewards which in return increases your influence in governance.
Boost Voter Rewards:
Higher GM NFT levels provide multipliers for voter rewards.
Multiplier percentages increase with GM NFT levels, enhancing the value of your votes.
Dynamic Benefits:
If your node level is upgraded, the GM NFT's level is also upgraded dynamically.
Nodes can be detached and reassigned as needed.
When you link a VeChain Node to a GM NFT, the NFT receives a free upgrade based on the node type:
None
1
Strength
2
Thunder
4
Mjolnir
6
VeThorX
2
StrengthX
4
Note: If the free upgrade level exceeds the NFT's current maximum unlocked level, the level is capped.
Check Node Ownership:
Ensure you own the VeChain Node or it has been delegated to you.
Select a GM NFT:
Choose an NFT to link to your node. Use the VeBetter interface to view your GM NFTs.
Link Your Node:
Use the Node Management feature in the VeBetter platform to attach your node to the selected GM NFT.
Monitor Your GM NFT Level:
Check the NFT’s level after linking. Free upgrades are applied automatically.
Participate in Governance:
Use the linked GM NFT for voting in VeBetter proposals and XApp allocation to maximize rewards.
Single Linkage:
A node can only be linked to one GM NFT at a time.
Non-Transferable:
GM NFTs with attached nodes cannot be transferred or sold.
Ownership Alignment:
Free upgrades apply only if the GM NFT owner and the node owner (or delegatee) are the same.
Dynamic Adjustments:
Upgrading or downgrading a node updates the GM NFT’s level dynamically.
Higher GM NFT levels significantly increase your rewards during governance and x-allocatin voting participation. Here’s how the multiplier system works:
2
Moon
10%
1.1
3
Mercury
20%
1.2
4
Venus
50%
Detachment Rules:
Only the node owner, delegatee, or GM NFT owner can detach the node.
Detaching a node resets the GM NFT’s level unless it was paid for using B3TR.
Reassigning Nodes:
After detaching, the node can be linked to another GM NFT for additional upgrades or governance participation.
Node Type: Thunder
GM NFT Initial Level: 1
Free Upgrade Level: 4 (Venus)
Outcome: The GM NFT is upgraded to Level 4 (Venus) for free.
GM Rewards Weight: 1.5
If the total GM voter reward weight that cycle is 300, the user's share is:
of the GM Rewards Pool
Node Type: MjolnirX
GM NFT Initial Level: 5 (Mars)
Free Upgrade Level: 7 (Saturn)
Outcome: The GM NFT is upgraded to Level 7 (Saturn) for free. To reach Level 8 (Uranus), donate 2,500,000 B3TR.
Given total GM voter reward weight that cycle is 300
At Level 7: Wote Weight = 3
of the GM Rewards Pool
At Level 8: Vote Weight = 5
of the GM Rewards Pool
Important Update:
Legacy node mechanics have been replaced by StarGate staking NFTs.
Learn how staking, delegation, and participation work now:
ThunderX
6
MjolnirX
7
1.5
5
Mars
100%
2
6
Jupiter
150%
2.5
7
Saturn
200%
3
8
Uranus
400%
5
9
Neptune
900%
10
10
Galaxy
2400%
25
Roles define the permissions and access levels across different contracts and modules. This page outlines the structure of roles, their functions, and the path toward full decentralization.
To maintain a secure and flexible smart contract system, we leverage roles to manage administrative tasks and define who has the authority to perform specific actions. These roles control everything from minting tokens to upgrading contracts, pausing operations, and setting governance parameters.
The central goal of this structure is to gradually decentralize power from individual wallets to the DAO (the B3TRGovernor governance contract).
This document categorizes roles and outlines their functionalities, detailing what permissions each role grants. Here's a quick summary of some common roles and what they do:
DEFAULT_ADMIN_ROLE: The superuser role with the ability to grant, revoke, and renounce roles.
PAUSER_ROLE: Controls the ability to pause and unpause contract functionality.
MINTER_ROLE: Allows for token minting.
UPGRADER_ROLE: Permits contract upgrades and modifications.
CONTRACTS_ADDRESS_MANAGER_ROLE: Manages critical contract addresses.
DECAY_SETTINGS_MANAGER_ROLE: Manages parameters surrounding cycle lengths, allocation percentages and decay rates in the Emission contract.
GOVERNANCE_ROLE: Involved in governance decisions, proposal management, and voting.
All roles have in common the following functionality: they can renounce that role.
Once there isn’t any address that has the DEFAULT_ADMIN_ROLE then it won’t be possible to grant or revoke any role. If some contract is upgradeable and the DAO has the UPGRADER_ROLE then the DAO could decide to upgrade the contract and assign the role to whoever they want.
The ultimate aim is to create a self-governing system where no single entity holds absolute control. This section of the page provides a detailed plan for achieving this goal, outlining the steps for transitioning roles to the B3TRGovernor contract, removing direct admin control, and enabling decentralized governance.
Follow the outlined steps to understand the current state of role assignments and the specific actions required to achieve a more autonomous system. Through this journey, we aim to establish a resilient and community-driven ecosystem where the power of decision-making rests in the hands of the DAO and its stakeholders.
NB: This contract will be upgraded to handle app endorsement, so the “Add app” functionality triggered by a GOVERNANCE_ROLE could be removed in a future release
GOVERNOR_FUNCTIONS_SETTINGS_ROLE
setWhitelistFunction, setWhitelistFunctions, setIsFunctionRestrictionEnabled
Whitelist function that people can trigger in their proposals, or disable this check.
Admin Wallet, BTRGovernor
CONTRACTS_ADDRESS_MANAGER_ROLE
setVoterRewards, setXAllocationVoting, updateTimelock
Manages contract addresses
Admin Wallet, BTRGovernor
setXAllocationsDecayPeriod, setVote2EarnDecayPeriod
Sets decay periods for various emission-related settings
setTreasuryPercentage, setScalingFactor, setMaxVote2EarnDecay
Configures emission scaling factors and treasury settings
CONTRACTS_ADDRESS_MANAGER_ROLE
setXAllocationAddress, setVote2EarnAddress, setTreasuryAddress, setXAllocationsGovernorAddress
Configures addresses for key contracts
Admin Wallet
UPGRADER_ROLE
upgrade, renounceRole
Allows contract upgrades
Admin Wallet
MINTER_ROLE
Mint
Mint tokens for migration purposes
Admin Wallet
CONTRACTS_ADDRESS_MANAGER_ROLE
setXAllocationsGovernorAddress, setB3trGovernorAddress
Configures critical contract addresses
Admin Wallet
UPGRADER_ROLE
upgrade
Allows contract upgrades
Admin Wallet
stakeB3TR, unstakeB3TR
Manages staking and unstaking
PAUSER_ROLE
Pause, Unpause
Pauses and unpauses contract operations
Admin Wallet
UPGRADER_ROLE
Upgrade
Allows contract upgrades
Admin Wallet
setVoteRegistrarRole
Assigns who has permission to register votes
CONTRACTS_ADDRESS_MANAGER_ROLE
setEmissions, setGalaxyMember
Sets key contract addresses
Admin Wallet
UPGRADER_ROLE
Upgrade
Allows contract upgrades
Admin Wallet
GOVERNANCE_ROLE
Add app, setVotingEligibility
Adds new apps and defines voting eligibility
Admin Wallet
GOVERNANCE_ROLE
setVotingThreshold, setAppSharesCap
Sets parameters for voting
Admin Wallet, B3TRGovernor
setBaseAllocationPercentage, setVotingPeriod
Establishes voting periods and percentages
updateQuorumNumerator
Updates quorum requirements
CONTRACTS_ADDRESS_MANAGER_ROLE
setX2EarnAppsAddress, setEmissionsAddress, setVoterRewardsAddress
Manages key contract addresses
Admin Wallet
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
grantRole, revokeRole, renounceRole
Grants or revokes roles; allows renunciation of its role
Admin Multi Signature
PAUSER_ROLE
Pause, Unpause
Pauses or unpauses contract operations
Admin Wallet
MINTER_ROLE
Mint
Mints new tokens
Admin Wallet, Emissions Contract
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
grantRole, revokeRole, renounceRole, cancel,
_authorizeUpgrade, relay, setDepositThreshold, setVotingThreshold, setMinVotingDelay, updateQuorumNumerator
Grants or revokes roles; allows renunciation of its role; cancel pending proposals;
Admin Wallet
PROPOSAL_EXECUTOR_ROLE
Execute
Executes queued proposals
Admin Wallet
PAUSER_ROLE
Pause, Unpause
Pauses or unpauses contract (no proposal creation, queuing, or execution)
Admin Wallet
Role Name
Functions
Function Descriptions
Initial Assignees
MINTER_ROLE
Bootstrap, Start, renounceRole
Allows minting of tokens, initializing processes
Admin Wallet
DEFAULT_ADMIN_ROLE
grantRole, revokeRole, renounceRole
Manages roles and contract parameters
Admin multisig contract
DECAY_SETTINGS_MANAGER_ROLE
setCycleDuration, setXAllocationsDecay, setVote2EarnDecay
Sets emission cycle durations and related parameters
Admin Wallet
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
setMaxLevel, setMaxMintableLevels, setBaseURI, setB3TRtoUpgradeToLevel, setIsPublicMintingPaused
Sets contract parameters for levels, minting, and URI, Controls public minting
Admin Wallet
UPGRADER_ROLE
Upgrade
Allows contract upgrades
Admin Wallet
PAUSER_ROLE
Pause, Unpause
Pauses and unpauses the contract
Admin Wallet
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
grantRole, revokeRole, renounceRole
Grants or revokes roles; allows renunciation of its own role
Admin Wallet, Timelock contract
Proposer
schedule, cancel
Proposes, schedules, and cancels transactions
B3TRGovernor
Executor
Execute
Executes approved proposals and transactions
B3TRGovernor
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
grantRole, revokeRole, renounceRole
Grants/revokes roles; can renounce its own role
Admin Wallet
GOVERNANCE_ROLE
transferVTHO, transferB3TR, transferVOT3, transferVET
Manages VOT3, B3TR, VET and VTHO transfers
B3TRGovernor
transferTokens, transferNFT
Manages NFT and ERC20 token transfers
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
grantRole, revokeRole, renounceRole
Grants or revokes roles; allows renunciation of its role
Admin Wallet
UPGRADER_ROLE
Upgrade
Allows contract upgrades
Admin Wallet
PAUSER_ROLE
Pause, Unpause
Pauses or unpauses contract operations
Admin Wallet
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
setLevelToMultiplier, setScalingFactor
Sets reward scaling factors and levels
Admin Wallet
UPGRADER_ROLE
Upgrade
Allows contract upgrades
Admin Wallet
VOTE_REGISTRAR_ROLE
registerVote
Registers user votes for rewards
XAllocationVoting, B3TRGovernor
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
setBaseURI, UpdateAppMetadata
Configures base URI and updates app metadata
Admin Wallet
Update receiver address/ app admin
Sets or updates app receiver address and admin
Add/Remove app moderators
Manages app moderators
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
Admin Wallet
UPGRADER_ROLE
Upgrade
Allows contract upgrades
Admin Wallet
CONTRACTS_ADDRESS_MANAGER_ROLE
setX2EarnApps
Update the contract address of X2EarnApps
Admin Wallet
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
grantRole, revokeRole, renounceRole
Grants, revokes, or renounces roles
Admin Wallet
UPGRADER_ROLE
Upgrade
Allows contract upgrades
Admin Wallet
CONTRACTS_ADDRESS_MANAGER_ROLE
setXAllocationVotingAddress, setEmissionsAddress, setTreasuryAddress, setX2EarnAppsAddress
Manages key contract addresses
Admin Wallet
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
grantRole, revokeRole, renounceRole
Grants, revokes, or renounces roles
Admin Wallet
UPGRADER_ROLE
Upgrade
Allows contract upgrades
Admin Wallet
ROUND_STARTER_ROLE
startNewRound
Initiates a new voting round
Emissions Contract
Role Name
Functions
Function Descriptions
Initial Assignees
DEFAULT_ADMIN_ROLE
grantRole, revokeRole, renounceRole
Grants, revokes, or renounces roles
Admin Wallet
UPGRADER_ROLE
Upgrade
Allows contract upgrades
Admin Wallet
DISTRIBUTOR_ROLE
distributeDBARewards
Sends to surplus allocation to apps
Admin Wallet