feat: add rVirtual conversion via RVirtualConverter - #181
Conversation
Adds an open, permissionless 1:1 VIRTUAL -> rVirtual converter (RVirtualConverter, UUPS upgradeable), pre-funded with the rVirtual supply. veVirtual gains convertVeVirtualToRVirtual(id), which deletes a staking position (regardless of maturity or autoRenew state) and routes its underlying VIRTUAL through the same open converter entrypoint any wallet can call directly - no backend distribution step required. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit b98ca31. Configure here.
|
|
||
| _grantRole(DEFAULT_ADMIN_ROLE, _msgSender()); | ||
| _grantRole(ADMIN_ROLE, _msgSender()); | ||
| } |
There was a problem hiding this comment.
Implementation initializers left enabled
Medium Severity
RVirtualConverter is UUPS-upgradeable but never disables initializers on the implementation. Unlike other upgradeable contracts here (for example Minter), anyone can call initialize on the implementation itself, take over its admin roles, and empty any tokens sent to that address.
Reviewed by Cursor Bugbot for commit b98ca31. Configure here.


Adds an open, permissionless 1:1 VIRTUAL -> rVirtual converter (RVirtualConverter, UUPS upgradeable), pre-funded with the rVirtual supply. veVirtual gains convertVeVirtualToRVirtual(id), which deletes a staking position (regardless of maturity or autoRenew state) and routes its underlying VIRTUAL through the same open converter entrypoint any wallet can call directly - no backend distribution step required.
Note
High Risk
New upgradeable token bridge and veVirtual exit path directly affect VIRTUAL/rVirtual balances, converter liquidity, and governance voting power; misconfiguration or insufficient pre-funding could block conversions or drain the pool unexpectedly.
Overview
Introduces a permissionless 1:1 VIRTUAL → rVirtual path via a new UUPS-upgradeable
RVirtualConverter, expected to launch pre-funded with the full rVirtual supply so swaps draw down inventory instead of minting. Anyone can callconvertVirtualToRVirtual(amount, receiver); accumulated VIRTUAL can be swept by a configuredadminWalletthroughwithdrawVirtual, with no generic rescue for rVirtual (to avoid transfer-tax exposure).veVirtualadds admin-configuredsetRVirtualConverterandconvertVeVirtualToRVirtual(id), which removes a lock (including immature or auto-renew positions), burns the staker’s voting units, approves the converter, and uses the same public converter entrypoint—no special converter path for ve stakes.Tests cover converter behavior (1:1, liquidity limits, admin withdraw, UUPS round-trip via
RVirtualConverterV2Mock) and ve conversion edge cases (ownership, multi-lock, vote snapshots, allowance cleanup).Reviewed by Cursor Bugbot for commit b98ca31. Bugbot is set up for automated code reviews on this repo. Configure here.