# Please feel free to reach out with any contract design feedback We are working on the first version of soulwallet after the hackathon version. We would appreciate your feedback on contract design. Contract draft source-code: [SoulWallet.sol](https://github.com/proofofsoulprotocol/soul-wallet-contract/blob/73405dfd6b979b176dc13d1b08e7b274b23a3790/contracts/SoulWallet.sol) We are grateful to ERC-6900 for providing us with some inspiration, and we have also borrowed some implementations from Safe. In general, the current draft of soulwallet supports modules and plugins. A module is an external contract, while a plugin is a contract that implements the interfaces described in [IPlugin.sol](https://github.com/proofofsoulprotocol/soul-wallet-contract/blob/73405dfd6b979b176dc13d1b08e7b274b23a3790/contracts/interfaces/IPlugin.sol). ```solidity interface IPlugin is IPluggable { /** * @dev * hookType structure: * 0b1: GuardHook * 0b10: PreHook * 0b100: PostHook * * callType structure: * 0: call * 1: delegatecall * ... */ function supportsHook() external pure returns (uint8 hookType, uint8 callType); /** * @dev For flexibility, guardData does not participate in the userOp signature verification. * Plugins must revert when they do not need guardData but guardData.length > 0(for security reasons) */ function guardHook(UserOperation calldata userOp, bytes32 userOpHash, bytes calldata guardData) external; function preHook(address target, uint256 value, bytes calldata data) external; function postHook(address target, uint256 value, bytes calldata data) external; } ``` 1. supportsHook defines a list of hooks supported by a plugin and also declares whether it is a delegatecall type of plugin. - Why do we need `delegatecall`? - Due to the limitations of address-associated storage, in many cases, to implement guardHook (executed in validateUserOp), delegatecall must be allowed. This is because requiring the plugin to store data in address-associated storage with a custom structure would increase complexity, and some plugins that need to store a large amount of data (>128 bytes32) would not be feasible. - To ensure the safety of delegatecall, the soulwallet frontend simulates each transaction before sending it to ensure that some key storage slots (such as owner) are not unintentionally modified. - Why do we need `bytes calldata guardData`? - During the execution of guardHook, a plugin may require additional data, such as [Simple2FA.sol](https://github.com/proofofsoulprotocol/soul-wallet-contract/blob/73405dfd6b979b176dc13d1b08e7b274b23a3790/contracts/plugin/Simple2FA/Simple2FA.sol). This data can only be passed through userOp.signature. To avoid conflicts when different plugins parse guardData, soulwallet must parse guardData and pass it to the respective plugin based on its needs. - Why doesn't guardHook have any return value? - Yes, in common hooks, we can change the entire application's execution logic. For example, in guardHook, we can perform validations from validateUserOp and directly return a uint256 to the entrypoint, skip the original validateUserOp validation. However, this would mean dynamically modifying the signature logic of the soulwallet frontend. Frankly, coordinating different plugins with the soulwallet frontend is `a big challenge`. Therefore, we have decided that the signature logic cannot be changed in a fixed version of soulwallet. Any additional functionality of plugins and modules should be implemented through separate DApps (which can be upgraded by updating the contract). In the future, we may introduce Domain Specific Language (DSL) in the frontend to dynamically generate UI and modify execution logic, but this is a significant challenge. 2. About Security: - We want users to have permanent ownership of specific AA accounts (through social recovery). - Enabling new modules and plugins introduces additional risks, such as rendering social recovery unavailable. - Users need to wait for a secure time period (e.g., 48 hours) when enabling modules or plugins. This ensures that even if a hacker steals your account, they cannot immediately render social recovery unavailable. During this time, users can regain control through social recovery. - Users need to wait for a secure time period (e.g., 48 hours) when disabling modules or plugins. Some modules or plugins may be used to secure your account, such as [Dailylimit Plugin](https://github.com/proofofsoulprotocol/soul-wallet-contract/blob/73405dfd6b979b176dc13d1b08e7b274b23a3790/contracts/plugin/Dailylimit/Dailylimit.sol) or [SocialRecovery Module](https://github.com/proofofsoulprotocol/soul-wallet-contract/blob/73405dfd6b979b176dc13d1b08e7b274b23a3790/contracts/modules/SocialRecoveryModule/SocialRecoveryModule.sol). Removing these requires a 48-hour waiting period to prevent hackers from immediately removing components that secure your wallet. - Of course, users can choose to trust the [soulwallet whitelist](https://github.com/proofofsoulprotocol/soul-wallet-contract/blob/73405dfd6b979b176dc13d1b08e7b274b23a3790/contracts/trustedContractManager/TrustedContractManager.sol), which means they can add some plugins or modules without waiting (however, when removing them, even if they are in the whitelist, a 48-hour waiting period is required). - Storage Security: - Transactions sent through soulwallet must simulation first to ensure that they do not inadvertently modify some key storage (such as owner data). This helps mitigate risks caused by unaudited bugs in plugins or modules.