Only this pageAll pages
Powered by GitBook
1 of 46

VeBetterDAO

VeBetter

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Developer Guides

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

VePassport

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

VeChain Node & Staking Guides

Loading...

Loading...

Loading...

Loading...

Loading...

B3TR & VOT3 Tokens

B3TR - Incentive Token

Address: 0x5ef79995FE8a89e0812330E4378eB2660ceDe699

B3TR is the incentive token of VeBetter. Its functions include:

  1. General incentive token for VeBetter, including VeBetter Treasury Management

  2. Value carrier and monetization mechanism for active participants and innovative enterprise models

  3. Incentive token for sustainability applications

  4. 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.

VOT3 - Governance Token

Address: 0x76Ca782B59C74d088C7D2Cce2f211BC00836c602

VOT3 is the governance token of VeBetter. Its functions include:

  1. Required to take part in governance

  2. 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.

Trust Assumptions

Emissions

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.

Roles and Security

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.

Initial centralization

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.

X2Earn Allocations

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.

Allocation rounds

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.

Test Environment

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.

Testnet

Use our testnet environment, running on vechain testnet network, to create apps, interact with smart contracts, and manage reward distribution.

RuleBook for Apps

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:

1. Direct Double Dipping

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

Reward Distribution

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.

Personhood Check

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;

Accounts Linking

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.

Manage distributors funds

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

Blacklisting and Whitelisting

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.

Endpoints

Other apps or contracts can interact with this module through the following functions of the VePassport contract:

2. Recursive Rewarding (Incentive Layering)

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.

3. Fragmentation for Reward Multiplication

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.

4. Social Amplification Loops

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.

12 May 2025 Governance update
"dApp Tracker" proposal
JavaScript
Solidity

