Skip to content

[ARM] Unpause Ethena ARM via governance (035)#279

Open
clement-ux wants to merge 1 commit into
mainfrom
clement/unpause-ethena-arm
Open

[ARM] Unpause Ethena ARM via governance (035)#279
clement-ux wants to merge 1 commit into
mainfrom
clement/unpause-ethena-arm

Conversation

@clement-ux

@clement-ux clement-ux commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Description

The Ethena ARM is currently paused on-chain: it was left paused after the 031 multi-base upgrade and never unpaused. Since then, ownership of the ARM has moved from the 5/8 Guardian Safe to the mainnet Timelock, so unpausing can no longer be done by a direct multisig call — it must go through a GOVERNOR_SIX governance proposal.

This PR adds a governance-only deployment script that submits a single unpause() action on the Ethena ARM. No contracts are deployed.

Deployment

Script script/deploy/mainnet/035_UnpauseEthenaARMScript.s.sol

The propose() calldata and proposal id below are produced by:

make simulate

make simulate runs DeployManager against the latest mainnet state (where the ARM is Timelock-owned), simulates the proposal end-to-end, and logs the GOVERNOR_SIX propose() calldata to submit.

Governance

The Ethena ARM is owned by the Timelock (0x35918cDE7233F2dD33fA41ae3Cb6aE0e42E0e69F), which is the executor of the OZ Governor GOVERNOR_SIX (0x1D3Fbd4d129Ddd2372EA85c5Fa00b2682081c9EC). When the proposal executes, GovernorSix routes the call through the Timelock, which holds both the owner and proxy-admin roles on the ARM.

Verified on-chain:

Check Value Expected
EthenaARM proxy owner() 0x35918cDE…E0e69F TIMELOCK ✅
EthenaARM proxy admin (EIP-1967 slot) 0x35918cDE…E0e69F TIMELOCK ✅
GovernorSix.timelock() 0x35918cDE…E0e69F TIMELOCK ✅
EthenaARM paused() true needs unpause ✅

The proposal performs 1 action on the EthenaARM proxy 0xCEDa2d856238aA0D12f6329de20B9115f07C366d (value 0), as built in _buildGovernanceProposal():

# Signature Selector Args
0 unpause() 0x3f4ba83a

Description: Unpause the Ethena ARM

Proposal id: 105952564920326880829480980653921695351704517467605619581569766325476268429476

propose() calldata

Calldata for propose(address[],uint256[],string[],bytes[],string) to submit to GOVERNOR_SIX (0x1D3Fbd4d129Ddd2372EA85c5Fa00b2682081c9EC):

0xda95691a00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000ceda2d856238aa0d12f6329de20b9115f07c366d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000009756e7061757365282900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016556e70617573652074686520457468656e612041524d00000000000000000000

Tests

This script deploys nothing — it only builds the proposal. It runs through DeployManager (skip = false), so the smoke suite simulates it during setUp() and the ARM ends up unpaused for the swap/deposit tests.

Because the proposal executes through the Timelock, the smoke/fork suite must fork a post-transfer block (the default latest, per .env.example); at an earlier block the ARM is still multisig-owned and the simulation reverts with TimelockController: underlying transaction reverted.

make test-smoke @ block 25379366 (post-transfer) — 49/49 passing, including Fork_EthenaARM_Smoke_Test 12/12 (swaps run against the now-unpaused ARM).

@clement-ux clement-ux force-pushed the clement/unpause-ethena-arm branch from 8b84bba to d3647fe Compare June 23, 2026 09:55
The Ethena ARM was left paused after the 031 multi-base upgrade, and its
ownership has since moved from the Guardian Safe to the mainnet Timelock.
Add 035_UnpauseEthenaARMScript: a governance-only proposal that calls
unpause() on the ARM through GOVERNOR_SIX -> Timelock (the same path used
for LidoARM/EtherFiARM).

The propose() calldata and proposal id are produced by `make simulate`,
which runs DeployManager against the latest mainnet state where the ARM is
Timelock-owned. Because the script runs through DeployManager (skip = false),
the smoke/fork suite must fork a post-transfer block (the default latest,
per .env.example); at an earlier block the ARM is still multisig-owned and
the proposal simulation reverts.

Record the proposal id in build/deployments-1.json with tsGovernance = 0
(governance pending): DeployManager re-simulates it on fork until it is
executed on-chain.
@clement-ux clement-ux force-pushed the clement/unpause-ethena-arm branch from d3647fe to cfc118f Compare June 23, 2026 10:03

@naddison36 naddison36 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

approved

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.

2 participants