Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(world): allow transferring ownership of namespaces #1274

Merged
merged 12 commits into from
Sep 1, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,23 @@
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes16",
"name": "namespace",
"type": "bytes16"
},
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
18 changes: 18 additions & 0 deletions packages/world/abi/CoreSystem.sol/CoreSystem.abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -647,5 +647,23 @@
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes16",
"name": "namespace",
"type": "bytes16"
},
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,23 @@
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes16",
"name": "namespace",
"type": "bytes16"
},
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
18 changes: 18 additions & 0 deletions packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1233,6 +1233,24 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes16",
"name": "namespace",
"type": "bytes16"
},
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down
2 changes: 2 additions & 0 deletions packages/world/src/interfaces/IAccessManagementSystem.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ interface IAccessManagementSystem {
function grantAccess(bytes16 namespace, bytes16 name, address grantee) external;

function revokeAccess(bytes16 namespace, bytes16 name, address grantee) external;

function transferOwnership(bytes16 namespace, address newOwner) external;
}
3 changes: 2 additions & 1 deletion packages/world/src/modules/core/CoreModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ contract CoreModule is IModule, WorldContext {
* Register function selectors for all CoreSystem functions in the World
*/
function _registerFunctionSelectors() internal {
bytes4[17] memory functionSelectors = [
bytes4[18] memory functionSelectors = [
// --- WorldRegistrationSystem ---
WorldRegistrationSystem.registerNamespace.selector,
WorldRegistrationSystem.registerTable.selector,
Expand All @@ -127,6 +127,7 @@ contract CoreModule is IModule, WorldContext {
// --- AccessManagementSystem ---
AccessManagementSystem.grantAccess.selector,
AccessManagementSystem.revokeAccess.selector,
AccessManagementSystem.transferOwnership.selector,
// --- EphemeralRecordSystem ---
IStoreEphemeral.emitEphemeralRecord.selector,
IWorldEphemeral.emitEphemeralRecord.selector
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AccessControl } from "../../../AccessControl.sol";
import { Call } from "../../../Call.sol";
import { ResourceAccess } from "../../../tables/ResourceAccess.sol";
import { InstalledModules } from "../../../tables/InstalledModules.sol";
import { NamespaceOwner } from "../../../tables/NamespaceOwner.sol";

/**
* Granting and revoking access from/to resources.
Expand Down Expand Up @@ -35,4 +36,20 @@ contract AccessManagementSystem is System {
// Revoke access from the given resource
ResourceAccess.deleteRecord(resourceSelector, grantee);
}

/**
* Transfer ownership of the given namespace to newOwner.
* Revoke ResourceAccess for previous owner and grant to newOwner.
* Requires the caller to own the namespace.
*/
function transferOwnership(bytes16 namespace, address newOwner) public virtual {
// Require the caller to own the namespace
bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, 0, _msgSender());
// Grant access to new owner
ResourceAccess.set(resourceSelector, newOwner, true);
// Set namespace new owner
NamespaceOwner.set(namespace, newOwner);
// Revoke access from old owner
ResourceAccess.deleteRecord(resourceSelector, _msgSender());
}
}
8 changes: 8 additions & 0 deletions packages/world/test/World.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,14 @@ contract WorldTest is Test, GasReporter {
world.registerNamespace("test");
}

function testTransferNamespace() public {
world.registerNamespace("testTransfer");
world.transferOwnership("testTransfer", address(1));
assertEq(NamespaceOwner.get(world, "testTransfer"), address(1), "new owner should be namespace owner");
// Expect the new owner to have access
assertEq(ResourceAccess.get(world, "testTransfer", address(1)), true, "new owner should have access");
johngrantuk marked this conversation as resolved.
Show resolved Hide resolved
}

function testRegisterTable() public {
Schema schema = SchemaEncodeHelper.encode(SchemaType.BOOL, SchemaType.UINT256, SchemaType.STRING);
bytes16 namespace = "testNamespace";
Expand Down