VDB-28: feat: add TreasuryTokenBuybackDistributor for treasury cleanup (VDB-28)#167
Merged
fred-venus merged 12 commits intoJul 21, 2026
Conversation
One-shot helper for the "Venus Treasury Cleanup" VIP. Governance withdraws miscellaneous treasury tokens into this contract and calls distribute(), which splits each token's live balanceOf(this) across the six Treasury TokenBuyback contracts by fixed weights (BTCB/ETH/USDT/USDC 15%, XVS 10%, U 30%). Computing the split from the live balance means the VIP hardcodes no per-token amount and self-adjusts if balances change before execution. The U leg receives the re-read remaining balance, absorbing integer-division dust and fee-on-transfer wobble so the contract always ends at zero for every token. - contracts/helpers/TreasuryTokenBuybackDistributor.sol: the distributor - deploy/010-treasury-buyback-distributor.ts: hardhat-deploy script wiring the six buyback proxies from deployment artifacts (bsctestnet + bscmainnet) - tests: weight-sum invariant, exact/dust split, zero-balance skip, multi-decimal batch, idempotent repeat, fee-on-transfer drain-to-zero Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The prior bsctestnet deploy ran only the TreasuryBuyback dependency (redeploying an orphan U buyback implementation) and never deployed the distributor. The six buyback proxies are already deployed with committed artifacts on both networks, so the dependency is unnecessary and forces a spurious buyback-impl redeploy that shadows this script during a single-tag deploy. Drop it so the tag deploys only TreasuryTokenBuybackDistributor. Also revert the orphan UTreasuryBuyback implementation artifact (on-chain proxy still points to 0xDBE3..., upgrade was never performed) and remove its stray solc input. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
trumpgpt-bot
marked this pull request as ready for review
July 20, 2026 08:01
…ribution Redeem the treasury's VAI 1:1 (minus the PSM fee) for USDT at the VAI Peg Stability Module instead of DEX-swapping it out of the thin VAI market via the buybacks. The received USDT is then split across the six buybacks by the usual weights. convertVaiViaPsm is best-effort (self-call try/catch): a paused PSM, insufficient liquidity/minted headroom, or stale oracle can never brick the proposal — the VAI simply falls through to plain ERC20 distribution. No amount is hardcoded: the redeemed size derives from the live VAI balance, live PSM fee, and live oracle price. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Document why the VAI->USDT sizing read of the stable price does not poke updateAssetPrice (permitted only from the PSM's own context; the PSM refreshes the price itself inside swapVAIForStable), and that a stale read can only under-ask, never over-ask, since priceOut is floored into the denominator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per the requester, the USDT redeemed from the treasury's VAI at the VAI PSM should go straight back to VTreasury rather than being split across the six buybacks: USDT is already a base asset and needs no buyback conversion. Add a TREASURY immutable and pass it as the swapVAIForStable receiver so the redeemed USDT is delivered directly to VTreasury; the distributor never holds it. Wire the treasury per network in deploy/010 (bscmainnet VTreasury also equals the PSM's venusTreasury, so the small PSM fee lands there too) and update the unit tests accordingly (16 passing). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fred-venus
approved these changes
Jul 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
contracts/helpers/TreasuryTokenBuybackDistributor.sol— a minimal, one-shot helper for the Venus Treasury Cleanup VIP. It reads its own live balance of each supplied token and splits it across the six TreasuryTokenBuybackcontracts by fixed weights (BTCB 15% / ETH 15% / XVS 10% / USDT 15% / USDC 15% / U 30%). The five weighted legs transferbalance * weight / 10000; the U buyback receives the re-read remainder, absorbing integer-division dust and any fee-on-transfer wobble so the contract ends at zero for every token. Weights areconstantbps validated to sum to 10000 at construction; the six buyback addresses are immutables (nonzero-checked).distribute(address[])is permissionless and griefing-free — it can only move the contract's own balance to the fixed, verified destinations; it holds no treasury privilege.Also adds
deploy/010-treasury-buyback-distributor.ts(hardhat-deploy, tags["TreasuryTokenBuybackDistributor"], resolves per-network buyback addresses from committed deployment artifacts) and unit tests.Tests:
npx hardhat test tests/ProtocolReserve/TreasuryTokenBuybackDistributor.ts→ 9 passing (weight-sum invariant, exact-weight split, zero-balance skip, mixed decimals, idempotent repeat, fee-on-transfer drained to zero). solhint/prettier/eslint clean; compiles under solc 0.8.25. Deployed to bsctestnet at 0xfd45810d4c669e59510A096fc4cFA2233e5e20FD.Risk: the bscmainnet deploy is still pending (this PR ships the contract + testnet artifact); the mainnet buyback addresses must be passed as constructor args when deploying to mainnet.
Opened by the Venus dev bot. Review required; the bot cannot merge.