Skip to content

Commit

Permalink
revoke deployer key from timelock admin (#15710)
Browse files Browse the repository at this point in the history
* revoke deployer key from timelock admin

* use RenounceRole instead of Revoke

* add addtional checks/tests

* fix int type casting in test

* remove comment

* fix typo

---------

Co-authored-by: Akhil Chainani <[email protected]>
  • Loading branch information
krehermann and akhilchainani authored Dec 16, 2024
1 parent bd0296a commit 74d6b5a
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
31 changes: 31 additions & 0 deletions deployment/common/changeset/transfer_to_mcms_with_timelock.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,3 +211,34 @@ func TransferToDeployer(e deployment.Environment, cfg TransferToDeployerConfig)
e.Logger.Infof("deployer key accepted ownership tx %s", tx.Hash().Hex())
return deployment.ChangesetOutput{}, nil
}

var _ deployment.ChangeSet[RenounceTimelockDeployerConfig] = RenounceTimelockDeployer

type RenounceTimelockDeployerConfig struct {
ChainSel uint64
}

// RenounceTimelockDeployer revokes the deployer key from administering the contract.
func RenounceTimelockDeployer(e deployment.Environment, cfg RenounceTimelockDeployerConfig) (deployment.ChangesetOutput, error) {
contracts, err := MaybeLoadMCMSWithTimelockState(e, []uint64{cfg.ChainSel})
if err != nil {
return deployment.ChangesetOutput{}, err
}
tl := contracts[cfg.ChainSel].Timelock
if tl == nil {
return deployment.ChangesetOutput{}, fmt.Errorf("timelock not found on chain %d", cfg.ChainSel)
}
admin, err := tl.ADMINROLE(&bind.CallOpts{})
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to get admin role: %w", err)
}
tx, err := tl.RenounceRole(e.Chains[cfg.ChainSel].DeployerKey, admin, e.Chains[cfg.ChainSel].DeployerKey.From)
if err != nil {
return deployment.ChangesetOutput{}, fmt.Errorf("failed to revoke deployer key: %w", err)
}
if _, err := deployment.ConfirmIfNoError(e.Chains[cfg.ChainSel], tx, err); err != nil {
return deployment.ChangesetOutput{}, err
}
e.Logger.Infof("revoked deployer key from owning contract %s", tl.Address().Hex())
return deployment.ChangesetOutput{}, nil
}
58 changes: 58 additions & 0 deletions deployment/common/changeset/transfer_to_mcms_with_timelock_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package changeset

import (
"math/big"
"testing"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -78,3 +80,59 @@ func TestTransferToMCMSWithTimelock(t *testing.T) {
require.NoError(t, err)
require.Equal(t, e.Chains[chain1].DeployerKey.From, o)
}

func TestRenounceTimelockDeployer(t *testing.T) {
lggr := logger.TestLogger(t)
e := memory.NewMemoryEnvironment(t, lggr, 0, memory.MemoryEnvironmentConfig{
Chains: 1,
Nodes: 1,
})
chain1 := e.AllChainSelectors()[0]
e, err := ApplyChangesets(t, e, nil, []ChangesetApplication{
{
Changeset: WrapChangeSet(DeployMCMSWithTimelock),
Config: map[uint64]types.MCMSWithTimelockConfig{
chain1: proposalutils.SingleGroupTimelockConfig(t),
},
},
})
require.NoError(t, err)
addrs, err := e.ExistingAddresses.AddressesForChain(chain1)
require.NoError(t, err)

state, err := MaybeLoadMCMSWithTimelockChainState(e.Chains[chain1], addrs)
require.NoError(t, err)

tl := state.Timelock
require.NotNil(t, tl)

adminRole, err := tl.ADMINROLE(nil)
require.NoError(t, err)

r, err := tl.GetRoleMemberCount(&bind.CallOpts{}, adminRole)
require.NoError(t, err)
require.Equal(t, int64(2), r.Int64())

// Revoke Deployer
e, err = ApplyChangesets(t, e, nil, []ChangesetApplication{
{
Changeset: WrapChangeSet(RenounceTimelockDeployer),
Config: RenounceTimelockDeployerConfig{
ChainSel: chain1,
},
},
})
require.NoError(t, err)

// Check that the deployer is no longer an admin
r, err = tl.GetRoleMemberCount(&bind.CallOpts{}, adminRole)
require.NoError(t, err)
require.Equal(t, int64(1), r.Int64())

// Retrieve the admin address
admin, err := tl.GetRoleMember(&bind.CallOpts{}, adminRole, big.NewInt(0))
require.NoError(t, err)

// Check that the admin is the timelock
require.Equal(t, tl.Address(), admin)
}

0 comments on commit 74d6b5a

Please sign in to comment.