8000 Allow Safe to Own Itself by nlordell · Pull Request #998 · safe-global/safe-smart-account · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Allow Safe to Own Itself #998

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Allow Safe to Own Itself #998

wants to merge 3 commits into from

Conversation

nlordell
Copy link
Collaborator
@nlordell nlordell 8000 commented Jun 20, 2025

This change was originally proposed by @akshay-ap

This PR reverts an old change (See #229 and #259) and allows the Safe to once again own itself. This is a step towards 7702 support (#997), whereby we want the EOA that delegates to a Safe to be able to sign transactions for itself.

The restriction was originally put in place because execTransaction would call isValidSignature on itself (which used to be implemented on the Safe itself and not as part of the compatibility fallback handler), where the msg.sender would be the Safe itself, and allow for trivial "approved hash" signatures (through
this mechanism).

This is no longer possible since v1.3.0, as the isValidSignature call would be handled by the fallback handler, meaning that the msg.sender that can trivially sign "approve hash" signatures is no longer the Safe itself but the configured fallback handler. Since #866 and starting in v1.5.0 the CompatibilityFallbackHandler is implemented to disallow "approve hash" signatures regardless of the caller, further eliminating the requirement for the restriction.

Increasing Threshold Concerns

One concern with this change, and removing the restriction on having the Safe own itself, is that the Safe cannot sign for itself, so you can potentially block access to the account completely, by requiring the Safe "self-owner" to be included as part of the signing threshold. For example, if you have a n/n Safe (so threshold == ownerCount) and one of the owners is the Safe itself, then the Safe will not be able to ever produce a valid signature.

This PR reverts an old change (See #229 and #259) and allows the Safe
to once again own itself. This is a step towards 7702 support, whereby
we want the EOA that delegates to a Safe to be able to sign
transactions for itself.

The restriction was originally put in place because `execTransaction`
would call `isValidSignature` (which used to be implemented on the
Safe itself and not as part of the compatibility fallback handler) on
itself, where the `msg.sender` would be the Safe itself, and allow for
trivial "approved hash" signatures (through
[this](https://github.com/safe-global/safe-smart-account/blob/36db12a140331c522e773849ebc87d39f5abae1e/contracts/GnosisSafe.sol#L244-L245)
mechanism).

This is no longer possible since v1.3.0, as the `isValidSignature`
call would be handled by the fallback handler, meaning that the
`msg.sender` that can trivially sign "approve hash" signatures is no
longer the Safe itself but the configured fallback handler. Since #866
and starting in v1.5.0 the `CompatibilityFallbackHandler` is
implemented to disallow "approve hash" signatures regardless of the
caller, further eliminating the requirement for the restriction.

 ### Increasing Threshold Concerns

One concern with this change, and removing the restriction on having
the Safe own itself, is that the Safe cannot sign for itself, so you
can potentially block access to the account completely, by requiring
the Safe "self-owner" to be included as part of the signing threshold.
For example, if you have a n/n Safe (so `threshold == ownerCount` and
one of the owners is the Safe itself, then the Safe will not be able
to ever produce a valid signature).
@nlordell nlordell requested a review from a team as a code owner June 20, 2025 12:09
@nlordell nlordell requested review from rmeissner, akshay-ap, mmv08 and remedcu and removed request for a team June 20, 2025 12:09
@@ -165,7 +154,7 @@ describe("Safe", () => {
} = await setupTests();
await expect(
template.setup([user2.address, user2.address], 2, AddressZero, "0x", AddressZero, AddressZero, 0, AddressZero),
).to.be.revertedWith("GS203");
).to.be.revertedWith("GS204");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error duplicate owner is now consistently "GS204".

} as const;
const signatures = buildSignatureBytes([selfSignature]);

await expect(safe["checkSignatures(address,bytes32,bytes)"](user1.address, txHash, signatures)).to.be.revertedWith("GS025");
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that if we change the CompatibilityFallbackHandler to not use address(0) as the executor, then this test would fail:

diff --git a/contracts/handler/CompatibilityFallbackHandler.sol b/contracts/handler/CompatibilityFallbackHandler.sol
index 275797d..e652ad0 100644
--- a/contracts/handler/CompatibilityFallbackHandler.sol
+++ b/contracts/handler/CompatibilityFallbackHandler.sol
@@ -80,7 +80,7 @@ contract CompatibilityFallbackHandler is TokenCallbackHandler, ISignatureValidat
         } else {
             // We explicitly do not allow caller approved signatures for EIP-1271 to prevent unexpected behaviour. This
             // is done by setting the executor address to `0` which can never be an owner of the Safe.
-            safe.checkSignatures(address(0), messageHash, _signature);
+            safe.checkSignatures(msg.sender, messageHash, _signature);
         }
         return EIP1271_MAGIC_VALUE;
     }
  1) Safe
       checkSignatures
         should not allow trivial signatures when the Safe owns itself:
     AssertionError: Expected transaction to be reverted with reason 'GS025', but it didn't revert
      at async Context.<anonymous> (test/core/Safe.Signatures.spec.ts:511:13)

@nlordell
Copy link
Collaborator Author

Tagging with do not merge as I want this to be applied after the Safe v1.5.0 release.

@nlordell nlordell mentioned this pull request Jun 20, 2025
1 task
It is no longer true, and is allowed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant
0