Proof of investment

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.

  • Enabled checks

    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.

    Check personhood in a specific block

    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;
        ...
      }
    Endpoints
      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)
      ...
    }
    Rules
    • 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.

    Voting Process

    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.

    Example of casting a vote

    Earnings calculation

    • 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.

    Quorum impact on distribution

    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.

    Distribution trigger

    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

    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

    Funding Allocation for Project i=(∑jvij)2\text{Funding Allocation for Project }i = \left( \sum_{j} \sqrt{v_{ij}} \right)^2Funding Allocation for Project i=(∑j​vij​​)2

    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.

    Linear Voting

    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.

    Upgradeable parameters

    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%.

    Normalized Funding Allocation for Project i=(∑jvij)2∑k(∑jvkj)2×Emissions Pool\text{Normalized Funding Allocation for Project } i = \frac{\left( \sum_{j} \sqrt{v_{ij}} \right)^2}{\sum_{k} \left( \sum_{j} \sqrt{v_{kj}} \right)^2} \times \text{Emissions Pool} Normalized Funding Allocation for Project i=∑k​(∑j​vkj​​)2(∑j​vij​​)2​×Emissions Pool

    Go to https://dev.testnet.governance.vebetterdao.org

  • 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:

    Local node

    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.

    solo node
    distributable rewards pool,
    by increasing/ decreasing the wished amount. If you are
    new to the DAO
    , note that this feature will be enabled by default. You will have to
    immediately refill your rewards pool
    , up to the amount you want to distribute.

    Q&A

    What happen if my rewards pool goes to 0 ?

    If your balance is empty, it's either because you enabled the feature without adding funds to your rewards pool, or because you've run out of funds. You can either refill your rewards pool or disable the feature entirely at any time:

    Via VeBetterDAO Dashboard

    • Refill: Add funds directly through the VBD dashboard

    • Disable: Toggle off the feature in settings

    Via X2EarnRewardsPoolSmart Contract

    B3TR Emissions

    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.

    Recent Governance Change (April 2025)

    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.

    Emissions Schedule

    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.

    Emissions Chart

    Emissions Parameters

    The Emissions smart contract contains parameters for the emissions scheduling.

    Triggering Emissions

    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.

    Get Started

    Requirements

    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

    Test Environment

    Use our to create a test app running in the VeBetter ecosystem.

    Distribute B3TR

    Get some B3TR tokens on testnet, add a reward distributor then connect a smart contract or a backend and distribute rewards to your users.

    Proofs and Impacts

    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.

    Resources

    Have doubts? Check our additional resources specifically picked for you to speed up your development.

    Submit App

    When your app is ready submit it to VeBetter and join the movement!

    RuleBook

    Security

    Before going live be sure to go through our along the . Make sure to apply security measures to your app, avoiding hacks and farmers.

    Submit Your App

    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.

    Submission Process

    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:

    1. 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.

    2. 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.

    3. 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.

    4. 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.

    On-Chain App Submission Requirements

    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.

    Your APP ID

    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.

    B3TR Allocations

    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.

    Your App categories

    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.

    If you are submitting a native application, please link to your app a landing page.

    Checks

    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

    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.

    Contracts can be found at the following repository: https://github.com/vechain/vebetterdao-contracts Mainnet Address: 0x35a267671d8EDD607B2056A9a13E7ba7CF53c8b3

    Proof of Personhood

    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.

    Proof of Participation

    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.

    Proof of Investment

    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.

    Whitelisting, Blacklisting, and Bot Signalling

    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.

    Proof of Identity

    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.

    Delegation

    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.

    Testnet B3TR tokens

    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.

    Faucet

    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.

    Allocation rounds

    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 .

    Resources

    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.

    Roles

    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

    Legacy VeChain Node Guides (Pre-StarGate)

    Legacy System

    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

    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:

    1. B3TR Token: The incentive ERC-20 token with a 1 billion cap, used within the ecosystem for rewards and governance.

    2. Governance System:

    Passport Delegation

    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.

    X2Earn Creators NFT

    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.

    Overview

    • 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.

    Legacy Nodes to StarGate

    An overview of how VeChain moved from legacy nodes to StarGate including what migration means for participation and VeBetterDAO.

    Overview

    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 and Eligibility

    • 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.

    Functionality and Permissions

    • 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 and Burn Mechanism

    • 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.

    Key Points for Developers

    • 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.

    Legacy Nodes

    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

    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.

    For a full explanation of how StarGate works, refer to the official documentation:

    https://docs.stargate.vechain.org/

    Migration to StarGate

    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.

    Learn how to migrate your legacy node:

    https://docs.stargate.vechain.org/overview/legacy-nodes-migration

    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

    https://github.com/vechain/x-app-template
    Vechain Getting Started Documentation
    VeBetter contracts
    https://docs.stargate.vechain.org/overview/legacy-nodes-migration
    wallet
    Test Environment
    Test Environment
    Testnet B3TR tokens
    Reward Distribution
    Sustainability Proof and Impacts
    Resources
    Submit Your App
    RuleBook for Apps
    Security Considerations
    RuleBook
    Security Considerations
    Architecture overview of components that could be involved in creating a x2earn app
    Bot Signaling
    Long term VePassport
    Initial implementation
    GM level 1

    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

    🔗 Explore Interactive B3TR Emissions Simulator

    Emissions frequency (cycle length)

    VeChain Grants program
    endorsement
    allocation rounds
    Endorsement Guide for VeChain Node Holders
    When calling the isPerson function for a given address the contract will automatically check for delegated passports.

    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.

    Endpoints

    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.

    Resources

    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 addresses

    Contracts have been deployed on the vechain mainnet at the following addresses.

    Contract
    Address

    B3TR

    0x5ef79995FE8a89e0812330E4378eB2660ceDe699

    B3TRGovernor

    0x1c65C25fABe2fc1bCb82f253fA0C916a322f777C

    Emissions

    0xDf94739bd169C84fe6478D8420Bb807F1f47b135

    GalaxyMember

    0x93B8cD34A7Fc4f53271b9011161F7A2B5fEA9D1F

    TimeLock

    0x7B7EaF620d88E38782c6491D7Ce0B8D8cF3227e4

    Treasury

    0xD5903BCc66e439c753e525F8AF2FeC7be2429593

    VechainThor
    // 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)
    Rewards Distribution section

    Security Considerations

    X2Earn Apps should consider implementing necessary security measures to guard against farmers unfairly obtaining b3tr tokens.

    Farming Approaches

    • 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.

    Potential Solutions

    Securing Back-End APIs

    • 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

    How Sustainable Actions are Verified

    • 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.

    Suspicious Behaviour & Ban List

    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.

    Management of Private Keys

    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.

    Device Fingerprinting

    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.

    Other Strategies

    • 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.

    Conclusion

    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.

    Recommended Service: Guardian (Advanced Fraud Detection)

    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:

    Treasury

    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.

    Implementation

    Treasury will hold all assets belonging to the DAO. Such assets include VET, VTHO, B3TR

    Bot Signaling

    Authorised apps can flag suspicious addresses such as bots, and scammers to help the VeBetter and other apps identify and protect against bad actors.

    If a user is flagged incorrectly, VeBetter or selected apps can reset their signal count to clear their record.

    • Community Dashboard:

    Endpoints

    Proof of Participation

    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.

    Solidity

    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.com
    and a request to it is made from
    api.fakeapp.com
    , it will be rejected.
  • Rate 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.

  • Guardian
    https://dashboard.guardianstack.ai/
    https://docs.guardianstack.ai/
    ,
    VOT3
    and any other
    ERC-20
    or
    ERC-721
    tokens that have been transferred to the Treasury contract address.

    Tokens 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.

    Contract Functionality

    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

    Transfer Limits

    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:

    How Bot Signaling Works

    • 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.

    Snippet

    The following is a snippet of how to signal addresses by using the VeChain SDK.

    Permission Request

    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.

    Signal Admin Dashboard
    Apps security levels

    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.

    Cumulative score

    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)

    Threshold

    The threshold an address must meet to be considered a person is 300 points accumulated during the last 12 rounds.

    Endpoints

    Other apps or contracts can interact with the Proof of Participation module through the following functions of the VePassport contract:

    You can set this on the VeBetter governance app.

    Sustainability Proof

    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

    Reward Metadata

    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.

    Suggested Metadata Structure

    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.

    Examples

    To provide metadata you need to distribute the rewards through the X2EarnRewardsPool contract with the following function:

    Emitted Event: RewardMetadata

    Upon 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.

    Guidelines

    • 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.

    JavaScript

    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:

    Sustainability Proof

    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

    X2Earn Apps

    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.

    Join VeBetter

    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.

    Endorsement Guide for VeChain Node Holders

    Legacy System (Pre-StarGate)

    This page documents the legacy VeChain node endorsement system which was used before the StarGate upgrade. Legacy node endorsements are no longer active and have been replaced by StarGate staking NFTs.

    Node Management

    Legacy System (Pre-StarGate)

    This page describes legacy VeChain node management which applied before the StarGate upgrade. Legacy nodes have been deprecated and replaced by StarGate staking NFTs.

      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-contracts
    TESTNET: https://testnet.vechain.org
    MAINNET: https://mainnet.vechain.org

    You can check the current threshold amount by calling signalingThreshold

    Node management, delegation, and rewards now occur through StarGate.

    👉 If you still hold a legacy node, you must migrate to continue participating:

    https://docs.stargate.vechain.org/overview/legacy-nodes-migration

    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.

    Key Features for VeChain Node Holders

    1. 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.

    2. 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.

    3. 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.

    4. 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:

    https://docs.stargate.vechain.org/

    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

    Demo on how to reproduce the previous steps in the VeBetterDAO testnet sandbox

    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();
    
    4) Scroll down to the "Reward Distributors" section, and add the public address as a reward distributor

    5) Save changes

    here
    Sustainability Proofs and Impacts
    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 Scores

    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.

    VeChain Node Level
    Endorsement Score

    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.

    Voting Eligibility and Endorsement Status

    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.

    XApp Endorsement

    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.

    XApp Un-Endorsement and Grace Period

    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.

    Integrity Checks

    To ensure the consistency and validity of endorsements, VeBetter conducts periodic checks on endorsing nodes.

    App ID

    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.

    Signaling

    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.

    Metadata

    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:

    👉 Learn how participation works after StarGate:

    https://docs.stargate.vechain.org/

    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.

    What is an Endorsement?

    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.

    Endorsement Scores by Node Type

    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.

    How Endorsement Works

    1. 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.

    2. Endorse with Your Node: Select one XApp to endorse. Your endorsement adds the score of your node to the XApp’s cumulative endorsement score.

    3. 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.

    4. 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.

    5. 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.

    Managing Your Endorsements

    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.

    Key Points to Remember

    • 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:

    https://docs.stargate.vechain.org/

    Automation

    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.

    Auto-Voting & Auto-Claiming Rewards

    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.

    Overview

    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.

    Getting Started

    1. Navigate to the page

    2. Ensure you meet all eligibility

    3. Select your preferred apps for auto-voting

    4. Toggle-on Auto-voting & claim

    What’s Required to Enable

    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

    How It Works

    Note for First-Time Activation

    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.

    Weekly Automation Cycle

    1. Snapshot: At the start of each voting round, a snapshot is taken to determine eligible participants

    2. Auto-Voting: The service automatically casts votes based on your selected app preferences

    3. Auto-Claiming: After the round ends, your rewards are automatically claimed and deposited to your wallet

    Service Fee

    📊 Fee Structure

    To cover the gas costs of automating your transactions, a 10% fee is applied to your weekly claimed rewards.

    The fee and cap are community-driven. Since we are still in the MVP phase, this setup helps us fine-tune the model and better understand the operational costs of keeping the service running. The community is welcome to propose adjustments and share their findings so we can collaboratively evaluate whether updates are appropriate.

    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 Weekly Rewards
    Fee (10%)
    You Receive
    Service Gas Coverage

    ⚡ Why the fee? The service monitors all automation users and automatically processes transactions on your behalf. The 10% fee (capped at 100 B3TR) covers the gas costs and ensures reliable, hands-free automation every week.

    Important: Maintaining Eligibility

    Your automation can be automatically disabled if any of the following occurs:

    ⚠️ Auto-Disable Scenarios

    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.

    Constraints

    Manual Actions While Auto-Voting Is Active

    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.

    Understanding Your Status

    Your automation status will show one of three states the allocations page:

    🟡 Auto-Voting Is Enabled

    Auto-voting is enabled. It takes effect from the next round.

    • 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

    🟢 Auto-Voting Is Active

    Auto-voting is active. Your vote and rewards will be handled automatically..

    • 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

    🔴 Auto-Voting Is Disabled

    Auto-voting is disabled. It takes effect from the next round.

    • 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.

    AI Image Validation

    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.

    Example:

    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:

    Item
    Description

    We can use a multi-stage prompt to guide the AI through these tasks:

    Governance

    Following community proposal, since the, the deposits are now counted as voting power for XApp votes. The deposit threshold is capped at 5M VOT3. To submit a proposal, the proposer must thread and be a holder.

    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.

    Sustainability Proof and Impacts

    The proof will be stored on-chain in the form of an emitted event and will have the following JSON format:

    Parameters

    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:

    Voter Rewards

    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

    allocations
    requirements
    cumulative participation score
    allocations
    eligibility

    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.

    Examples

    To provide proofs and impacts you need to distribute the rewards through the X2EarnRewardsPool contract with the following function:

    Proofs

    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:

    Impacts

    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".

    Categories

    1. Carbon Footprint Reduction Key: carbon Description: Measures the decrease in greenhouse gas emissions. Metric: Grams (g) of CO2 equivalent reduced or removed.

    2. 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.

    3. 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.

    4. Timber Conservation Key: timber Description: Measures the reduction in the use or waste of timber resources. Metric: Grams (g) of timber saved.

    5. Plastic Reduction Key: plastic Description: Evaluates the decrease in the use or waste of plastic materials. Metric: Grams (g) of plastic saved or reduced.

    6. Education Time Key: education_time Description: Measures the amount of time a user spends learning about a sustainability topic. Metric: Seconds spent learning.

    7. Trees Planted Key: trees_planted Description: Tracks the number of trees planted as part of sustainability efforts. Metric: Number of trees planted.

    8. Calories Burned Key: calories_burned Description: Measures the energy expenditure from physical activity or exercise, promoting health and sustainability. Metric: Calories (kcal) burned.

    9. 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.

    10. 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:

    We ask each app to find a way to calculate the impact they are having based on the previously listed categories. If your app does not fit in any of the above categories please feel free to submit your own category and impact definition.

    Deprecated template (version 1)

    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
    biodiversity
    Governance Stabilization Period and Initialization

    At 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.

    Proposal Submission

    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.

    Community support

    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.

    Governance Process

    The governance process is the following: propose → vote → execute if succeeded.

    Let's break it down:

    1. Requirements

    • 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.

    2. Creating a Proposal

    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:

    1. Actionable Proposals

      Trigger an on-chain action, usually involving the treasury or contract calls.

    2. 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.

    3. Proposal Process

    1

    Deposit Period

    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.

    2

    Voting Period

    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.

    3

    Outcome vote

    Once the voting period is over, if the quorum is reached and the majority voted in favour, the proposal is considered successful and can proceed to be executed. A Timelock is used for this operation, which adds a delay to proposal execution.

    Proposal States
    Lifecycle of the proposal

    Quorum

    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.

    Vote Outcome

    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.

    Execution

    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.

    Governance setup

    Initially, only selected admins will be able to execute proposals.

    Vote Delegation

    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

    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.

    Linear Voting

    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.

    Upgradeable parameters

    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

    13th of August 2025
    create a Discourse
    Moon NFT
    votingPower=v, where v is the number of VOT3 tokens held\text{votingPower} = \sqrt{v}, \text{ where } v \text{ is the number of VOT3 tokens held} votingPower=v​, where v is the number of VOT3 tokens held
    All funds received by the Vote2Earn pool are used solely to reward voters proportionally based on VOT3. The GM Rewards pool receives a fixed 5% of weekly emissions and distributes rewards to qualifying voters who hold a GM NFT.

    Galaxy Member NFT: Unlock Greater Rewards with Upgrades

    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.

    Unlocking GM NFT Levels

    There are two ways to upgrade your GM NFT:

    B3TR Requirements for Upgrades

    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

    Benefits of Upgrading Your GM NFT

    • 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.

    Linear Rewards

    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.

    Reward Formula

    Where

    • Vi,vV_{i,v}Vi,v​ = VOT3 balance of user i when voting on proposal v

    • CCC = all proposals (Governance and XAllocation Voting) in the cycle the user participated in

    • uuu = all users who voted on any proposal during the cycle

    • Vote2EarncycleVote2Earn_{cycle}Vote2Earncycle​​ = total Vote2Earn reward pool for the cycle

    Example:

    Given:

    • 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.

    GM Rewards

    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.

    Reward Formula

    Where

    • Wi,vW_{i,v}Wi,v​ = reward weight of user i when voting on proposal v (based on GM NFT level)

    • CCC = all proposals (Governance and XAllocation Voting) in the cycle the user participated in

    • uuu = all users who voted with a GM NFT during the cycle

    • GMRewardsPoolcycleGMRewardsPool_{\text{cycle}}GMRewardsPoolcycle​ = 5% of total B3TR emissions for the cycle

    Example:

    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: 10×2=2010×2=2010×2=20

    • User B: 2×2=42×2=42×2=4

    • User C: 25×1=25 25×1=2525×1=25

    • Total Weight: 20+4+25=4920+4+25=4920+4+25=49

    Reward Calculations:

    User A: Reward = 2049×50,000=20,408.16 {\frac{20}{49}\times 50,000 } = 20,408.164920​×50,000=20,408.16 B3TR

    User B: Reward = 449×50,000=4,081.63 {\frac{4}{49}\times 50,000 } = 4,081.63494​×50,000=4,081.63 B3TR

    User C: Reward = 2549×50,000=25,510.20 {\frac{25}{49}\times 50,000 } = 25,510.204925​×50,000=25,510.20 B3TR

    Quadratic Rewarding (disabled from round 23)

    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.

    April 2025 Governance Update
    Rewardi=(∑v∈CVi,v∑u∑v∈CVu,v)×Vote2EarncycleReward_i = \left( \frac{\sum_{v \in C} V_{i,v}}{\sum_{u} \sum_{v \in C} V_{u,v}} \right) \times Vote2Earn_{\text{cycle}} Rewardi​=(∑u​∑v∈C​Vu,v​∑v∈C​Vi,v​​)×Vote2Earncycle​
    Reward=(10,000/5,300,000)∗1,000,000=1,887B3TRReward = (10,000 / 5,300,000) * 1,000,000 = 1,887 B3TRReward=(10,000/5,300,000)∗1,000,000=1,887B3TR
    GMRewardi=(∑v∈CWi,v∑u∑v∈CWu,v)×GMRewardsPoolcycle\text{GMReward}_i = \left( \frac{\sum\limits_{v \in C} W_{i,v}}{\sum\limits_{u} \sum\limits_{v \in C} W_{u,v}} \right) \times GMRewardsPool_{\text{cycle}}GMRewardi​=​u∑​v∈C∑​Wu,v​v∈C∑​Wi,v​​​×GMRewardsPoolcycle​

    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

    Smart Contracts

    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.

    2MB
    Hacken_Vechain Foundation_[SCA] VeChain _ VeBetter DAO _ May2024_P-2024-304_1_20240621 16_17 (1).pdf
    PDF
    Open

    Putting it all together we get a picture of the connections of all smart contracts with hierarchies and usages between each other.

    13MB
    vebetterdao_architecture_diagram.pdf
    PDF
    Open

    The following is the list of all smart contracts listed alphabetically:

    B3TR

    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

    B3TRProxy

    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.

    B3TRGovernor

    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

    Emissions

    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

    GalaxyMember

    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

    NodeManagement

    Legacy contract

    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

    Timelock

    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

    Treasury

    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

    VOT3

    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

    VoterRewards

    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

    X2EarnApps

    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

    X2EarnCreators

    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

    X2EarnRewardsPool

    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

    XAllocationPool

    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

    XAllocationVoting

    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

    B3TR Multisig

    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.

    Dynamic Base Allocation Pool

    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

    Relayer Rewards Pool

    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

    Libraries

    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.

    GovernorClockLogic

    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.

    GovernorConfigurator

    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.

    GovernorDepositLogic

    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.

    GovernorFunctionRestrictionsLogic

    Library for managing function restrictions within the Governor contract.

    This library provides functions to whitelist or restrict functions that can be called by proposals.

    GovernorProposalLogic

    Library for managing proposals in the Governor contract.

    This library provides functions to create, cancel, execute, and validate proposals.

    GovernorQuorumLogic

    Library for managing quorum numerators using checkpointed data structures.

    GovernorStateLogic

    Library for Governor state logic, managing the state transitions and validations of governance proposals.

    GovernorVotesLogic

    Library for handling voting logic in the Governor contract.

    Contracts Upgradeability

    We are using UUPS proxy for our upgradeable contracts. You can read more about it here:.

    Resources

    Library updates

    In B3TRGovernor, we are utilising libraries inside some of the modules. To upgrade the functionalities inside these libraries the following steps must be done.

    1. Update library

    2. Deploy new library

    3. Deploy new implementation contract connecting updated library with new library address

    4. Upgrade the proxy to use this new implementation smart contract using the upgradeToAndCall function .

    VeChain Nodes X GM NFTs: Maximising Benefits within VeBetter

    Legacy System (Pre-StarGate)

    This page explains how legacy VeChain nodes previously interacted with GM NFTs before the StarGate upgrade. Legacy node mechanics have been replaced by StarGate staking NFTs.

    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

    https://docs.stargate.vechain.org/
    https://governance.vebetterdao.org/proposals/24829756257606634701400089449417807964640877888736006394567167792281000041364
    https://docs.openzeppelin.com/contracts/5.x/api/proxy

    GalaxyMember

    GM NFT interactions are no longer based on legacy nodes.

    👉 Learn how staking NFTs work in StarGate:

    https://docs.stargate.vechain.org/overview/nft-tiers

    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.


    Why Link Your VeChain Node to a GM NFT?

    Linking your VeChain Node to a GM NFT provides multiple advantages:

    1. 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.

    2. 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.

    3. 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.


    VeChain Nodes and Free Upgrade Levels

    When you link a VeChain Node to a GM NFT, the NFT receives a free upgrade based on the node type:

    VeChain Node Type
    Free Upgrade Level

    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.


    Step-by-Step Guide: Linking Your Node

    1. Check Node Ownership:

      • Ensure you own the VeChain Node or it has been delegated to you.

    2. Select a GM NFT:

      • Choose an NFT to link to your node. Use the VeBetter interface to view your GM NFTs.

    3. Link Your Node:

      • Use the Node Management feature in the VeBetter platform to attach your node to the selected GM NFT.

    4. Monitor Your GM NFT Level:

      • Check the NFT’s level after linking. Free upgrades are applied automatically.

    5. Participate in Governance:

      • Use the linked GM NFT for voting in VeBetter proposals and XApp allocation to maximize rewards.


    Rules for Linking Nodes

    • 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.


    Reward Multipliers and Governance Influence

    Higher GM NFT levels significantly increase your rewards during governance and x-allocatin voting participation. Here’s how the multiplier system works:

    Level
    Name
    Multiplier Percentage
    Reward Weight

    2

    Moon

    10%

    1.1

    3

    Mercury

    20%

    1.2

    4

    Venus

    50%


    Detaching and Reassigning Nodes

    • 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.


    Examples

    Example 1: Free Upgrade with a Node

    • 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:

      • 1.5300=0.5%\frac{1.5}{300} = 0.5\%3001.5​=0.5% of the GM Rewards Pool

    Example 2: Combining Free and Paid Upgrades

    • 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

      • 3300=1.0%\frac{3}{300} = 1.0\%3003​=1.0% 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:

    https://docs.stargate.vechain.org/

    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

    5300=1.66%\frac{5}{300} = 1.66\%3005​=1.66%

    Roles And Permissions

    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).

    Roles

    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.

    Permissions

    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.

    Contract: B3TR

    Steps for full decentralization:

    Contract: B3TRGovernor

    Steps for full decentralization:

    Contract: Emissions

    Steps for full decentralization:

    Contract: GalaxyMember

    Steps for full decentralization:

    Contract: Timelock

    Steps for full decentralization:

    Contract: Treasury

    Steps for full decentralization:

    Contract: VOT3

    Steps for full decentralization:

    Contract: VoterRewards

    Steps for full decentralization:

    Contract: X2EarnApps

    Steps for full decentralization:

    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

    Contract: X2EarnRewardsPool

    Steps for full decentralization:

    Contract: XAllocationPool

    Steps for full decentralization:

    Contract: XAllocationVoting

    Steps for full decentralization:

    Contract: Dynamic Base Allocation Pool

    Steps for full decentralization:

    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

    We grant the DECAY_SETTINGS_MANAGER_ROLE to the B3TRGovernor and revoke it from the current wallet

    MINTER_ROLE

    Mint

    Mint tokens for migration purposes

    Admin Wallet

    CONTRACTS_ADDRESS_MANAGER_ROLE

    setXAllocationsGovernorAddress, setB3trGovernorAddress

    Configures critical contract addresses

    Admin Wallet

    We grant the DEFAULT_ADMIN_ROLE to the B3TRGovernor and revoke it from the current 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

    We grant the DEFAULT_ADMIN_ROLE to the B3TRGovernor and revoke it from current 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

    https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeabledocs.openzeppelin.com