Skip to content

Commit

Permalink
add puppet factory
Browse files Browse the repository at this point in the history
  • Loading branch information
alvrs committed Oct 30, 2023
1 parent a6bdbbd commit 2ecfa3d
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,4 @@ contract PuppetDelegationControl is DelegationControl {
address puppet = _msgSender();
return PuppetRegistry.get(PUPPET_TABLE_ID, systemId) == puppet;
}

/**
* Initialize a delegation by storing the mapping from systemId to puppet
*/
function initDelegation(ResourceId systemId, address puppet) public {
// Require the caller to be the owner of the system
AccessControlLib.requireOwner(systemId, _msgSender());
PuppetRegistry.set(PUPPET_TABLE_ID, systemId, puppet);
}
}
25 changes: 25 additions & 0 deletions packages/world-modules/src/modules/puppet/PuppetFactorySystem.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.21;

import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";
import { System } from "@latticexyz/world/src/System.sol";
import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.sol";

import { AccessControlLib } from "../../utils/AccessControlLib.sol";

import { PuppetRegistry } from "./tables/PuppetRegistry.sol";
import { Puppet } from "./Puppet.sol";
import { PUPPET_TABLE_ID } from "./constants.sol";

contract PuppetFactorySystem is System {
function createPuppet(ResourceId systemId) public returns (address puppet) {
// Only the owner of a system can create a puppet for it
AccessControlLib.requireOwner(systemId, _msgSender());

// Deploy a new puppet contract
puppet = address(new Puppet(IBaseWorld(_world()), systemId));

// Register the puppet
PuppetRegistry.set(PUPPET_TABLE_ID, systemId, puppet);
}
}
2 changes: 1 addition & 1 deletion packages/world-modules/src/modules/puppet/PuppetMaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Puppet } from "./Puppet.sol";
contract PuppetMaster {
error PuppetMaster_NoPuppet(address systemAddress, ResourceId systemId);

function puppet() internal returns (Puppet) {
function puppet() internal view returns (Puppet) {
ResourceId systemId = SystemRegistry.getSystemId(address(this));
address puppetAddress = PuppetRegistry.get(PUPPET_TABLE_ID, systemId);
if (puppetAddress == address(0)) revert PuppetMaster_NoPuppet(address(this), systemId);
Expand Down
7 changes: 5 additions & 2 deletions packages/world-modules/src/modules/puppet/PuppetModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { Module } from "@latticexyz/world/src/Module.sol";
import { WorldContextConsumer } from "@latticexyz/world/src/WorldContext.sol";
import { revertWithBytes } from "@latticexyz/world/src/revertWithBytes.sol";

import { PuppetFactorySystem } from "./PuppetFactorySystem.sol";
import { PuppetDelegationControl } from "./PuppetDelegationControl.sol";
import { MODULE_NAME, PUPPET_DELEGATION, PUPPET_TABLE_ID } from "./constants.sol";
import { MODULE_NAME, PUPPET_DELEGATION, PUPPET_FACTORY, PUPPET_TABLE_ID } from "./constants.sol";

import { PuppetRegistry } from "./tables/PuppetRegistry.sol";

Expand All @@ -17,6 +18,7 @@ import { PuppetRegistry } from "./tables/PuppetRegistry.sol";
*/
contract PuppetModule is Module {
PuppetDelegationControl private immutable puppetDelegationControl = new PuppetDelegationControl();
PuppetFactorySystem private immutable puppetFactorySystem = new PuppetFactorySystem();

function getName() public pure returns (bytes16) {
return MODULE_NAME;
Expand All @@ -41,7 +43,8 @@ contract PuppetModule is Module {
// Register table
PuppetRegistry.register(PUPPET_TABLE_ID);

// Register system
// Register puppet factory and delegation control
world.registerSystem(PUPPET_FACTORY, puppetFactorySystem, true);
world.registerSystem(PUPPET_DELEGATION, puppetDelegationControl, true);
}
}
4 changes: 4 additions & 0 deletions packages/world-modules/src/modules/puppet/constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ ResourceId constant PUPPET_DELEGATION = ResourceId.wrap(
bytes32(abi.encodePacked(RESOURCE_SYSTEM, NAMESPACE, bytes16("Delegation")))
);

ResourceId constant PUPPET_FACTORY = ResourceId.wrap(
bytes32(abi.encodePacked(RESOURCE_SYSTEM, NAMESPACE, bytes16("Factory")))
);

ResourceId constant PUPPET_TABLE_ID = ResourceId.wrap(
bytes32(abi.encodePacked(RESOURCE_TABLE, NAMESPACE, bytes16("PuppetRegistry")))
);
16 changes: 10 additions & 6 deletions packages/world-modules/src/modules/puppet/createPuppet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,21 @@ pragma solidity >=0.8.21;
import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";
import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.sol";
import { WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol";
import { PUPPET_DELEGATION } from "./constants.sol";
import { PUPPET_DELEGATION, PUPPET_FACTORY } from "./constants.sol";
import { PuppetDelegationControl } from "./PuppetDelegationControl.sol";
import { Puppet } from "./Puppet.sol";
import { PuppetFactorySystem } from "./PuppetFactorySystem.sol";

using WorldResourceIdInstance for ResourceId;

/**
* This free function can be used to create a puppet and register it with the puppet delegation control.
* Since it is inlined in the caller's context, the calls originate from the caller's address.
*/
function createPuppet(IBaseWorld world, ResourceId systemId) returns (address puppet) {
puppet = address(new Puppet(world, systemId));
world.registerNamespaceDelegation(
systemId.getNamespaceId(),
PUPPET_DELEGATION,
abi.encodeCall(PuppetDelegationControl.initDelegation, (systemId, puppet))
puppet = abi.decode(
world.call(PUPPET_FACTORY, abi.encodeCall(PuppetFactorySystem.createPuppet, (systemId))),
(address)
);
world.registerNamespaceDelegation(systemId.getNamespaceId(), PUPPET_DELEGATION, new bytes(0));
}

0 comments on commit 2ecfa3d

Please sign in to comment.