Skip to content

Commit f29b2f0

Browse files
GarmashAlexAmxxernestognw
authored
Prevent revert in isModuleInstalled for fallback modules on short additionalContext (#5961)
Co-authored-by: Hadrien Croubois <[email protected]> Co-authored-by: ernestognw <[email protected]>
1 parent 5eb047a commit f29b2f0

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
### Bug fixes
44

55
- `ERC165Checker`: Ensure the `supportsERC165` function returns false if the target reverts during the `supportsInterface(0xffffffff)` call. ([#5810](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5880))
6+
- `AccountERC7579`: Prevent revert in `isModuleInstalled` for fallback modules when `additionalContext` has fewer than 4 bytes. The function now returns `false` instead of reverting, ensuring ERC-7579 compliance. ([#5961](https://github.com/OpenZeppelin/openzeppelin-contracts/pull/5961))
67

78
### Breaking changes
89

contracts/account/extensions/draft-AccountERC7579.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ abstract contract AccountERC7579 is Account, IERC1271, IERC7579Execution, IERC75
149149
) public view virtual returns (bool) {
150150
if (moduleTypeId == MODULE_TYPE_VALIDATOR) return _validators.contains(module);
151151
if (moduleTypeId == MODULE_TYPE_EXECUTOR) return _executors.contains(module);
152-
if (moduleTypeId == MODULE_TYPE_FALLBACK) return _fallbacks[bytes4(additionalContext[0:4])] == module;
152+
if (moduleTypeId == MODULE_TYPE_FALLBACK)
153+
// ERC-7579 requires this function to return bool, never revert. Check length to avoid out-of-bounds access.
154+
return additionalContext.length > 3 && _fallbacks[bytes4(additionalContext[0:4])] == module;
153155
return false;
154156
}
155157

test/account/extensions/AccountERC7579.behavior.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,22 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) {
9191
});
9292
});
9393

94+
describe('isModuleInstalled', function () {
95+
it('should not revert if calldata is empty or too short', async function () {
96+
await expect(
97+
this.mock.isModuleInstalled(MODULE_TYPE_FALLBACK, this.modules[MODULE_TYPE_FALLBACK], '0x'),
98+
).to.eventually.equal(false);
99+
100+
await expect(
101+
this.mock.isModuleInstalled(MODULE_TYPE_FALLBACK, this.modules[MODULE_TYPE_FALLBACK], '0x123456'),
102+
).to.eventually.equal(false);
103+
104+
await expect(
105+
this.mock.isModuleInstalled(MODULE_TYPE_FALLBACK, this.modules[MODULE_TYPE_FALLBACK], '0x12345678'),
106+
).to.eventually.equal(false);
107+
});
108+
});
109+
94110
describe('module installation', function () {
95111
it('should revert if the caller is not the canonical entrypoint or the account itself', async function () {
96112
await expect(this.mock.connect(this.other).installModule(MODULE_TYPE_VALIDATOR, this.mock, '0x'))

0 commit comments

Comments
 (0)