Skip to content

Commit 34c3b52

Browse files
committed
Update in response to review comments
1 parent adb422e commit 34c3b52

File tree

6 files changed

+85
-37
lines changed

6 files changed

+85
-37
lines changed

contracts/colony/Colony.sol

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -340,39 +340,18 @@ contract Colony is ColonyStorage, PatriciaTreeProofs, MultiChain {
340340
return IColonyNetwork(colonyNetworkAddress).installExtension(_extensionId, _version);
341341
}
342342

343-
// Deprecated
344-
function upgradeExtension(bytes32 _extensionId, uint256 _newVersion)
345-
public stoppable auth
346-
{
347-
IColonyNetwork(colonyNetworkAddress).upgradeExtension(_extensionId, _newVersion);
348-
}
349-
350343
function upgradeExtension(address _extension, uint256 _newVersion)
351344
public stoppable auth
352345
{
353346
IColonyNetwork(colonyNetworkAddress).upgradeExtension(_extension, _newVersion);
354347
}
355348

356-
// Deprecated
357-
function deprecateExtension(bytes32 _extensionId, bool _deprecated)
358-
public stoppable auth
359-
{
360-
IColonyNetwork(colonyNetworkAddress).deprecateExtension(_extensionId, _deprecated);
361-
}
362-
363349
function deprecateExtension(address _extension, bool _deprecated)
364350
public stoppable auth
365351
{
366352
IColonyNetwork(colonyNetworkAddress).deprecateExtension(_extension, _deprecated);
367353
}
368354

