Skip to content

chore(ens): draft calldata review for EP 6.39 - Treasury Flow Automation#75

Merged
alextnetto merged 6 commits intomainfrom
ens/ep-6-39-treasury-flow-automation
Mar 27, 2026
Merged

chore(ens): draft calldata review for EP 6.39 - Treasury Flow Automation#75
alextnetto merged 6 commits intomainfrom
ens/ep-6-39-treasury-flow-automation

Conversation

@alextnetto
Copy link
Copy Markdown
Member

@alextnetto alextnetto commented Mar 25, 2026

Summary

Calldata Verification

# Target Function Status
1 RegistrarManager addRegistrar(currentRegistrar) PASS
2 RegistrarManager addRegistrar(newRegistrar) PASS
3 RegistrarManager addRegistrar(oldRegistrar) PASS
4 Current Registrar transferOwnership(manager) PASS
5 New Registrar transferOwnership(manager) PASS
6 Old Registrar transferOwnership(manager) PASS
7 Endowment Safe execTransactionscopeTarget(MANAGER, USDC) PASS
8 Endowment Safe execTransactionscopeFunction(MANAGER, USDC, transfer) PASS
9 Endowment Safe execTransactionscopeTarget(MANAGER, timelock) PASS
10 Endowment Safe execTransactionallowFunction(MANAGER, timelock, 0x0, SEND) PASS

Test plan

  • forge test --match-path "src/ens/proposals/ep-registrar-manager-endowment/*" -vv — all 43 tests pass
  • Post-execution negative tests: USDC transfer and ETH send to non-timelock addresses blocked
  • Cyfrin audit included

…omation

Fetch draft proposal data from Tally draft 2820664548653007898.
All 8 executable calls verified: calldata matches manual derivation.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2bda65929f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


This is the current suggestion for the funding policy.

The timelock maintains a 6 months runway in USDC (~$8M at current spending). Each quarter, Karpatkey calculates the current runway on the timelock. If it falls below 6 months, the endowment sends the shortfall. If it exceeds 6 months, no transfer is needed and the excess stays invested in the endowment. If an additional governance proposal requiring capital is approved, this may trigger an earlier runway evaluation and transfer, consistent with this policy.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reconcile conflicting runway durations in proposal text

The proposal currently defines three different runway targets: a “two-year” target in the Abstract/Impact sections, a “6 months” operating runway in Funding Policy, and a “three-year” requirement in the IPS alignment paragraph. Because these values drive when treasury transfers should occur, this inconsistency can lead to contradictory execution decisions depending on which section is followed. Please normalize the policy wording so one unambiguous runway rule is described.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is the proposal description fetched verbatim from the Tally draft — we don't author or modify it.

The runway numbers refer to different things:

  • 6 months: operational USDC runway maintained on the timelock (quarterly rebalancing trigger)
  • Three-year: stablecoin runway calculated at the Endowment level per the IPS
  • Two-year (in Abstract): appears to be an inaccuracy in the proposer's text — likely should say "six-month" to match the Funding Policy section

Worth flagging to the proposal author but outside the scope of our calldata review.

#### Key Addresses

• Timelock: 0xFe89cc7aBB2C4183683ab71653C4cdc9B02D44b7 (wallet.ensdao.eth)
• Current Registrar Controller: 0x253553366Da8546fC250F225fE3d25d0C782303b (controller.ens.eth)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Match listed current controller with executable transactions

The description lists 0x253553... as the current registrar controller, but the executable payload only adds/transfers ownership for 0x59E16f... and 0x283Af0... (calls 1–4 in proposalCalldata.json). This mismatch means the narrative and execution payload describe different controller scope, which can mislead reviewers and voters about which contracts are actually being handed to RegistrarManager.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — this was already noted as an INFO finding in the security report.

The description lists 0x253553... (controller.ens.eth) as "Current Registrar Controller" in Key Addresses, but the calldata only registers 0x59E16f... (ETH Registrar Controller 2) and 0x283Af0... (Old ETH Registrar Controller). This is intentional per the proposer's design: the description explains that controller.ens.eth "already sends withdrawn ETH to the timelock," so it's excluded from the RegistrarManager.

The narrative's Key Addresses section lists all relevant controllers for context, while the transactions only target the two that need ownership transfer. Not a calldata issue — a documentation clarity point for the proposer.

Include controller.ens.eth (0x2535...303b) alongside the existing
two controllers. Proposal now has 10 transactions: 3 addRegistrar +
3 transferOwnership + 4 Zodiac role updates.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1450016b14

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +85 to 88
// 1) Register current registrar controller (controller.ens.eth)
targets[0] = managerAddr;
calldatas[0] = abi.encodeWithSelector(RegistrarManager.addRegistrar.selector, address(NEW_REGISTRAR));
calldatas[0] = abi.encodeWithSelector(RegistrarManager.addRegistrar.selector, address(CURRENT_REGISTRAR));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep generated calls consistent with draft proposal payload

_generateCallData() now includes addRegistrar(CURRENT_REGISTRAR) (and later transferOwnership for the same controller), but src/ens/proposals/ep-registrar-manager-endowment/proposalCalldata.json still defines an 8-call draft payload that does not include those operations. This means the governance simulation is validating a different transaction batch than the draft being reviewed, so the calldata check can report success while the real Tally payload remains unverified for this scope.

Useful? React with 👍 / 👎.

- Add dirPath() override to enable calldata comparison against proposalCalldata.json
- Re-fetch draft with all 3 controllers and correct 65-byte Safe signatures
- All 10 executable calls verified: manual derivation matches Tally draft
Add post-execution assertions that USDC transfers and ETH sends
to non-timelock addresses are blocked. Prevents false positive
if Zodiac conditions were misconfigured to allow broader scope.
Re-fetch proposalCalldata.json and description from the new draft URL.
All 10 executable calls verified against manual derivation.
@alextnetto alextnetto merged commit a846be7 into main Mar 27, 2026
@alextnetto alextnetto changed the title chore(ens): draft calldata review for EP 6.39 — Treasury Flow Automation chore(ens): draft calldata review for EP 6.39 - Treasury Flow Automation Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant