Skip to content
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

📝 Add Natspec comments for clarity #146

Merged
merged 7 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions contracts/smart-account/base/Executor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ import {Enum} from "../common/Enum.sol";

/// @title Executor - A contract that can execute transactions
abstract contract Executor is IExecutor {
/**
* @notice Executes a given operation (either Call or DelegateCall) to a specified address with provided data.
* @param to The address to which the operation should be executed.
* @param value The amount of ether (in wei) to send with the call (only for Call operations).
* @param data The call data to send with the operation.
* @param operation The type of operation to execute (either Call or DelegateCall).
* @param txGas The amount of gas to use for the operation.
* @return success A boolean indicating whether the operation was successful.
*/
function _execute(
address to,
uint256 value,
Expand Down
9 changes: 5 additions & 4 deletions contracts/smart-account/base/FallbackManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,17 @@ abstract contract FallbackManager is SelfAuthorized, IFallbackManager {
}
}

/**
* @notice Sets a new fallback handler. This function will revert if the provided handler address is zero.
* @dev This function is internal and utilizes assembly for optimized storage operations.
* @param handler The address of the new fallback handler.
*/
function _setFallbackHandler(address handler) internal {
if (handler == address(0)) revert HandlerCannotBeZero();
address previousHandler;

assembly {
previousHandler := sload(FALLBACK_HANDLER_STORAGE_SLOT)
//}
//bytes32 slot = FALLBACK_HANDLER_STORAGE_SLOT;

//assembly {
sstore(FALLBACK_HANDLER_STORAGE_SLOT, handler)
}
emit ChangedFallbackHandler(previousHandler, handler);
Expand Down
18 changes: 16 additions & 2 deletions contracts/smart-account/base/ModuleManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,14 @@ abstract contract ModuleManager is SelfAuthorized, Executor, IModuleManager {
emit DisabledModule(module);
}

// TODO: can use not executor.execute, but SmartAccount._call for the unification

/**
* @notice Executes an operation from a module, emits specific events based on the result.
* @param to The address to which the operation should be executed.
* @param value The amount of ether (in wei) to send with the call (only for Call operations).
* @param data The call data to send with the operation.
* @param operation The type of operation to execute (either Call or DelegateCall).
* @return success A boolean indicating whether the operation was successful.
*/
function _executeFromModule(
address to,
uint256 value,
Expand Down Expand Up @@ -259,6 +265,14 @@ abstract contract ModuleManager is SelfAuthorized, Executor, IModuleManager {
return initialAuthorizationModule;
}

/**
* @notice Sets up a new module by calling a specified setup contract with provided data.
* The function will revert if the setupContract address is zero or if the setup call fails.
* @dev This function is internal and utilizes assembly for low-level call operations and error handling.
* @param setupContract The address of the contract that will be called to set up the module.
* @param setupData The call data to send to the setup contract.
* @return module The address of the newly set up module.
*/
function _setupModule(
address setupContract,
bytes memory setupData
Expand Down
18 changes: 17 additions & 1 deletion contracts/smart-account/common/ReentrancyGuard.sol
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity 0.8.17;

/// @title Reentrancy Guard - reentrancy protection
/**
* @title ReentrancyGuard
* @notice Provides a contract-level guard against reentrancy attacks.
* @dev Uses a single contract-wide status flag for efficiency.
* Use the `nonReentrant` modifier on functions to protect them.
*/
abstract contract ReentrancyGuard {
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;

uint256 private _reentrancyStatus;

/// @notice Custom error to denote that reentrancy protection has been activated.
error ReentrancyProtectionActivated();

/**
* @notice Modifier to prevent a contract from calling itself, directly or indirectly.
* @dev Checks if the function has been re-entered, and if so, reverts with a custom error.
*/
modifier nonReentrant() {
if (_reentrancyStatus == ENTERED)
revert ReentrancyProtectionActivated();
Expand All @@ -18,10 +28,16 @@ abstract contract ReentrancyGuard {
_reentrancyStatus = NOT_ENTERED;
}

/// @notice Initializes the `ReentrancyGuard` contract, setting the reentrancy status to `NOT_ENTERED`.
constructor() {
_reentrancyStatus = NOT_ENTERED;
}

/**
* @notice Checks if the reentrancy guard is currently activated.
* @dev Returns true if the guard is activated, false otherwise.
* @return A boolean indicating whether the reentrancy guard is activated.
*/
function _isReentrancyGuardEntered() internal view returns (bool) {
return _reentrancyStatus == ENTERED;
}
Expand Down
15 changes: 10 additions & 5 deletions contracts/smart-account/common/SecuredTokenTransfer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ pragma solidity 0.8.17;

/// @title SecuredTokenTransfer - Secure token transfer
abstract contract SecuredTokenTransfer {
/// @dev Transfers a token and returns if it was a success
/// @param token Token that should be transferred
/// @param receiver Receiver to whom the token should be transferred
/// @param amount The amount of tokens that should be transferred
/**
* @dev Transfers a specified amount of ERC20 tokens to a receiver.
* @notice This function utilizes the standard `transfer` function of ERC20 tokens.
* It ensures the token address is valid and that the token contract exists before attempting the transfer.
* @param token The address of the ERC20 token to be transferred.
* @param receiver The address to receive the tokens.
* @param amount The amount of tokens to transfer.
* @return transferred A boolean indicating whether the transfer was successful.
*/
function _transferToken(
address token,
address receiver,
Expand All @@ -23,7 +28,7 @@ abstract contract SecuredTokenTransfer {

assembly {
// We write the return value to scratch space.
// See https://docs.soliditylang.org/en/v0.8.17/internals/layout_in_memory.html#layout-in-memory
// See https://docs.soliditylang.org/en/latest/internals/layout_in_memory.html#layout-in-memory
let success := call(
sub(gas(), 10000),
token,
Expand Down
16 changes: 14 additions & 2 deletions contracts/smart-account/common/SelfAuthorized.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,26 @@ pragma solidity 0.8.17;

import {ISelfAuthorized} from "../interfaces/common/ISelfAuthorized.sol";

/// @title SelfAuthorized - authorizes current contract to perform actions
/**
* @title SelfAuthorized
* @notice This contract provides a modifier to ensure that only the contract itself can call certain functions.
* @dev Functions with the `authorized` modifier can only be called by the contract itself.
* This can be useful for security purposes or to ensure a specific call flow.
*/
contract SelfAuthorized is ISelfAuthorized {
/**
* @notice Modifier to ensure a function is only callable by the contract itself.
* @dev Checks if the caller is the current contract. If not, reverts.
*/
modifier authorized() {
// This is a function call as it minimized the bytecode size
_requireSelfCall();
_;
}

/**
* @dev Internal function to check if the caller is the current contract.
* @dev If the caller isn't the contract, it reverts with a specific error.
*/
function _requireSelfCall() private view {
if (msg.sender != address(this)) revert CallerIsNotSelf(msg.sender);
}
Expand Down
12 changes: 10 additions & 2 deletions contracts/smart-account/common/SignatureDecoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@ pragma solidity 0.8.17;

/// @title SignatureDecoder - Decodes signatures that a encoded as bytes
abstract contract SignatureDecoder {
/// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`.
/// @param signature concatenated rsv signatures
/**
* @dev Splits a given signature into its `r`, `s`, and `v` components.
* @notice The signature is assumed to be in the compact format:
* r (32 bytes) + s (32 bytes) + v (1 byte).
* This function uses assembly for efficient memory operations.
* @param signature The signature bytes.
* @return v The `v` component of the signature.
* @return r The `r` component of the signature as bytes32.
* @return s The `s` component of the signature as bytes32.
*/
function _signatureSplit(
bytes memory signature
) internal pure returns (uint8 v, bytes32 r, bytes32 s) {
Expand Down
17 changes: 17 additions & 0 deletions contracts/smart-account/common/Stakeable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ contract Stakeable is Ownable, IStakeable {
_transferOwnership(_newOwner);
}

/**
* @dev Stakes a certain amount of Ether on an EntryPoint.
* @notice The contract should have enough Ether to cover the stake.
* @param epAddress Address of the EntryPoint where the stake is added.
* @param unstakeDelaySec The delay in seconds before the stake can be unlocked.
*/
function addStake(
address epAddress,
uint32 unstakeDelaySec
Expand All @@ -22,11 +28,22 @@ contract Stakeable is Ownable, IStakeable {
IEntryPoint(epAddress).addStake{value: msg.value}(unstakeDelaySec);
}

/**
* @dev Unlocks the stake on an EntryPoint.
* @notice This starts the unstaking delay after which funds can be withdrawn.
* @param epAddress Address of the EntryPoint where the stake is unlocked.
*/
function unlockStake(address epAddress) external override onlyOwner {
require(epAddress != address(0), "Invalid EP address");
IEntryPoint(epAddress).unlockStake();
}

/**
* @dev Withdraws the stake from an EntryPoint to a specified address.
* @notice This can only be done after the unstaking delay has passed since the unlock.
* @param epAddress Address of the EntryPoint where the stake is withdrawn from.
* @param withdrawAddress Address to receive the withdrawn stake.
*/
function withdrawStake(
address epAddress,
address payable withdrawAddress
Expand Down
13 changes: 9 additions & 4 deletions contracts/smart-account/deployer/Create3.sol
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ library Create3 {
if (!success || codeSize(addr) == 0) revert ErrorCreatingContract();
}

/**
* @dev Computes the CREATE2 proxy address using the provided salt.
* @param _salt The salt used to derive the proxy contract address.
* @return Address of the proxy contract derived using CREATE2.
*/
function addressOfProxy(bytes32 _salt) internal view returns (address) {
return
address(
Expand Down Expand Up @@ -129,10 +134,10 @@ library Create3 {
}

/**
@notice Returns the size of the code on a given address
@param _addr Address that may or may not contain code
@return size of the code on the given `_addr`
*/
* @dev Returns the size of the code stored at a specific address.
* @param _addr The address to check.
* @return size The size of the code stored at the given address.
*/
function codeSize(address _addr) internal view returns (uint256 size) {
assembly {
size := extcodesize(_addr)
Expand Down
10 changes: 10 additions & 0 deletions contracts/smart-account/deployer/Deployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,21 @@ import "./Create3.sol";
contract Deployer {
event ContractDeployed(address indexed contractAddress);

/**
* @dev Deploys a new contract using the Create3 library with a specific salt and initialization code.
* @param _salt The salt used to derive the deployed contract address.
* @param _creationCode The bytecode used to initialize and deploy the contract.
*/
function deploy(bytes32 _salt, bytes calldata _creationCode) external {
address deployedContract = Create3.create3(_salt, _creationCode);
emit ContractDeployed(deployedContract);
}

/**
* @dev Computes the final deployed address using the Create3 library and a given salt.
* @param _salt The salt used in the original Create3 deployment.
* @return Address of the final deployed contract.
*/
function addressOf(bytes32 _salt) external view returns (address) {
return Create3.addressOf(_salt);
}
Expand Down
21 changes: 21 additions & 0 deletions contracts/smart-account/handler/DefaultCallbackHandler.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ contract DefaultCallbackHandler is
string public constant NAME = "Default Callback Handler";
string public constant VERSION = "1.0.0";

/**
* @dev Checks if the contract supports a given interface.
* @param interfaceId The interface identifier, as specified in ERC-165.
* @return True if the contract implements the given interface, false otherwise.
*/
function supportsInterface(
bytes4 interfaceId
) external view virtual override returns (bool) {
Expand All @@ -31,6 +36,10 @@ contract DefaultCallbackHandler is
interfaceId == type(IERC165).interfaceId;
}

/**
* @dev Handles the receipt of a single ERC1155 token type.
* @return The interface selector for the called function.
*/
function onERC1155Received(
address,
address,
Expand All @@ -41,6 +50,10 @@ contract DefaultCallbackHandler is
return IERC1155Receiver.onERC1155Received.selector;
}

/**
* @dev Handles the receipt of multiple ERC1155 token types.
* @return The interface selector for the called function.
*/
function onERC1155BatchReceived(
address,
address,
Expand All @@ -51,6 +64,10 @@ contract DefaultCallbackHandler is
return IERC1155Receiver.onERC1155BatchReceived.selector;
}

/**
* @dev Handles the receipt of an ERC721 token.
* @return The interface selector for the called function.
*/
function onERC721Received(
address,
address,
Expand All @@ -60,6 +77,10 @@ contract DefaultCallbackHandler is
return IERC721Receiver.onERC721Received.selector;
}

/**
* @dev Handles the receipt of an ERC777 token.
* This function does not have any specific logic as it's implemented for completeness.
*/
function tokensReceived(
address,
address,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

/// @dev Contract containing constants related to authorization module results.
contract AuthorizationModulesConstants {
uint256 internal constant VALIDATION_SUCCESS = 0;
uint256 internal constant SIG_VALIDATION_FAILED = 1;
}
11 changes: 5 additions & 6 deletions contracts/smart-account/modules/BaseAuthorizationModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ pragma solidity 0.8.17;
/* solhint-disable no-empty-blocks */

import {IBaseAuthorizationModule} from "../interfaces/modules/IBaseAuthorizationModule.sol";
import {AuthorizationModulesConstants} from "./AuthorizationModulesConstants.sol";

contract AuthorizationModulesConstants {
uint256 internal constant VALIDATION_SUCCESS = 0;
uint256 internal constant SIG_VALIDATION_FAILED = 1;
}

/// @dev Base contract for authorization modules
abstract contract BaseAuthorizationModule is
IBaseAuthorizationModule,
AuthorizationModulesConstants
{}
{

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

/* solhint-disable function-max-lines,no-unused-import */
/* solhint-disable function-max-lines */

import {BaseAuthorizationModule} from "./BaseAuthorizationModule.sol";
import {ISessionValidationModule} from "../interfaces/modules/ISessionValidationModule.sol";
Expand All @@ -11,7 +11,7 @@ import {_packValidationData} from "@account-abstraction/contracts/core/Helpers.s
import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol";
import {IBatchedSessionRouterModule} from "../interfaces/modules/IBatchedSessionRouterModule.sol";
import {IAuthorizationModule} from "../interfaces/IAuthorizationModule.sol";
import {ISignatureValidator} from "../interfaces/ISignatureValidator.sol";


/**
* @title Batched Session Router
Expand Down Expand Up @@ -130,7 +130,6 @@ contract BatchedSessionRouter is
}

/**
* @inheritdoc ISignatureValidator
* @dev isValidSignature according to BaseAuthorizationModule
* @param _dataHash Hash of the data to be validated.
* @param _signature Signature over the the _dataHash.
Expand Down
Loading
Loading