From 18d3aea55b1d7f4b442c21343795c299a56fc481 Mon Sep 17 00:00:00 2001 From: alvarius Date: Thu, 7 Sep 2023 19:54:59 +0200 Subject: [PATCH] feat(world): allow callFrom from own address without explicit delegation (#1407) --- .changeset/silver-mangos-thank.md | 5 +++++ packages/world/gas-report.json | 6 +++--- packages/world/src/World.sol | 5 +++++ packages/world/test/World.t.sol | 21 +++++++++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 .changeset/silver-mangos-thank.md diff --git a/.changeset/silver-mangos-thank.md b/.changeset/silver-mangos-thank.md new file mode 100644 index 0000000000..aec6ac4051 --- /dev/null +++ b/.changeset/silver-mangos-thank.md @@ -0,0 +1,5 @@ +--- +"@latticexyz/world": patch +--- + +Allow `callFrom` with the own address as `delegator` without requiring an explicit delegation diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index b3e0438426..24a0aacd2c 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -237,7 +237,7 @@ "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "call a system via a callbound delegation", - "gasUsed": 44074 + "gasUsed": 44114 }, { "file": "test/StandardDelegationsModule.t.sol", @@ -249,7 +249,7 @@ "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "call a system via a timebound delegation", - "gasUsed": 34779 + "gasUsed": 34819 }, { "file": "test/UniqueEntityModule.t.sol", @@ -291,7 +291,7 @@ "file": "test/World.t.sol", "test": "testCallFromUnlimitedDelegation", "name": "call a system via an unlimited delegation", - "gasUsed": 17853 + "gasUsed": 17893 }, { "file": "test/World.t.sol", diff --git a/packages/world/src/World.sol b/packages/world/src/World.sol index fce2f6ad72..2e4f67ee2b 100644 --- a/packages/world/src/World.sol +++ b/packages/world/src/World.sol @@ -191,6 +191,11 @@ contract World is StoreRead, IStoreData, IWorldKernel { bytes32 resourceSelector, bytes memory funcSelectorAndArgs ) external payable virtual returns (bytes memory) { + // If the delegator is the caller, call the system directly + if (delegator == msg.sender) { + return SystemCall.callWithHooksOrRevert(msg.sender, resourceSelector, funcSelectorAndArgs, msg.value); + } + // Check if there is an explicit authorization for this caller to perform actions on behalf of the delegator Delegation explicitDelegation = Delegation.wrap(Delegations.get({ delegator: delegator, delegatee: msg.sender })); diff --git a/packages/world/test/World.t.sol b/packages/world/test/World.t.sol index 7efd9a9eb8..e03cdb2dab 100644 --- a/packages/world/test/World.t.sol +++ b/packages/world/test/World.t.sol @@ -664,6 +664,27 @@ contract WorldTest is Test, GasReporter { assertEq(returnedAddress, address(this), "subsystem returned wrong address"); } + function testCallFromSelf() public { + // Register a new system + WorldTestSystem system = new WorldTestSystem(); + bytes32 resourceSelector = ResourceSelector.from("namespace", "testSystem"); + world.registerSystem(resourceSelector, system, true); + + address caller = address(1); + + // Call a system via callFrom with the own address + vm.prank(caller); + bytes memory returnData = world.callFrom( + caller, + resourceSelector, + abi.encodeWithSelector(WorldTestSystem.msgSender.selector) + ); + address returnedAddress = abi.decode(returnData, (address)); + + // Expect the system to have received the delegator's address + assertEq(returnedAddress, caller); + } + function testCallFromUnlimitedDelegation() public { // Register a new system WorldTestSystem system = new WorldTestSystem();