Audit: CL8Y flows through smart contracts (PASS) + operational hardening recommendations #69

Closed
opened 2026-04-26 08:27:06 +00:00 by PlasticDigits · 0 comments
PlasticDigits commented 2026-04-26 08:27:06 +00:00 (Migrated from gitlab.com)

Summary

A thorough audit of every CL8Y inflow / outflow path across the Yieldomega smart contracts has been merged to main as docs/onchain/cl8y-flow-audit.md (commit 2511077).

Result: PASS. The codebase implements the stated invariant correctly:

Every discretionary CL8Y outflow is gated by an immediate onlyOwner / onlyRole(...) check with no timelock (so a human can run a manual review and execute), and every other outflow is deterministic on-rails routing or a hardcoded burn.

No hidden outflow surfaces were found (no rescue, sweep, recoverERC20, selfdestruct, or admin-redirectable burn-sink setter).

What was audited

  • CL8Y-handling contracts: TimeCurve, FeeRouter, PodiumPool, EcosystemTreasury, DoubLPIncentives, CL8YProtocolTreasury (all three FeeSink subclasses), RabbitTreasury, TimeCurveBuyRouter, ReferralRegistry.
  • 8 inflow sites classified (low risk).
  • 9 deterministic outflow sites classified (recipient bound by code or on-chain state).
  • 1 discretionary outflow family classified — FeeSink.withdraw on the three sink deployments — plus TimeCurve.setReservePodiumPayoutsEnabled and the UUPS upgrade authorization on each proxy. All are immediate role-gated with no timelock, matching the design spec.

See the report for the full per-site table with file/line references.

Recommendations (operational hardening — non-blocking)

These do not require contract changes. They tighten monitoring, deployment, and documentation around the existing (correct) controls.

R1 — Document expected withdraw destinations for each CL8Y sink

In docs/onchain/treasury-contracts.md, add a per-sink note listing the expected destination(s) of FeeSink.withdraw(token=CL8Y, to=…, amount=…) (e.g. multisig address, LP locker contract). Off-spec destinations in Withdrawn events then become obvious in monitoring/review.

Affected sinks: EcosystemTreasury, DoubLPIncentives, CL8YProtocolTreasury.

R2 — Add monitoring rows for high-impact admin events

In docs/onchain/security-and-threat-model.md (or a new operational monitoring doc), add high-severity alert rows for:

  • Upgraded(address implementation) on every UUPS proxy (TimeCurve, FeeRouter, PodiumPool, RabbitTreasury, ReferralRegistry, and the three FeeSink subclasses).
  • FeeRouter.SinksUpdated(...).
  • TimeCurve.ReservePodiumPayoutsEnabled(...), BuyFeeRoutingEnabled(...), CharmRedemptionEnabled(...), TimeCurveBuyRouterSet(...).
  • Withdrawn(token == CL8Y, …) from each CL8Y-receiving sink.

R3 — Deploy-time guard against using MockReserveCl8y / MockCL8Y in production

