Skip to content

Commit

Permalink
test(world): check core system functions can only be delegatecalled (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
yonadaaa authored Feb 27, 2024
1 parent 9c83adc commit 2b65f13
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 37 deletions.
2 changes: 1 addition & 1 deletion packages/world/gas-report.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"file": "test/Factories.t.sol",
"test": "testWorldFactoryGas",
"name": "deploy world via WorldFactory",
"gasUsed": 12697195
"gasUsed": 12698811
},
{
"file": "test/World.t.sol",
Expand Down
41 changes: 5 additions & 36 deletions packages/world/src/modules/init/InitModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { BatchCallSystem } from "./implementations/BatchCallSystem.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 { Systems } from "../../codegen/tables/Systems.sol";
import { FunctionSelectors } from "../../codegen/tables/FunctionSelectors.sol";
Expand Down Expand Up @@ -135,54 +136,22 @@ contract InitModule is Module {
* @dev Iterates through known function signatures and registers them.
*/
function _registerFunctionSelectors() internal {
string[4] memory functionSignaturesAccessManagement = [
// --- AccessManagementSystem ---
"grantAccess(bytes32,address)",
"revokeAccess(bytes32,address)",
"transferOwnership(bytes32,address)",
"renounceOwnership(bytes32)"
];
string[4] memory functionSignaturesAccessManagement = getFunctionSignaturesAccessManagement();
for (uint256 i = 0; i < functionSignaturesAccessManagement.length; i++) {
_registerRootFunctionSelector(ACCESS_MANAGEMENT_SYSTEM_ID, functionSignaturesAccessManagement[i]);
}

string[2] memory functionSignaturesBalanceTransfer = [
// --- BalanceTransferSystem ---
"transferBalanceToNamespace(bytes32,bytes32,uint256)",
"transferBalanceToAddress(bytes32,address,uint256)"
];
string[2] memory functionSignaturesBalanceTransfer = getFunctionSignaturesBalanceTransfer();
for (uint256 i = 0; i < functionSignaturesBalanceTransfer.length; i++) {
_registerRootFunctionSelector(BALANCE_TRANSFER_SYSTEM_ID, functionSignaturesBalanceTransfer[i]);
}

string[2] memory functionSignaturesBatchCall = [
// --- BatchCallSystem ---
"batchCall((bytes32,bytes)[])",
"batchCallFrom((address,bytes32,bytes)[])"
];
string[2] memory functionSignaturesBatchCall = getFunctionSignaturesBatchCall();
for (uint256 i = 0; i < functionSignaturesBatchCall.length; i++) {
_registerRootFunctionSelector(BATCH_CALL_SYSTEM_ID, functionSignaturesBatchCall[i]);
}

string[14] memory functionSignaturesRegistration = [
// --- ModuleInstallationSystem ---
"installModule(address,bytes)",
// --- StoreRegistrationSystem ---
"registerTable(bytes32,bytes32,bytes32,bytes32,string[],string[])",
"registerStoreHook(bytes32,address,uint8)",
"unregisterStoreHook(bytes32,address)",
// --- WorldRegistrationSystem ---
"registerNamespace(bytes32)",
"registerSystemHook(bytes32,address,uint8)",
"unregisterSystemHook(bytes32,address)",
"registerSystem(bytes32,address,bool)",
"registerFunctionSelector(bytes32,string)",
"registerRootFunctionSelector(bytes32,string,bytes4)",
"registerDelegation(address,bytes32,bytes)",
"unregisterDelegation(address)",
"registerNamespaceDelegation(bytes32,bytes32,bytes)",
"unregisterNamespaceDelegation(bytes32)"
];
string[14] memory functionSignaturesRegistration = getFunctionSignaturesRegistration();
for (uint256 i = 0; i < functionSignaturesRegistration.length; i++) {
_registerRootFunctionSelector(REGISTRATION_SYSTEM_ID, functionSignaturesRegistration[i]);
}
Expand Down
62 changes: 62 additions & 0 deletions packages/world/src/modules/init/functionSignatures.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.24;

/**
* @dev Function signatures for access management system
*/
function getFunctionSignaturesAccessManagement() pure returns (string[4] memory) {
return [
// --- AccessManagementSystem ---
"grantAccess(bytes32,address)",
"revokeAccess(bytes32,address)",
"transferOwnership(bytes32,address)",
"renounceOwnership(bytes32)"
];
}

/**
* @dev Function signatures for balance transfer system
*/
function getFunctionSignaturesBalanceTransfer() pure returns (string[2] memory) {
return [
// --- BalanceTransferSystem ---
"transferBalanceToNamespace(bytes32,bytes32,uint256)",
"transferBalanceToAddress(bytes32,address,uint256)"
];
}

/**
* @dev Function signatures for batch call system
*/
function getFunctionSignaturesBatchCall() pure returns (string[2] memory) {
return [
// --- BatchCallSystem ---
"batchCall((bytes32,bytes)[])",
"batchCallFrom((address,bytes32,bytes)[])"
];
}

/**
* @dev Function signatures for registration system
*/
function getFunctionSignaturesRegistration() pure returns (string[14] memory) {
return [
// --- ModuleInstallationSystem ---
"installModule(address,bytes)",
// --- StoreRegistrationSystem ---
"registerTable(bytes32,bytes32,bytes32,bytes32,string[],string[])",
"registerStoreHook(bytes32,address,uint8)",
"unregisterStoreHook(bytes32,address)",
// --- WorldRegistrationSystem ---
"registerNamespace(bytes32)",
"registerSystemHook(bytes32,address,uint8)",
"unregisterSystemHook(bytes32,address)",
"registerSystem(bytes32,address,bool)",
"registerFunctionSelector(bytes32,string)",
"registerRootFunctionSelector(bytes32,string,bytes4)",
"registerDelegation(address,bytes32,bytes)",
"unregisterDelegation(address)",
"registerNamespaceDelegation(bytes32,bytes32,bytes)",
"unregisterNamespaceDelegation(bytes32)"
];
}
72 changes: 72 additions & 0 deletions packages/world/test/InitSystems.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.24;

import { Test } from "forge-std/Test.sol";

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

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

import { LimitedCallContext } from "../src/modules/init/LimitedCallContext.sol";
import { getFunctionSignaturesAccessManagement, getFunctionSignaturesBalanceTransfer, getFunctionSignaturesBatchCall, getFunctionSignaturesRegistration } from "../src/modules/init/functionSignatures.sol";

import { ACCESS_MANAGEMENT_SYSTEM_ID, BALANCE_TRANSFER_SYSTEM_ID, BATCH_CALL_SYSTEM_ID, REGISTRATION_SYSTEM_ID } from "../src/modules/init/constants.sol";

import { Systems } from "../src/codegen/tables/Systems.sol";

contract LimitedCallContextTest is Test {
function setUp() public {
StoreSwitch.setStoreAddress(address(createWorld()));
}

function callSystem(ResourceId resourceId, string memory functionSignature) internal {
address system = Systems.getSystem(resourceId);

// Generate empty calldata of sufficient length (any additional bytes are ignored)
bytes memory callData = new bytes(1000);
// Copy the selector into the calldata
bytes memory selector = abi.encodeWithSignature(functionSignature);
for (uint256 i = 0; i < selector.length; i++) {
callData[i] = selector[i];
}

// In this low level call, the status boolean corresponds to whether we reverted with `UnauthorizedCallContext`
vm.expectRevert(abi.encodeWithSelector(LimitedCallContext.UnauthorizedCallContext.selector));
(bool success, ) = system.call(callData);

assertTrue(success);
}

function testAccessManagementSystem() public {
string[4] memory functionSignaturesAccessManagement = getFunctionSignaturesAccessManagement();

for (uint256 i; i < functionSignaturesAccessManagement.length; i++) {
callSystem(ACCESS_MANAGEMENT_SYSTEM_ID, functionSignaturesAccessManagement[i]);
}
}

function testBalanceTransferSystem() public {
string[2] memory functionSignaturesBalanceTransfer = getFunctionSignaturesBalanceTransfer();

for (uint256 i; i < functionSignaturesBalanceTransfer.length; i++) {
callSystem(BALANCE_TRANSFER_SYSTEM_ID, functionSignaturesBalanceTransfer[i]);
}
}

function testBatchCallSystem() public {
string[2] memory functionSignaturesBatchCall = getFunctionSignaturesBatchCall();

for (uint256 i; i < functionSignaturesBatchCall.length; i++) {
callSystem(BATCH_CALL_SYSTEM_ID, functionSignaturesBatchCall[i]);
}
}

function testRegistrationSystem() public {
string[14] memory functionSignaturesRegistration = getFunctionSignaturesRegistration();

for (uint256 i; i < functionSignaturesRegistration.length; i++) {
callSystem(REGISTRATION_SYSTEM_ID, functionSignaturesRegistration[i]);
}
}
}

0 comments on commit 2b65f13

Please sign in to comment.