Skip to content

Commit b75af29

Browse files
authored
Merge pull request #752 from fei-protocol/gov-addresses
Add Governance upgrade addresses
2 parents 0536999 + ebb56f4 commit b75af29

File tree

7 files changed

+104
-15
lines changed

7 files changed

+104
-15
lines changed

contracts/pods/PodAdminGateway.sol

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,19 @@ contract PodAdminGateway is CoreRef, IPodAdminGateway {
157157
emit PodMembershipTransferLock(_podId, _lock);
158158
}
159159

160+
/// @notice Transfer the admin of a pod to a new address
161+
/// @dev Permissioned to GOVERNOR, POD_ADMIN and the specific pod admin role
162+
function transferAdmin(uint256 _podId, address _newAdmin)
163+
external
164+
hasAnyOfThreeRoles(TribeRoles.GOVERNOR, TribeRoles.POD_ADMIN, getSpecificPodAdminRole(_podId))
165+
{
166+
ControllerV1 podController = ControllerV1(memberToken.memberController(_podId));
167+
address oldPodAdmin = podController.podAdmin(_podId);
168+
169+
podController.updatePodAdmin(_podId, _newAdmin);
170+
emit UpdatePodAdmin(_podId, oldPodAdmin, _newAdmin);
171+
}
172+
160173
/////////////// VETO CONTROLLER /////////////////
161174

162175
/// @notice Allow a proposal to be vetoed in a pod timelock

contracts/test/integration/governance/PodAdminGateway.t.sol

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pragma solidity ^0.8.0;
33

44
import {TimelockController} from "@openzeppelin/contracts/governance/TimelockController.sol";
55
import {ControllerV1} from "@orcaprotocol/contracts/contracts/ControllerV1.sol";
6+
import {MemberToken} from "@orcaprotocol/contracts/contracts/MemberToken.sol";
67
import {Vm} from "../../utils/Vm.sol";
78
import {DSTest} from "../../utils/DSTest.sol";
89
import {PodFactory} from "../../../pods/PodFactory.sol";
@@ -149,6 +150,32 @@ contract PodAdminGatewayIntegrationTest is DSTest {
149150
assertFalse(memberTransfersLocked);
150151
}
151152