Add a chain-id whitelist (or vm.envString(\"NETWORK\") check) in contracts/script/DeployDev.s.sol so that the MockReserveCl8y fallback path cannot fire on any non-Anvil RPC. Cheap, single-line change. Matches existing comment intent ("NOT for production").

Link the new docs/onchain/cl8y-flow-audit.md from:

  • docs/onchain/security-and-threat-model.md
  • docs/onchain/fee-routing-and-governance.md
  • docs/operations/final-signoff-and-value-movement.md (issue #55)

R5 — Mainnet checklist: confirm role custody is multisig

In docs/operations/deployment-checklist.md, add an explicit check that on the production deploy, DEFAULT_ADMIN_ROLE, WITHDRAWER_ROLE, GOVERNOR_ROLE, and Ownable ownership of every contract on the CL8Y path are held by a multisig (or hardware-backed signer). The contract design assumes this — the checklist should make it a literal pre-launch gate.

Conclusion

No protocol changes recommended. The contract design and gating model match the stated security requirement ("owner/admin without timelock so manual review can be done"). Recommendations R1–R5 are operational hardening to make the existing controls easier to monitor, harder to misuse, and easier to audit in future.

References

## Summary A thorough audit of every CL8Y inflow / outflow path across the Yieldomega smart contracts has been merged to `main` as [`docs/onchain/cl8y-flow-audit.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/onchain/cl8y-flow-audit.md) (commit `2511077`). **Result: PASS.** The codebase implements the stated invariant correctly: > Every discretionary CL8Y outflow is gated by an immediate `onlyOwner` / `onlyRole(...)` check **with no timelock** (so a human can run a manual review and execute), and every other outflow is deterministic on-rails routing or a hardcoded burn. No hidden outflow surfaces were found (no `rescue`, `sweep`, `recoverERC20`, `selfdestruct`, or admin-redirectable burn-sink setter). ## What was audited - **CL8Y-handling contracts:** `TimeCurve`, `FeeRouter`, `PodiumPool`, `EcosystemTreasury`, `DoubLPIncentives`, `CL8YProtocolTreasury` (all three `FeeSink` subclasses), `RabbitTreasury`, `TimeCurveBuyRouter`, `ReferralRegistry`. - **8 inflow sites** classified (low risk). - **9 deterministic outflow sites** classified (recipient bound by code or on-chain state). - **1 discretionary outflow family** classified — `FeeSink.withdraw` on the three sink deployments — plus `TimeCurve.setReservePodiumPayoutsEnabled` and the UUPS upgrade authorization on each proxy. All are immediate role-gated with no timelock, matching the design spec. See the report for the full per-site table with file/line references. ## Recommendations (operational hardening — non-blocking) These do **not** require contract changes. They tighten monitoring, deployment, and documentation around the existing (correct) controls. ### R1 — Document expected `withdraw` destinations for each CL8Y sink In [`docs/onchain/treasury-contracts.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/onchain/treasury-contracts.md), add a per-sink note listing the expected destination(s) of `FeeSink.withdraw(token=CL8Y, to=…, amount=…)` (e.g. multisig address, LP locker contract). Off-spec destinations in `Withdrawn` events then become obvious in monitoring/review. Affected sinks: `EcosystemTreasury`, `DoubLPIncentives`, `CL8YProtocolTreasury`. ### R2 — Add monitoring rows for high-impact admin events In [`docs/onchain/security-and-threat-model.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/onchain/security-and-threat-model.md) (or a new operational monitoring doc), add high-severity alert rows for: - `Upgraded(address implementation)` on every UUPS proxy (`TimeCurve`, `FeeRouter`, `PodiumPool`, `RabbitTreasury`, `ReferralRegistry`, and the three `FeeSink` subclasses). - `FeeRouter.SinksUpdated(...)`. - `TimeCurve.ReservePodiumPayoutsEnabled(...)`, `BuyFeeRoutingEnabled(...)`, `CharmRedemptionEnabled(...)`, `TimeCurveBuyRouterSet(...)`. - `Withdrawn(token == CL8Y, …)` from each CL8Y-receiving sink. ### R3 — Deploy-time guard against using `MockReserveCl8y` / `MockCL8Y` in production Add a chain-id whitelist (or `vm.envString(\"NETWORK\")` check) in `contracts/script/DeployDev.s.sol` so that the `MockReserveCl8y` fallback path **cannot** fire on any non-Anvil RPC. Cheap, single-line change. Matches existing comment intent (\"NOT for production\"). ### R4 — Cross-link the audit from related docs Link the new `docs/onchain/cl8y-flow-audit.md` from: - `docs/onchain/security-and-threat-model.md` - `docs/onchain/fee-routing-and-governance.md` - `docs/operations/final-signoff-and-value-movement.md` (issue #55) ### R5 — Mainnet checklist: confirm role custody is multisig In `docs/operations/deployment-checklist.md`, add an explicit check that on the production deploy, `DEFAULT_ADMIN_ROLE`, `WITHDRAWER_ROLE`, `GOVERNOR_ROLE`, and `Ownable` ownership of every contract on the CL8Y path are held by a multisig (or hardware-backed signer). The contract design assumes this — the checklist should make it a literal pre-launch gate. ## Conclusion **No protocol changes recommended.** The contract design and gating model match the stated security requirement (\"owner/admin without timelock so manual review can be done\"). Recommendations R1–R5 are operational hardening to make the existing controls easier to monitor, harder to misuse, and easier to audit in future. ## References - Report: [`docs/onchain/cl8y-flow-audit.md`](https://gitlab.com/PlasticDigits/yieldomega/-/blob/main/docs/onchain/cl8y-flow-audit.md) - Commit: [`2511077`](https://gitlab.com/PlasticDigits/yieldomega/-/commit/2511077) - Related: issue #55 (final signoff / value-movement gates), `docs/onchain/fee-routing-and-governance.md`, `docs/onchain/security-and-threat-model.md`
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-04-26 09:32:52 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
code/yieldomega#69
No description provided.