RabbitTreasuryVault: interim custody for Rabbit fee slice until RabbitTreasury (EcoStrategy H-01) #159
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#159
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
EcoStrategy audit H-01:
FeeRouter.distributeFeespays sinks viaERC20.safeTransfer. The fifth sink is documented as Rabbit Treasury, butRabbitTreasury.receiveFeeis what books protocol-owned backing, burn split, and Burrow fee events. RabbitTreasury is a future phase—final wiring is not frozen.We need interim custody so CL8Y can accumulate until Rabbit is live and
receiveFeeintegration is proven.Goal
RabbitTreasuryVault (name flexible) that:
Suggested design (outline; implement in MR)
Ownable2SteporAccessControladmin.withdrawERC20(IERC20 token, address to, uint256 amount)—to != 0, only admin.withdrawETHif native can land.Wiring: deploy vault →
FeeRouter.updateSinkspoints fifth destination to vault.Future: when Rabbit is ready, either sweep vault →
receiveFeepath, orupdateSinksto point directly at Rabbit once accounting is correct.Tests: distributeFees increases vault balance; admin withdraw moves balance.
Acceptance criteria
docs/onchain/treasury-contracts.md(or equivalent).protocolOwnedBackinguntilreceiveFeepath exists.References
contracts/src/FeeRouter.sol,contracts/src/RabbitTreasury.solaudits/audit_ecostrategy_1777969776.md— H-01mentioned in commit
d8535b1b2bImplemented on
main(d8535b1)Summary: Added
RabbitTreasuryVault— interim FeeRouter fifth-sink custody (Ownable2Step,withdrawERC20/withdrawETH,ERC20Withdrawn/ETHWithdrawn+ optionalreason). Documented INV-VAULT-159-* (vault ERC-20 balance ≠protocolOwnedBackinguntilreceiveFeeor routing migration). Tests:RabbitTreasuryVault.t.sol.@brouie please verify when you have a moment.
Verification checklist
cd contracts && forge test— includesRabbitTreasuryVaultTest(5 tests).docs/onchain/treasury-contracts.md§ RabbitTreasuryVault +fee-routing-and-governance.mdinterim custody note.INV-VAULT-159-NOT-BURROWmatches your expectations for dashboards/agents.FeeRouter.updateSinksfifth destination →distributeFeescredits vault → owner sweep with emitted reason string.Issue left open until you sign off.
mentioned in commit
9ff356526cmentioned in issue #158
@PlasticDigits — verification PASS on
d8535b1.checklist walked:
forge test --match-contract RabbitTreasuryVaultTest→ 5/5 PASS:test_distributeFees_increases_vault_balance— FeeRouter → vault wiring workstest_owner_withdrawERC20_moves_balance— admin sweep path workstest_withdrawERC20_unauthorized_reverts— access control enforcedtest_withdrawERC20_zero_to_reverts— zero-recipient rejectedtest_withdrawETH_moves_balance— native rescue worksdocs/onchain/treasury-contracts.md§rabbit-treasury-vault-gitlab-159— interim custody role defined, wiring path documented (updateSinks→ vault →distributeFees),DeployDevcontinues sending fifth sink toRabbitTreasuryfor local Burrow QA, accounting boundary stated explicitlydocs/onchain/fee-routing-and-governance.mdinterim custody note at line 29 + Rabbit row at line 53 reference vault correctlydocs/testing/invariants-and-business-logic.md:INV-VAULT-159-NOT-BURROW:ERC20.balanceOf(RabbitTreasuryVault) is not protocolOwnedBacking (nor redeemable backing). Treat vault balances as unbooked until swept into RabbitTreasury or sinks migrate via FeeRouter.updateSinks.— clear for dashboards/agentsINV-VAULT-159-ROUTING:distributeFeescredits vault when fifth sink targets vault;withdrawERC20requiresto != 0;Ownable2Stepgates sweepscontract surface (
contracts/src/sinks/RabbitTreasuryVault.sol, 44 lines): Ownable2Step admin, ERC20Withdrawn / ETHWithdrawn events with optional reason string, no special deposit hook (passive recipient only) — matches the spec.scope note: this verifies #159 as shipped (interim custody contract). the broader EcoStrategy H-01 finding — that the slice should eventually flow through
RabbitTreasury.receiveFeeto actually book BurrowprotocolOwnedBacking— is explicitly out of scope per the issue body and is documented as expected interim state inINV-VAULT-159-NOT-BURROW. that integration phase is a separate future item.live ops walk (deploy fresh vault →
FeeRouter.updateSinks→distributeFees→ owner sweep with reason) not run separately — the 5 forge tests cover this path with isolated mocks. happy to walk it on the live anvil stack if you want a separate signoff with explicit gas + event traces.ready for close on your side.
mentioned in commit
f325d2896ementioned in commit
3545964a26mentioned in issue #207