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): add CallWithSignatureSystem #3496

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/world/mud.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ export const configInput = {
},
key: [],
},
CallWithSignatureNonces: {
schema: { signer: "address", nonce: "uint256" },
key: ["signer"],
},
},
excludeSystems: [
// Worldgen currently does not support systems inheriting logic
Expand Down
5 changes: 5 additions & 0 deletions packages/world/src/IWorldErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,9 @@ interface IWorldErrors {
* @param functionSelector The function selector of the disallowed callback.
*/
error World_CallbackNotAllowed(bytes4 functionSelector);

/**
* @notice Raised when the signature of a call to `callWithSignature` is invalid.
*/
error World_InvalidSignature();
}
1 change: 1 addition & 0 deletions packages/world/src/codegen/index.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/world/src/codegen/interfaces/IBaseWorld.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

199 changes: 199 additions & 0 deletions packages/world/src/codegen/tables/CallWithSignatureNonces.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 15 additions & 3 deletions packages/world/src/modules/init/InitModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ import { NamespaceDelegationControl } from "../../codegen/tables/NamespaceDelega
import { AccessManagementSystem } from "./implementations/AccessManagementSystem.sol";
import { BalanceTransferSystem } from "./implementations/BalanceTransferSystem.sol";
import { BatchCallSystem } from "./implementations/BatchCallSystem.sol";
import { CallWithSignatureSystem } from "./implementations/CallWithSignatureSystem/CallWithSignatureSystem.sol";

import { RegistrationSystem } from "./RegistrationSystem.sol";
import { ACCESS_MANAGEMENT_SYSTEM_ID, BALANCE_TRANSFER_SYSTEM_ID, BATCH_CALL_SYSTEM_ID, REGISTRATION_SYSTEM_ID } from "./constants.sol";
import { getFunctionSignaturesAccessManagement, getFunctionSignaturesBalanceTransfer, getFunctionSignaturesBatchCall, getFunctionSignaturesRegistration } from "./functionSignatures.sol";
import { ACCESS_MANAGEMENT_SYSTEM_ID, BALANCE_TRANSFER_SYSTEM_ID, BATCH_CALL_SYSTEM_ID, REGISTRATION_SYSTEM_ID, DELEGATION_SYSTEM_ID } from "./constants.sol";
import { getFunctionSignaturesAccessManagement, getFunctionSignaturesBalanceTransfer, getFunctionSignaturesBatchCall, getFunctionSignaturesRegistration, getFunctionSignaturesDelegation } from "./functionSignatures.sol";

import { Systems } from "../../codegen/tables/Systems.sol";
import { FunctionSelectors } from "../../codegen/tables/FunctionSelectors.sol";
Expand All @@ -31,6 +32,7 @@ import { SystemHooks } from "../../codegen/tables/SystemHooks.sol";
import { SystemRegistry } from "../../codegen/tables/SystemRegistry.sol";
import { InitModuleAddress } from "../../codegen/tables/InitModuleAddress.sol";
import { Balances } from "../../codegen/tables/Balances.sol";
import { CallWithSignatureNonces } from "../../codegen/tables/CallWithSignatureNonces.sol";

import { WorldRegistrationSystem } from "./implementations/WorldRegistrationSystem.sol";

Expand All @@ -45,17 +47,20 @@ contract InitModule is Module {
address internal immutable balanceTransferSystem;
address internal immutable batchCallSystem;
address internal immutable registrationSystem;
address internal immutable delegationSystem;

constructor(
AccessManagementSystem _accessManagementSystem,
BalanceTransferSystem _balanceTransferSystem,
BatchCallSystem _batchCallSystem,
RegistrationSystem _registrationSystem
RegistrationSystem _registrationSystem,
CallWithSignatureSystem _delegationSystem
) {
accessManagementSystem = address(_accessManagementSystem);
balanceTransferSystem = address(_balanceTransferSystem);
batchCallSystem = address(_batchCallSystem);
registrationSystem = address(_registrationSystem);
delegationSystem = address(_delegationSystem);
}

/**
Expand Down Expand Up @@ -94,6 +99,7 @@ contract InitModule is Module {
SystemHooks.register();
SystemRegistry.register();
InitModuleAddress.register();
CallWithSignatureNonces.register();

ResourceIds._setExists(ROOT_NAMESPACE_ID, true);
NamespaceOwner._set(ROOT_NAMESPACE_ID, _msgSender());
Expand All @@ -116,6 +122,7 @@ contract InitModule is Module {
_registerSystem(balanceTransferSystem, BALANCE_TRANSFER_SYSTEM_ID);
_registerSystem(batchCallSystem, BATCH_CALL_SYSTEM_ID);
_registerSystem(registrationSystem, REGISTRATION_SYSTEM_ID);
_registerSystem(delegationSystem, DELEGATION_SYSTEM_ID);
}

/**
Expand Down Expand Up @@ -155,6 +162,11 @@ contract InitModule is Module {
for (uint256 i = 0; i < functionSignaturesRegistration.length; i++) {
_registerRootFunctionSelector(REGISTRATION_SYSTEM_ID, functionSignaturesRegistration[i]);
}

string[1] memory functionSignaturesDelegation = getFunctionSignaturesDelegation();
for (uint256 i = 0; i < functionSignaturesDelegation.length; i++) {
_registerRootFunctionSelector(DELEGATION_SYSTEM_ID, functionSignaturesDelegation[i]);
}
}

/**
Expand Down
8 changes: 8 additions & 0 deletions packages/world/src/modules/init/constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,11 @@ ResourceId constant BATCH_CALL_SYSTEM_ID = ResourceId.wrap(
ResourceId constant REGISTRATION_SYSTEM_ID = ResourceId.wrap(
bytes32(abi.encodePacked(RESOURCE_SYSTEM, ROOT_NAMESPACE, bytes16("Registration")))
);

/**
* @dev Resource ID for the delegation system.
* @dev This ID is derived from the RESOURCE_SYSTEM type, the ROOT_NAMESPACE, and the system name.
*/
ResourceId constant DELEGATION_SYSTEM_ID = ResourceId.wrap(
(bytes32(abi.encodePacked(RESOURCE_SYSTEM, ROOT_NAMESPACE, "Delegation")))
);
10 changes: 10 additions & 0 deletions packages/world/src/modules/init/functionSignatures.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,13 @@ function getFunctionSignaturesRegistration() pure returns (string[14] memory) {
"unregisterNamespaceDelegation(bytes32)"
];
}

/**
* @dev Function signatures for delegation system
*/
function getFunctionSignaturesDelegation() pure returns (string[1] memory) {
return [
// --- CallWithSignatureSystem ---
"callWithSignature(address,bytes32,bytes,uint256)"
];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.24;

import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";

import { System } from "../../../../System.sol";
import { SystemCall } from "../../../../SystemCall.sol";
import { CallWithSignatureNonces } from "../../../../codegen/tables/CallWithSignatureNonces.sol";
import { IWorldErrors } from "../../../../IWorldErrors.sol";
import { LimitedCallContext } from "../../LimitedCallContext.sol";
import { createDelegation } from "../createDelegation.sol";
import { getSignedMessageHash } from "./getSignedMessageHash.sol";
import { ECDSA } from "./ECDSA.sol";
import { validateCallWithSignature } from "./validateCallWithSignature.sol";

contract CallWithSignatureSystem is System, IWorldErrors, LimitedCallContext {
/**
* @notice Calls a system with a given system ID using the given signature.
* @param signer The address on whose behalf the system is called.
* @param systemId The ID of the system to be called.
* @param callData The ABI data for the system call.
* @param signature The EIP712 signature.
* @return Return data from the system call.
*/
function callWithSignature(
address signer,
ResourceId systemId,
bytes memory callData,
bytes memory signature
) public payable onlyDelegatecall returns (bytes memory) {
validateCallWithSignature(signer, systemId, callData, signature);

CallWithSignatureNonces._set(signer, CallWithSignatureNonces._get(signer) + 1);

return SystemCall.callWithHooksOrRevert(signer, systemId, callData, _msgValue());
}
}
Loading
Loading