Skip to content

Commit

Permalink
chore: install new view function on ep v0.6 (#23)
Browse files Browse the repository at this point in the history
## Summary
The tradeoff is installation gas cost vs convenient access to states
through MSCA itself. For more details, please refer to
[How to write an ERC-6900
Plugin](https://dev.collab.land/blog/how-to-write-an-erc-6900-plugin/#3-map-plugin-logic-to-msca-functions).
**Note**: this PR is on
[entry-point-v0.6](https://github.com/circlefin/buidl-wallet-contracts/tree/entry-point-v0.6).

## Detail
### Changeset
* install `getReplaySafeMessageHash` for both `SingleOwnerPlugin` and
`WeightedWebauthnMultisigPlugin` so they could be both called through
MSCA itself
* install `upgradeTo` (**OZ v4 only**) in
`WeightedWebauthnMultisigPlugin` so it has the feature parity with
`SingleOwnerPlugin`

### Checklist
- [x] Did you add new tests and confirm all tests pass? (`yarn test`)
- [ ] Did you update relevant docs? (docs are found in the `docs`
folder)
- [x] Do your commits follow the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard?
- [x] Does your PR title also follow the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) standard?
- [ ] If you have a breaking change, is it [correctly reflected in your
commit
message](https://www.conventionalcommits.org/en/v1.0.0/#examples)? (e.g.
`feat!: breaking change`)
- [x] Did you run lint (`yarn lint`) and fix any issues?
- [x] Did you run formatter (`yarn format:check`) and fix any issues
(`yarn format:write`)?

## Testing
* Updated the tests to reflect the installation 

## Documentation
n/a
  • Loading branch information
huaweigu authored Oct 15, 2024
1 parent ffa4585 commit f854da1
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 13 deletions.
5 changes: 5 additions & 0 deletions src/msca/6900/v0.7/account/UpgradableMSCA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ contract UpgradableMSCA is BaseMSCA, UUPSUpgradeable {
emit UpgradableMSCAInitialized(address(this), address(entryPoint));
}

/// @inheritdoc UUPSUpgradeable
function upgradeTo(address newImplementation) public override onlyProxy validateNativeFunction {
super.upgradeTo(newImplementation);
}

/// @inheritdoc UUPSUpgradeable
function upgradeToAndCall(address newImplementation, bytes memory data)
public
Expand Down
3 changes: 2 additions & 1 deletion src/msca/6900/v0.7/libs/SelectorRegistryLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ library SelectorRegistryLib {
function _isNativeFunctionSelector(bytes4 selector) internal pure returns (bool) {
return selector == IStandardExecutor.execute.selector || selector == IStandardExecutor.executeBatch.selector
|| selector == IPluginManager.installPlugin.selector || selector == IPluginManager.uninstallPlugin.selector
|| selector == UUPSUpgradeable.upgradeToAndCall.selector || selector == UUPSUpgradeable.proxiableUUID.selector
|| selector == UUPSUpgradeable.upgradeTo.selector || selector == UUPSUpgradeable.upgradeToAndCall.selector
|| selector == UUPSUpgradeable.proxiableUUID.selector
// check against IERC165 methods
|| selector == IERC165.supportsInterface.selector
// check against IPluginExecutor methods
Expand Down
7 changes: 5 additions & 2 deletions src/msca/6900/v0.7/plugins/v1_0_0/acl/SingleOwnerPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,12 @@ contract SingleOwnerPlugin is BasePlugin, ISingleOwnerPlugin, IERC1271, BaseERC7
/// @inheritdoc BasePlugin
function pluginManifest() external pure override returns (PluginManifest memory) {
PluginManifest memory manifest;
manifest.executionFunctions = new bytes4[](4);
manifest.executionFunctions = new bytes4[](5);
manifest.executionFunctions[0] = this.transferOwnership.selector;
manifest.executionFunctions[1] = this.getOwner.selector;
manifest.executionFunctions[2] = this.getOwnerOf.selector;
manifest.executionFunctions[3] = this.isValidSignature.selector;
manifest.executionFunctions[4] = this.getReplaySafeMessageHash.selector;

ManifestFunction memory userOpValidationAssociatedFunction =
ManifestFunction(ManifestAssociatedFunctionType.SELF, uint8(FunctionId.USER_OP_VALIDATION_OWNER), 0);
Expand Down Expand Up @@ -177,7 +178,7 @@ contract SingleOwnerPlugin is BasePlugin, ISingleOwnerPlugin, IERC1271, BaseERC7
ManifestFunction memory runtimeAlwaysAllowAssociatedFunction =
ManifestFunction(ManifestAssociatedFunctionType.RUNTIME_VALIDATION_ALWAYS_ALLOW, 0, 0);
// the following direct function calls (from EOA/SC) should be gated by the runtimeValidationAssociatedFunction
manifest.runtimeValidationFunctions = new ManifestAssociatedFunction[](10);
manifest.runtimeValidationFunctions = new ManifestAssociatedFunction[](11);
// plugin functions
manifest.runtimeValidationFunctions[0] =
ManifestAssociatedFunction(this.transferOwnership.selector, runtimeValidationAssociatedFunction);
Expand All @@ -201,6 +202,8 @@ contract SingleOwnerPlugin is BasePlugin, ISingleOwnerPlugin, IERC1271, BaseERC7
ManifestAssociatedFunction(this.getOwnerOf.selector, runtimeAlwaysAllowAssociatedFunction);
manifest.runtimeValidationFunctions[9] =
ManifestAssociatedFunction(this.isValidSignature.selector, runtimeAlwaysAllowAssociatedFunction);
manifest.runtimeValidationFunctions[10] =
ManifestAssociatedFunction(this.getReplaySafeMessageHash.selector, runtimeAlwaysAllowAssociatedFunction);
manifest.interfaceIds = new bytes4[](2);
manifest.interfaceIds[0] = type(IERC1271).interfaceId;
manifest.interfaceIds[1] = type(ISingleOwnerPlugin).interfaceId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,12 @@ contract WeightedWebauthnMultisigPlugin is BaseWeightedMultisigPlugin, BaseERC71
function pluginManifest() external pure virtual override returns (PluginManifest memory) {
PluginManifest memory manifest;

manifest.executionFunctions = new bytes4[](4);
manifest.executionFunctions = new bytes4[](5);
manifest.executionFunctions[0] = this.addOwners.selector;
manifest.executionFunctions[1] = this.removeOwners.selector;
manifest.executionFunctions[2] = this.updateMultisigWeights.selector;
manifest.executionFunctions[3] = this.isValidSignature.selector;
manifest.executionFunctions[4] = this.getReplaySafeMessageHash.selector;

ManifestFunction memory ownerUserOpValidationFunction = ManifestFunction({
functionType: ManifestAssociatedFunctionType.SELF,
Expand All @@ -171,9 +172,9 @@ contract WeightedWebauthnMultisigPlugin is BaseWeightedMultisigPlugin, BaseERC71
});

// Update native functions to use userOpValidationFunction provided by this plugin
// The view functions `isValidSignature` and `eip712Domain` are excluded from being assigned a user
// The view functions `isValidSignature` and `getReplaySafeMessageHash` are excluded from being assigned a user
// operation validation function since they should only be called via the runtime path.
manifest.userOpValidationFunctions = new ManifestAssociatedFunction[](8);
manifest.userOpValidationFunctions = new ManifestAssociatedFunction[](9);
manifest.userOpValidationFunctions[0] = ManifestAssociatedFunction({
executionSelector: this.addOwners.selector,
associatedFunction: ownerUserOpValidationFunction
Expand Down Expand Up @@ -210,6 +211,10 @@ contract WeightedWebauthnMultisigPlugin is BaseWeightedMultisigPlugin, BaseERC71
executionSelector: UUPSUpgradeable.upgradeToAndCall.selector,
associatedFunction: ownerUserOpValidationFunction
});
manifest.userOpValidationFunctions[8] = ManifestAssociatedFunction({
executionSelector: UUPSUpgradeable.upgradeTo.selector,
associatedFunction: ownerUserOpValidationFunction
});

ManifestFunction memory alwaysAllowFunction = ManifestFunction({
functionType: ManifestAssociatedFunctionType.RUNTIME_VALIDATION_ALWAYS_ALLOW,
Expand All @@ -222,7 +227,7 @@ contract WeightedWebauthnMultisigPlugin is BaseWeightedMultisigPlugin, BaseERC71
functionId: 0,
dependencyIndex: 0 // Unused.
});
manifest.runtimeValidationFunctions = new ManifestAssociatedFunction[](10);
manifest.runtimeValidationFunctions = new ManifestAssociatedFunction[](11);

manifest.runtimeValidationFunctions[0] = ManifestAssociatedFunction({
executionSelector: this.isValidSignature.selector,
Expand Down Expand Up @@ -264,6 +269,10 @@ contract WeightedWebauthnMultisigPlugin is BaseWeightedMultisigPlugin, BaseERC71
executionSelector: UUPSUpgradeable.upgradeToAndCall.selector,
associatedFunction: alwaysRevertFunction
});
manifest.runtimeValidationFunctions[10] = ManifestAssociatedFunction({
executionSelector: UUPSUpgradeable.upgradeTo.selector,
associatedFunction: alwaysRevertFunction
});

return manifest;
}
Expand Down
5 changes: 5 additions & 0 deletions test/msca/6900/v0.7/SingleOwnerPlugin.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,11 @@ contract SingleOwnerPluginTest is TestUtils {

// verify supportedInterfaces
assertEq(bytes32(msca1.getSupportedInterface(type(IERC1271).interfaceId)), bytes32(uint256(1)));

executionDetail = msca1.getExecutionDetail(singleOwnerPlugin.getReplaySafeMessageHash.selector);
assertEq(executionDetail.plugin, singleOwnerPluginAddr);
assertEq(executionDetail.userOpValidationFunction.pack(), EMPTY_FUNCTION_REFERENCE);
assertEq(executionDetail.runtimeValidationFunction.pack(), RUNTIME_VALIDATION_ALWAYS_ALLOW_FUNCTION_REFERENCE);
}

function testTransferOwnership() public {
Expand Down
13 changes: 7 additions & 6 deletions test/msca/6900/v0.7/plugins/WeightedWebauthnMultisigPlugin.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -270,14 +270,15 @@ contract WeightedWebauthnMultisigPluginTest is TestUtils {

function test_pluginManifest() public {
PluginManifest memory manifest = plugin.pluginManifest();
// 4 execution functions (addOwners, removeOwners, updateMultisigWeights, isValidSignature)
assertEq(4, manifest.executionFunctions.length);
// 4 execution functions (addOwners, removeOwners, updateMultisigWeights, isValidSignature,
// getReplaySafeMessageHash)
assertEq(5, manifest.executionFunctions.length);

// 7 native + 1 plugin exec func
assertEq(8, manifest.userOpValidationFunctions.length);
// 8 native + 1 plugin exec func
assertEq(9, manifest.userOpValidationFunctions.length);

// 10 runtime validations (isValidSignature, eip712Domain, 8 disabled functions)
assertEq(10, manifest.runtimeValidationFunctions.length);
// 11 runtime validations (isValidSignature, getReplaySafeMessageHash, 9 disabled functions)
assertEq(11, manifest.runtimeValidationFunctions.length);
}

function test_pluginMetadata() public {
Expand Down

0 comments on commit f854da1

Please sign in to comment.