153+
/// @notice Transfer pod admin to new admin
154+
function testTransferPodAdmin() public {
155+
address memberToRemove = podConfig.members[0];
156+
address newAdmin = address(0x22);
157+
158+
vm.prank(feiDAOTimelock);
159+
podAdminGateway.transferAdmin(podId, newAdmin);
160+
161+
address newAdminOnFactory = factory.getPodAdmin(podId);
162+
assertEq(newAdminOnFactory, newAdmin);
163+
164+
address newAdminOnController = ControllerV1(podController).podAdmin(podId);
165+
assertEq(newAdminOnController, newAdmin);
166+
167+
// Validate new pod admin can perform an admin function, such as removing a member
168+
vm.prank(newAdmin);
169+
MemberToken(memberToken).burn(memberToRemove, podId);
170+
171+
uint256 numPodMembers = factory.getNumMembers(podId);
172+
assertEq(numPodMembers, podConfig.members.length - 1);
173+
174+
address[] memory podMembers = factory.getPodMembers(podId);
175+
assertEq(podMembers[0], podConfig.members[1]);
176+
assertEq(podMembers[1], podConfig.members[2]);
177+
}
178+
152179
/// @notice Validate that a non-PodAdmin fails to call a priviledged admin method
153180
function testNonAdminFailsToRemoveMember() public {
154181
vm.expectRevert(bytes("UNAUTHORIZED"));

proposals/dao/fip_82.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const transferOrcaTokens = async (
4343
const fipNumber = '82';
4444

4545
const deploy: DeployUpgradeFunc = async (deployAddress: string, addresses: NamedAddresses, logging: boolean) => {
46+
const deploySigner = (await ethers.getSigners())[0];
4647
// 1. Deploy public pod executor
4748
const podExecutorFactory = await ethers.getContractFactory('PodExecutor');
4849
const podExecutor = await podExecutorFactory.deploy(addresses.core);
@@ -59,6 +60,7 @@ const deploy: DeployUpgradeFunc = async (deployAddress: string, addresses: Named
5960
podExecutor.address // Public pod executor
6061
);
6162
await podFactory.deployTransaction.wait();
63+
logging && console.log('Pod factory deployed to:', podFactory.address);
6264

6365
// 3. Deploy PodAdminGateway contract
6466
const podAdminGatewayFactory = await ethers.getContractFactory('PodAdminGateway');
@@ -69,8 +71,7 @@ const deploy: DeployUpgradeFunc = async (deployAddress: string, addresses: Named
6971
);
7072
await podAdminGateway.deployTransaction.wait();
7173
logging && console.log(`Deployed PodAdminGateway at ${podAdminGateway.address}`);
72-
await transferOrcaTokens(addresses.orcaShipToken, deployAddress, podFactory.address, 2);
73-
logging && console.log('Pod factory deployed to:', podFactory.address);
74+
await transferOrcaTokens(addresses.orcaShipToken, deployAddress, podFactory.address, 1);
7475

7576
// 4. Create TribalCouncil and Protocol Tier pods
7677
const tribalCouncilPod: PodCreationConfig = {
@@ -95,9 +96,8 @@ const deploy: DeployUpgradeFunc = async (deployAddress: string, addresses: Named
9596
logging && console.log('Tribal council Gnosis safe is: ', councilSafeAddress);
9697

9798
// 5. Create contract artifacts for timelock, so address is available to DAO script
98-
const mockSigner = await getImpersonatedSigner(deployAddress);
99-
const tribalCouncilTimelock = new ethers.Contract(councilTimelockAddress, timelockABI, mockSigner);
100-
const tribalCouncilSafe = new ethers.Contract(councilSafeAddress, gnosisSafeABI, mockSigner);
99+
const tribalCouncilTimelock = new ethers.Contract(councilTimelockAddress, timelockABI, deploySigner);
100+
const tribalCouncilSafe = new ethers.Contract(councilSafeAddress, gnosisSafeABI, deploySigner);
101101

102102
// 6. Deploy GovernanceMetadataRegistry contract
103103
const metadataRegistryFactory = await ethers.getContractFactory('GovernanceMetadataRegistry');

protocol-configuration/dependencies.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,10 +1036,10 @@ const dependencies: DependencyMap = {
10361036
contractDependencies: ['core', 'podExecutor', 'podAdminGateway']
10371037
},
10381038
podAdminGateway: {
1039-
contractDependencies: ['core', 'podFactory']
1039+
contractDependencies: ['core', 'podFactory', 'tribalCouncilTimelock']
10401040
},
10411041
podExecutor: {
1042-
contractDependencies: ['podFactory']
1042+
contractDependencies: ['podFactory', 'tribalCouncilTimelock']
10431043
},
10441044
nopeDAO: {
10451045
contractDependencies: ['core', 'tribe']
@@ -1064,6 +1064,12 @@ const dependencies: DependencyMap = {
10641064
},
10651065
voltOracle: {
10661066
contractDependencies: ['volt', 'voltDepositWrapper', 'collateralizationOracle']
1067+
},
1068+
tribalCouncilTimelock: {
1069+
contractDependencies: ['podExecutor', 'tribalCouncilSafe', 'podAdminGateway']
1070+
},
1071+
tribalCouncilSafe: {
1072+
contractDependencies: ['tribalCouncilTimelock']
10671073
}
10681074
};
10691075

protocol-configuration/mainnetAddresses.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2015,6 +2015,46 @@ const MainnetAddresses: MainnetAddresses = {
20152015
artifactName: 'unknown',
20162016
address: '0x84dc71500D504163A87756dB6368CC8bB654592f',
20172017
category: AddressCategory.Volt
2018+
},
2019+
podExecutor: {
2020+
artifactName: 'PodExecutor',
2021+
address: '0x489BeB7b2829D0e57f1776899D561afc1bBeef11',
2022+
category: AddressCategory.Governance
2023+
},
2024+
podAdminGateway: {
2025+
artifactName: 'PodAdminGateway',
2026+
address: '0xf14DccfB071672F1394BaA58d136D94dD1cEDc85',
2027+
category: AddressCategory.Governance
2028+
},
2029+
podFactory: {
2030+
artifactName: 'PodFactory',
2031+
address: '0xeF9f961266Ad9Bb46396577A77234dBFEb4dAac7',
2032+
category: AddressCategory.Governance
2033+
},
2034+
governanceMetadataRegistry: {
2035+
artifactName: 'GovernanceMetadataRegistry',
2036+
address: '0xd78Cd3AaE6168BE43B548877aAc68312B9df9AFb',
2037+
category: AddressCategory.Governance
2038+
},
2039+
nopeDAO: {
2040+
artifactName: 'NopeDAO',
2041+
address: '0x6C7aF43Ce97686e0C8AcbBc03b2E4f313c0394C7',
2042+
category: AddressCategory.Governance
2043+
},
2044+
tribalCouncilTimelock: {
2045+
artifactName: 'TimelockController',
2046+
address: '0x9F80E03985303eB8b2ABC031Cb82716D7913f531',
2047+
category: AddressCategory.Governance
2048+
},
2049+
tribalCouncilSafe: {
2050+
artifactName: 'unknown',
2051+
address: '0xdb6236E5363aBdeb807198e820DD5CC04BfC8dDd',
2052+
category: AddressCategory.Governance
2053+
},
2054+
roleBastion: {
2055+
artifactName: 'RoleBastion',
2056+
address: '0x8096314D9014EbB69Fc777ED3791DDE6FFbaFAed',
2057+
category: AddressCategory.Governance
20182058
}
20192059
};
20202060

protocol-configuration/optimisticGovernance.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { ethers } from 'ethers';
2-
31
export type PodConfig = {
42
members: string[];
53
threshold: number;
@@ -50,10 +48,12 @@ export const MIN_TIMELOCK_DELAY = 86400; // 1 day
5048
export const tribeCouncilPodConfig: PodConfig = {
5149
members: tribalCouncilMembers,
5250
threshold: 5,
53-
label: '0x54726962616c436f756e63696c00000000000000000000000000000000000000', // TribalCouncil
54-
ensString: 'tribalcouncil',
51+
label: '0xcc74924992a4b3a8d464650443c1d35252c3c4eacfcae441e1a646c194eda9c9', // tribalcouncil
52+
ensString: 'tribalcouncil.pod.xyz',
5553
imageUrl: '',
5654
minDelay: 86400 * 4, // 4 days
5755
numMembers: tribalCouncilMembers.length,
5856
placeHolderMembers: placeHolderCouncilMembers
5957
};
58+
59+
export const TRIBAL_COUNCIL_POD_ID = 24;

test/integration/proposals_config.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,24 @@ const proposals: ProposalsConfigMap = {
1919
}
2020
*/
2121
fip_82: {
22-
deploy: true, // deploy flag for whether to run deploy action during e2e tests or use mainnet state
22+
deploy: false, // deploy flag for whether to run deploy action during e2e tests or use mainnet state
2323
totalValue: 0, // amount of ETH to send to DAO execution
2424
proposal: fip_82, // full proposal file, imported from '@proposals/description/fip_xx.ts'
2525
proposalId: '',
2626
affectedContractSignoff: [
27-
'podAdminFactory',
2827
'roleBastion',
2928
'podFactory',
3029
'podExecutor',
3130
'nopeDAO',
3231
'governanceMetadataRegistry',
3332
'core',
34-
'tribe'
33+
'tribe',
34+
'feiDAOTimelock',
35+
'tribalCouncilTimelock',
36+
'tribalCouncilSafe',
37+
'podAdminGateway'
3538
],
36-
deprecatedContractSignoff: [''],
39+
deprecatedContractSignoff: [],
3740
category: ProposalCategory.DAO
3841
},
3942
fip_98: {

0 commit comments

Comments
 (0)