369-
// Deprecated
370-
function uninstallExtension(bytes32 _extensionId)
371-
public stoppable auth
372-
{
373-
IColonyNetwork(colonyNetworkAddress).uninstallExtension(_extensionId);
374-
}
375-
376355
function uninstallExtension(address _extension)
377356
public stoppable auth
378357
{
@@ -477,6 +456,15 @@ contract Colony is ColonyStorage, PatriciaTreeProofs, MultiChain {
477456
function finishUpgrade() public always {
478457
ColonyAuthority colonyAuthority = ColonyAuthority(address(authority));
479458
bytes4 sig;
459+
460+
sig = bytes4(keccak256("upgradeExtension(address,uint256)"));
461+
colonyAuthority.setRoleCapability(uint8(ColonyRole.Root), address(this), sig, true);
462+
463+
sig = bytes4(keccak256("deprecateExtension(address,bool)"));
464+
colonyAuthority.setRoleCapability(uint8(ColonyRole.Root), address(this), sig, true);
465+
466+
sig = bytes4(keccak256("uninstallExtension(address)"));
467+
colonyAuthority.setRoleCapability(uint8(ColonyRole.Root), address(this), sig, true);
480468
}
481469

482470
function checkNotAdditionalProtectedVariable(uint256 _slot) public view recovery {

contracts/colony/ColonyAuthority.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ contract ColonyAuthority is CommonAuthority {
111111
addRoleCapability(ROOT_ROLE, "burnTokens(address,uint256)");
112112
addRoleCapability(ROOT_ROLE, "unlockToken()");
113113

114-
// Added in colony v6 (dandelion-lwss)
114+
// Added in colony v7 (dandelion-lwss)
115115
addRoleCapability(FUNDING_ROLE, "moveFundsBetweenPots(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address)");
116116

117117
// Added in colony v8 (e-lwss)

contracts/colonyNetwork/ColonyNetworkExtensions.sol

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ contract ColonyNetworkExtensions is ColonyNetworkStorage {
7070
public
7171
stoppable
7272
{
73-
address extension = migrateToMultiExtension(_extensionId);
73+
address extension = migrateToMultiExtension(_extensionId, msg.sender);
7474
upgradeExtension(extension, _newVersion);
7575

7676
emit ExtensionUpgraded(_extensionId, msg.sender, _newVersion);
@@ -101,7 +101,7 @@ contract ColonyNetworkExtensions is ColonyNetworkStorage {
101101
public
102102
stoppable
103103
{
104-
address extension = migrateToMultiExtension(_extensionId);
104+
address extension = migrateToMultiExtension(_extensionId, msg.sender);
105105
deprecateExtension(extension, _deprecated);
106106

107107
emit ExtensionDeprecated(_extensionId, msg.sender, _deprecated);
@@ -122,7 +122,7 @@ contract ColonyNetworkExtensions is ColonyNetworkStorage {
122122
public
123123
stoppable
124124
{
125-
address extension = migrateToMultiExtension(_extensionId);
125+
address extension = migrateToMultiExtension(_extensionId, msg.sender);
126126
uninstallExtension(extension);
127127

128128
emit ExtensionUninstalled(_extensionId, msg.sender);
@@ -142,6 +142,18 @@ contract ColonyNetworkExtensions is ColonyNetworkStorage {
142142
emit ExtensionUninstalled(_extension, msg.sender);
143143
}
144144

145+
function migrateToMultiExtension(bytes32 _extensionId, address _colony)
146+
public
147+
stoppable
148+
returns (address)
149+
{
150+
address extension = installations[_extensionId][_colony];
151+
require(extension != address(0x0), "colony-network-extension-not-installed");
152+
153+
multiInstallations[extension] = payable(_colony);
154+
return extension;
155+
}
156+
145157
// Public view functions
146158

147159
function getExtensionResolver(bytes32 _extensionId, uint256 _version)
@@ -183,12 +195,4 @@ contract ColonyNetworkExtensions is ColonyNetworkStorage {
183195
address extension = Resolver(_resolver).lookup(VERSION_SIG);
184196
return ColonyExtension(extension).version();
185197
}
186-
187-
function migrateToMultiExtension(bytes32 _extensionId) internal returns (address) {
188-
address extension = installations[_extensionId][msg.sender];
189-
require(extension != address(0x0), "colony-network-extension-not-installed");
190-
191-
multiInstallations[extension] = msg.sender;
192-
return extension;
193-
}
194198
}

contracts/colonyNetwork/IColonyNetwork.sol

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,12 @@ interface IColonyNetwork is ColonyNetworkDataTypes, IRecovery {
350350
/// @param extension Address of the extension installation
351351
function uninstallExtension(address extension) external;
352352

353+
/// @notice Migrate extension bookkeeping to multiExtension
354+
/// @param extensionId keccak256 hash of the extension name, used as an indentifier
355+
/// @param colony Address of the colony the extension is installed in
356+
/// @return extension The address of the extension
357+
function migrateToMultiExtension(bytes32 extensionId, address colony) external returns (address extension);
358+
353359
/// @notice Get an extension's resolver.
354360
/// @param extensionId keccak256 hash of the extension name, used as an indentifier
355361
/// @param version Version of the extension

docs/_Interface_IColonyNetwork.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,24 @@ Reverse lookup a username from an address.
733733
|---|---|---|
734734
|domain|string|A string containing the colony-based ENS name corresponding to addr
735735

736+
### `migrateToMultiExtension`
737+
738+
Migrate extension bookkeeping to multiExtension
739+
740+
741+
**Parameters**
742+
743+
|Name|Type|Description|
744+
|---|---|---|
745+
|extensionId|bytes32|keccak256 hash of the extension name, used as an indentifier
746+
|colony|address|Address of the colony the extension is installed in
747+
748+
**Return Parameters**
749+
750+
|Name|Type|Description|
751+
|---|---|---|
752+
|extension|address|The address of the extension
753+
736754
### `punishStakers`
737755

738756
Function called to punish people who staked against a new reputation root hash that turned out to be incorrect.

test/contracts-network/colony-network-extensions.js

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,28 +154,60 @@ contract("Colony Network Extensions", (accounts) => {
154154
await metaColony.addExtensionToNetwork(TEST_EXTENSION, testExtension2Resolver.address);
155155
});
156156

157-
it("allows a root user to install an extension with any version", async () => {
158-
const tx = await colony.installExtension(TEST_EXTENSION, 2, { from: ROOT });
157+
it("allows a root user to install an extension", async () => {
158+
const tx = await colony.installExtension(TEST_EXTENSION, 1, { from: ROOT });
159159

160160
const extensionAddress = getExtensionAddressFromTx(tx);
161-
const extension = await TestExtension2.at(extensionAddress);
161+
const extension = await TestExtension1.at(extensionAddress);
162162
const owner = await extension.owner();
163163
expect(owner).to.equal(colonyNetwork.address);
164164

165165
const identifier = await extension.identifier();
166166
const version = await extension.version();
167167
const colonyAddress = await extension.getColony();
168168
expect(identifier).to.equal(TEST_EXTENSION);
169-
expect(version).to.eq.BN(2);
169+
expect(version).to.eq.BN(1);
170170
expect(colonyAddress).to.equal(colony.address);
171171

172172
// Only colonyNetwork can install the extension
173173
await checkErrorRevert(extension.install(colony.address), "ds-auth-unauthorized");
174174
});
175175

176+
it("allows a root user to install an extension with any version", async () => {
177+
const tx = await colony.installExtension(TEST_EXTENSION, 2, { from: ROOT });
178+
179+
const extensionAddress = getExtensionAddressFromTx(tx);
180+
const extension = await TestExtension2.at(extensionAddress);
181+
182+
const identifier = await extension.identifier();
183+
const version = await extension.version();
184+
expect(identifier).to.equal(TEST_EXTENSION);
185+
expect(version).to.eq.BN(2);
186+
});
187+
176188
it("does not allow an extension to be installed with a nonexistent resolver", async () => {
177189
await checkErrorRevert(colony.installExtension(TEST_EXTENSION, 0, { from: ROOT }), "colony-network-extension-bad-version");
178190
});
191+
192+
it("allows colonies to migrate to multiExtension bookkeeping", async () => {
193+
const extension = await TestExtension1.new();
194+
await extension.install(colony.address);
195+
196+
let colonyAddress;
197+
198+
colonyAddress = await colonyNetwork.getExtensionMultiInstallation(extension.address);
199+
expect(colonyAddress).to.equal(ethers.constants.AddressZero);
200+
201+
// Set up `installations` mapping in the old style
202+
const slot = soliditySha3(`0x000000000000000000000000${colony.address.slice(2)}`, soliditySha3(TEST_EXTENSION, 39));
203+
const value = `0x000000000000000000000000${extension.address.slice(2)}`;
204+
await editableColonyNetwork.setStorageSlot(slot, value);
205+
206+
await colonyNetwork.migrateToMultiExtension(TEST_EXTENSION, colony.address);
207+
208+
colonyAddress = await colonyNetwork.getExtensionMultiInstallation(extension.address);
209+
expect(colonyAddress).to.equal(colony.address);
210+
});
179211
});
180212

181213
describe("upgrading extensions", () => {

0 commit comments

Comments
 (0)