Skip to content

Commit

Permalink
chore: rename 'Dock' to 'Station'
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielstoica committed Oct 31, 2024
1 parent 32a9c02 commit e4e5560
Show file tree
Hide file tree
Showing 24 changed files with 239 additions and 306 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
pragma solidity ^0.8.26;

import { BaseScript } from "./Base.s.sol";
import { DockRegistry } from "./../src/DockRegistry.sol";
import { StationRegistry } from "./../src/StationRegistry.sol";
import { ModuleKeeper } from "./../src/ModuleKeeper.sol";
import { EntryPoint } from "@thirdweb/contracts/prebuilts/account/utils/Entrypoint.sol";

/// @notice Deploys at deterministic addresses across chains an instance of {DockRegistry}
/// @notice Deploys at deterministic addresses across chains an instance of {StationRegistry}
/// @dev Reverts if any contract has already been deployed
contract DeployDeterministicDockRegistry is BaseScript {
contract DeployDeterministicStationRegistry is BaseScript {
/// @dev By using a salt, Forge will deploy the contract via a deterministic CREATE2 factory
/// https://book.getfoundry.sh/tutorials/create2-tutorial?highlight=deter#deterministic-deployment-using-create2
function run(
string memory create2Salt,
address initialAdmin,
EntryPoint entrypoint,
ModuleKeeper moduleKeeper
) public virtual broadcast returns (DockRegistry dockRegistry) {
) public virtual broadcast returns (StationRegistry stationRegistry) {
bytes32 salt = bytes32(abi.encodePacked(create2Salt));

// Deterministically deploy the {DockRegistry} smart account factory
dockRegistry = new DockRegistry{ salt: salt }(initialAdmin, entrypoint, moduleKeeper);
// Deterministically deploy the {StationRegistry} smart account factory
stationRegistry = new StationRegistry{ salt: salt }(initialAdmin, entrypoint, moduleKeeper);
}
}
16 changes: 8 additions & 8 deletions script/DeployWorkspace.s.sol → script/DeploySpace.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ pragma solidity ^0.8.26;

import { BaseScript } from "./Base.s.sol";
import { Space } from "../src/Space.sol";
import { DockRegistry } from "./../src/DockRegistry.sol";
import { StationRegistry } from "./../src/StationRegistry.sol";

/// @notice Deploys an instance of {Space} and enables initial module(s)
contract DeployContainer is BaseScript {
contract DeploySpace is BaseScript {
function run(
address initialAdmin,
DockRegistry dockRegistry,
uint256 dockId,
StationRegistry stationRegistry,
uint256 stationId,
address[] memory initialModules
) public virtual broadcast returns (Space space) {
// Get the number of total accounts created by the `initialAdmin` deployer
uint256 totalAccountsOfAdmin = dockRegistry.totalAccountsOfSigner(initialAdmin);
uint256 totalAccountsOfAdmin = stationRegistry.totalAccountsOfSigner(initialAdmin);

// Construct the ABI-encoded data to be passed to the `createAccount` method
bytes memory data = abi.encode(totalAccountsOfAdmin, dockId, initialModules);
bytes memory data = abi.encode(totalAccountsOfAdmin, stationId, initialModules);

// Deploy a new {Space} smart account through the {DockRegistry} account factory
space = Space(payable(dockRegistry.createAccount(initialAdmin, data)));
// Deploy a new {Space} smart account through the {StationRegistry} account factory
space = Space(payable(stationRegistry.createAccount(initialAdmin, data)));
}
}
8 changes: 4 additions & 4 deletions src/Space.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { ISpace } from "./interfaces/ISpace.sol";
import { ModuleManager } from "./abstracts/ModuleManager.sol";
import { IModuleManager } from "./interfaces/IModuleManager.sol";
import { Errors } from "./libraries/Errors.sol";
import { DockRegistry } from "./DockRegistry.sol";
import { StationRegistry } from "./StationRegistry.sol";
import { ModuleKeeper } from "./ModuleKeeper.sol";

/// @title Space
Expand All @@ -44,7 +44,7 @@ contract Space is ISpace, AccountCore, ERC1271, ModuleManager {
(,, address[] memory initialModules) = abi.decode(_data, (uint256, uint256, address[]));

// Enable the initial module(s)
ModuleKeeper moduleKeeper = DockRegistry(factory).moduleKeeper();
ModuleKeeper moduleKeeper = StationRegistry(factory).moduleKeeper();
_initializeModuleManager(moduleKeeper, initialModules);

// Initialize the {Space} smart contract
Expand Down Expand Up @@ -179,7 +179,7 @@ contract Space is ISpace, AccountCore, ERC1271, ModuleManager {
/// @inheritdoc IModuleManager
function enableModule(address module) public override onlyAdminOrEntrypoint {
// Retrieve the address of the {ModuleKeeper}
ModuleKeeper moduleKeeper = DockRegistry(factory).moduleKeeper();
ModuleKeeper moduleKeeper = StationRegistry(factory).moduleKeeper();

// Checks, Effects: enable the module
_enableModule(moduleKeeper, module);
Expand Down Expand Up @@ -292,7 +292,7 @@ contract Space is ISpace, AccountCore, ERC1271, ModuleManager {
/// @dev Registers the account on the factory if it hasn't been registered yet
function _registerOnFactory() internal {
// Get the address of the factory contract
DockRegistry factoryContract = DockRegistry(factory);
StationRegistry factoryContract = StationRegistry(factory);

// Checks: the smart account is registered on the factory contract
if (!factoryContract.isRegistered(address(this))) {
Expand Down
86 changes: 43 additions & 43 deletions src/DockRegistry.sol → src/StationRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,111 +6,111 @@ import { IEntryPoint } from "@thirdweb/contracts/prebuilts/account/interface/IEn
import { PermissionsEnumerable } from "@thirdweb/contracts/extension/PermissionsEnumerable.sol";
import { EnumerableSet } from "@thirdweb/contracts/external-deps/openzeppelin/utils/structs/EnumerableSet.sol";

import { IDockRegistry } from "./interfaces/IDockRegistry.sol";
import { IStationRegistry } from "./interfaces/IStationRegistry.sol";
import { Space } from "./Space.sol";
import { ModuleKeeper } from "./ModuleKeeper.sol";
import { Errors } from "./libraries/Errors.sol";

/// @title DockRegistry
/// @notice See the documentation in {IDockRegistry}
contract DockRegistry is IDockRegistry, BaseAccountFactory, PermissionsEnumerable {
/// @title StationRegistry
/// @notice See the documentation in {IStationRegistry}
contract StationRegistry is IStationRegistry, BaseAccountFactory, PermissionsEnumerable {
using EnumerableSet for EnumerableSet.AddressSet;

/*//////////////////////////////////////////////////////////////////////////
STORAGE
//////////////////////////////////////////////////////////////////////////*/

/// @inheritdoc IDockRegistry
/// @inheritdoc IStationRegistry
ModuleKeeper public override moduleKeeper;

/// @inheritdoc IDockRegistry
mapping(uint256 dockId => address owner) public override ownerOfDock;
/// @inheritdoc IStationRegistry
mapping(uint256 stationId => address owner) public override ownerOfStation;

/// @inheritdoc IDockRegistry
mapping(address space => uint256 dockId) public override dockIdOfSpace;
/// @inheritdoc IStationRegistry
mapping(address space => uint256 stationId) public override stationIdOfSpace;

/// @dev Counter to keep track of the next dock ID
uint256 private _dockNextId;
/// @dev Counter to keep track of the next station ID
uint256 private _stationNextId;

/*//////////////////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////////////////*/

/// @dev Initializes the {Space} implementation, the Entrypoint, registry admin and sets first dock ID to 1
/// @dev Initializes the {Space} implementation, the Entrypoint, registry admin and sets first station ID to 1
constructor(
address _initialAdmin,
IEntryPoint _entrypoint,
ModuleKeeper _moduleKeeper
) BaseAccountFactory(address(new Space(_entrypoint, address(this))), address(_entrypoint)) {
_setupRole(DEFAULT_ADMIN_ROLE, _initialAdmin);

_dockNextId = 1;
_stationNextId = 1;
moduleKeeper = _moduleKeeper;
}

/*//////////////////////////////////////////////////////////////////////////
NON-CONSTANT FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/

/// @inheritdoc IDockRegistry
/// @inheritdoc IStationRegistry
function createAccount(
address _admin,
bytes calldata _data
) public override(BaseAccountFactory, IDockRegistry) returns (address) {
// Get the dock ID and initial modules array from the calldata
) public override(BaseAccountFactory, IStationRegistry) returns (address) {
// Get the station ID and initial modules array from the calldata
// Note: calldata contains a salt (usually the number of accounts created by an admin),
// dock ID and an array with the initial enabled modules on the account
(, uint256 dockId, address[] memory initialModules) = abi.decode(_data, (uint256, uint256, address[]));
// station ID and an array with the initial enabled modules on the account
(, uint256 stationId, address[] memory initialModules) = abi.decode(_data, (uint256, uint256, address[]));

// Checks: a new dock must be created first
if (dockId == 0) {
// Store the ID of the next dock
dockId = _dockNextId;
// Checks: a new station must be created first
if (stationId == 0) {
// Store the ID of the next station
stationId = _stationNextId;

// Effects: set the owner of the freshly created dock
ownerOfDock[dockId] = msg.sender;
// Effects: set the owner of the freshly created station
ownerOfStation[stationId] = msg.sender;

// Effects: increment the next dock ID
// Use unchecked because the dock ID cannot realistically overflow
// Effects: increment the next station ID
// Use unchecked because the station ID cannot realistically overflow
unchecked {
_dockNextId++;
_stationNextId++;
}
} else {
// Checks: `msg.sender` is the dock owner
if (ownerOfDock[dockId] != msg.sender) {
revert Errors.CallerNotDockOwner();
// Checks: `msg.sender` is the station owner
if (ownerOfStation[stationId] != msg.sender) {
revert Errors.CallerNotStationOwner();
}
}

// Interactions: deploy a new {Space} smart account
address space = super.createAccount(_admin, _data);

// Assign the ID of the dock to which the new space belongs
dockIdOfSpace[space] = dockId;
// Assign the ID of the station to which the new space belongs
stationIdOfSpace[space] = stationId;

// Log the {Space} creation
emit SpaceCreated(_admin, dockId, space, initialModules);
emit SpaceCreated(_admin, stationId, space, initialModules);

// Return {Space} smart account address
return space;
}

/// @inheritdoc IDockRegistry
function transferDockOwnership(uint256 dockId, address newOwner) external {
// Checks: `msg.sender` is the current owner of the dock
address currentOwner = ownerOfDock[dockId];
/// @inheritdoc IStationRegistry
function transferStationOwnership(uint256 stationId, address newOwner) external {
// Checks: `msg.sender` is the current owner of the station
address currentOwner = ownerOfStation[stationId];
if (msg.sender != currentOwner) {
revert Errors.CallerNotDockOwner();
revert Errors.CallerNotStationOwner();
}

// Effects: update dock's ownership
ownerOfDock[dockId] = newOwner;
// Effects: update station's ownership
ownerOfStation[stationId] = newOwner;

// Log the ownership transfer
emit DockOwnershipTransferred({ dockId: dockId, oldOwner: currentOwner, newOwner: newOwner });
emit StationOwnershipTransferred({ stationId: stationId, oldOwner: currentOwner, newOwner: newOwner });
}

/// @inheritdoc IDockRegistry
/// @inheritdoc IStationRegistry
function updateModuleKeeper(ModuleKeeper newModuleKeeper) external onlyRole(DEFAULT_ADMIN_ROLE) {
// Effects: update the {ModuleKeeper} address
moduleKeeper = newModuleKeeper;
Expand All @@ -123,7 +123,7 @@ contract DockRegistry is IDockRegistry, BaseAccountFactory, PermissionsEnumerabl
CONSTANT FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/

/// @inheritdoc IDockRegistry
/// @inheritdoc IStationRegistry
function totalAccountsOfSigner(address signer) public view returns (uint256) {
return accountsOfSigner[signer].length();
}
Expand Down
5 changes: 0 additions & 5 deletions src/interfaces/IModuleManager.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.26;

import { DockRegistry } from "./../DockRegistry.sol";

/// @title IModuleManager
/// @notice Contract that provides functionalities to manage multiple modules within a {Space} contract
interface IModuleManager {
Expand All @@ -22,9 +20,6 @@ interface IModuleManager {
CONSTANT FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/

/// @notice Returns the address of the {DockRegistry} contract
/* function dockRegistry() external view returns (DockRegistry);
*/
/// @notice Checks whether the `module` module is enabled on the space
function isModuleEnabled(address module) external view returns (bool isEnabled);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@ import { Space } from "./../Space.sol";
import { IModuleKeeper } from "./IModuleKeeper.sol";
import { ModuleKeeper } from "./../ModuleKeeper.sol";

/// @title IDockRegistry
/// @notice Contract that provides functionalities to create docks and deploy {Space}s from a single place
interface IDockRegistry {
/// @title IStationRegistry
/// @notice Contract that provides functionalities to create stations and deploy {Space}s from a single place
interface IStationRegistry {
/*//////////////////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////////////////*/

/// @notice Emitted when a new {Space} contract gets deployed
/// @param owner The address of the owner
/// @param dockId The ID of the dock to which this {Space} belongs
/// @param stationId The ID of the station to which this {Space} belongs
/// @param space The address of the {Space}
/// @param initialModules Array of initially enabled modules
event SpaceCreated(address indexed owner, uint256 indexed dockId, address space, address[] initialModules);
event SpaceCreated(address indexed owner, uint256 indexed stationId, address space, address[] initialModules);

/// @notice Emitted when the ownership of a {Dock} is transferred to a new owner
/// @param dockId The address of the {Dock}
/// @notice Emitted when the ownership of a {Station} is transferred to a new owner
/// @param stationId The address of the {Station}
/// @param oldOwner The address of the current owner
/// @param newOwner The address of the new owner
event DockOwnershipTransferred(uint256 indexed dockId, address oldOwner, address newOwner);
event StationOwnershipTransferred(uint256 indexed stationId, address oldOwner, address newOwner);

/// @notice Emitted when the {ModuleKeeper} address is updated
/// @param newModuleKeeper The new address of the {ModuleKeeper}
Expand All @@ -36,11 +36,11 @@ interface IDockRegistry {
/// @notice Returns the address of the {ModuleKeeper} contract
function moduleKeeper() external view returns (ModuleKeeper);

/// @notice Retrieves the owner of the given dock ID
function ownerOfDock(uint256 dockId) external view returns (address);
/// @notice Retrieves the owner of the given station ID
function ownerOfStation(uint256 stationId) external view returns (address);

/// @notice Retrieves the dock ID of the given space address
function dockIdOfSpace(address space) external view returns (uint256);
/// @notice Retrieves the station ID of the given space address
function stationIdOfSpace(address space) external view returns (uint256);

/// @notice Retrieves the total number of accounts created by the `signer` address
function totalAccountsOfSigner(address signer) external view returns (uint256);
Expand All @@ -49,37 +49,37 @@ interface IDockRegistry {
NON-CONSTANT FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/

/// @notice Creates a new {Space} contract and attaches it to a dock
/// @notice Creates a new {Space} contract and attaches it to a station
///
/// Notes:
/// - if `dockId` equal zero, a new dock will be created
/// - if `stationId` equal zero, a new station will be created
///
/// Requirements:
/// - `msg.sender` MUST be the dock owner if a new space is to be attached to an existing dock
/// - `msg.sender` MUST be the station owner if a new space is to be attached to an existing station
///
/// @param _admin The ID of the dock to attach the {Space} to
/// @param _admin The ID of the station to attach the {Space} to
/// @param _data Array of initially enabled modules
function createAccount(address _admin, bytes calldata _data) external returns (address space);

/// @notice Transfers the ownership of the `dockId` dock
/// @notice Transfers the ownership of the `stationId` station
///
/// Notes:
/// - does not check for zero-address; ownership will be renounced if `newOwner` is the zero-address
///
/// Requirements:
/// - `msg.sender` MUST be the current dock owner
/// - `msg.sender` MUST be the current station owner
///
/// @param dockId The ID of the dock of whose ownership is to be transferred
/// @param stationId The ID of the station of whose ownership is to be transferred
/// @param newOwner The address of the new owner
function transferDockOwnership(uint256 dockId, address newOwner) external;
function transferStationOwnership(uint256 stationId, address newOwner) external;

/// @notice Updates the address of the {ModuleKeeper}
///
/// Notes:
/// - does not check for zero-address;
///
/// Requirements:
/// - reverts if `msg.sender` is not the {DockRegistry} owner
/// - reverts if `msg.sender` is not the {StationRegistry} owner
///
/// @param newModuleKeeper The new address of the {ModuleKeeper}
function updateModuleKeeper(ModuleKeeper newModuleKeeper) external;
Expand Down
8 changes: 4 additions & 4 deletions src/libraries/Errors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ pragma solidity ^0.8.26;
/// @notice Library containing all custom errors the protocol may revert with
library Errors {
/*//////////////////////////////////////////////////////////////////////////
DOCK-REGISTRY
STATION-REGISTRY
//////////////////////////////////////////////////////////////////////////*/

/// @notice Thrown when `msg.sender` is not the dock owner
error CallerNotDockOwner();
/// @notice Thrown when `msg.sender` is not the station owner
error CallerNotStationOwner();

/*//////////////////////////////////////////////////////////////////////////
CONTAINER
SPACE
//////////////////////////////////////////////////////////////////////////*/

/// @notice Thrown when `msg.sender` is not the {Space} contract owner
Expand Down
Loading

0 comments on commit e4e5560

Please sign in to comment.