# OffBlocksSmartWallet.sol

### Contract Overview

#### Inherits:

* `ReentrancyGuard` & `Ownable` from OpenZeppelin
* Also imports `IOffBlocksEscrow`, `IOffBlocksSmartWallet` & `IOffBlocksSmartWalletFactory` interfaces and  `IERC20` &`ECDSA` from OpenZeppelin which is used in the contract
* PendingWithdrawal

**Author:** OffBlocks Team

**Description**: The `OffBlocksSmartWallet` is designed for EVM chains supporting ERC-4337. It interacts with an escrow contract to facilitate token approvals and deposits, supports nonce-based operations for security, and manages withdrawals through an internal `PendingWithdrawal` contract module.

### Constructor

```solidity
constructor(address _owner, address _escrow, address _smartWalletFactory);
```

* **Inputs**:
  * `_owner`: The owner of the smart wallet.
  * `_escrow`: Address of the OffBlocks escrow contract.
  * `_smartWalletFactory`: Address of the OffBlocks smart wallet factory.
* **Outputs**: None.
* **Description**: Initializes a new `OffBlocksSmartWallet` with the specified owner, linked to a specific escrow and factory contract.

### Functions

**approveTokensToEscrow**

```solidity
function approveTokensToEscrow(address _token, uint256 _amount, uint256 _nonce, bytes calldata _signature) external onlyEscrowOwner;
```

* **Description**: Approves a specified amount of tokens to the escrow contract, using a signature for authorization.
* **Inputs**:
  * `_token`: The token to approve.
  * `_amount`: Amount of tokens to approve.
  * `_nonce`: A nonce for operation uniqueness.
  * `_signature`: An off-chain generated signature for operation verification.
* **Emits**: `ApproveTokensToEscrow` event upon success.

**depositIntoEscrow**

```solidity
function depositIntoEscrow(address _token, uint256[] calldata _splitAmounts, address[] calldata _splitAddresses) external nonReentrant onlyEscrowOwner;
```

* **Description**: Deposits tokens into the escrow contract for split distribution.
* **Inputs**:
  * `_token`: The token to deposit.
  * `_splitAmounts`: Array of amounts for split distribution.
  * `_splitAddresses`: Array of addresses for receiving the split amounts.
* **Emits**: `DepositIntoEscrow` event upon success.

**topUpDepositIntoEscrow**

```solidity
function topUpDepositIntoEscrow(uint256 _depositId, uint256[] calldata _splitAmounts) external nonReentrant onlyEscrowOwner;
```

* **Description**: Tops up an existing deposit in the escrow contract.
* **Inputs**:
  * `_depositId`: The ID of the deposit to top up.
  * `_splitAmounts`: New split amounts for the deposit.
* **Emits**: `TopUpDepositIntoEscrow` event upon success.

**initiateTokenWithdrawal**

```solidity
function initiateTokenWithdrawal(address _token, uint256 _amount) external nonReentrant onlyOwner;
```

* **Description**: Initiates a withdrawal of tokens to the owner after a delay.
* **Inputs**:
  * `_token`: The token to withdraw.
  * `_amount`: The amount of tokens to withdraw.

**claimTokenWithdrawal**

```solidity
function claimTokenWithdrawal(address _token) external nonReentrant onlyOwner;
```

* **Description**: Claims a pending token withdrawal after the delay.
* **Inputs**:
  * `_token`: The token to claim withdrawal for.

**getSmartWalletOwner**

```solidity
function smartWalletOwner() public view returns (address);
```

* **Description**: Returns the address of the owner of the smart wallet.
* **Outputs**: Address of the smart wallet owner.

**escrowOwner**

```solidity
function escrowOwner() public view returns (address);
```

* **Description**: Returns the address of the owner of the linked escrow contract.
* **Outputs**: Address of the escrow contract owner.

**\_validateNonce**

```solidity
function _validateNonce(uint256 _nonce) internal;
```

* **Description**: Validates the provided nonce to ensure it matches the expected sequence, incrementing the wallet's nonce upon success.
* **Inputs**: `_nonce` - The nonce to validate.

**\_validateSignature**

```solidity
function _validateSignature(bytes32 _hash, bytes calldata _signature) internal view;
```

* **Description**: Validates the provided signature against the expected hash and the wallet owner's address.
* **Inputs**:
  * `_hash` - The hash of the signed data.
  * `_signature` - The signature to validate.

**\_getHash**

```solidity
function _getHash(bytes memory _data) internal pure returns (bytes32);
```

* **Description**: Computes the hash of the given data.
* **Inputs**: `_data` - The data to hash.
* **Outputs**: The hash of the data.

**\_getSum**

```solidity
function _getSum(uint256[] memory _values) internal pure returns (uint256);
```

* **Description**: Calculates the sum of the given array of values.
* **Inputs**: `_values` - An array of values to sum.
* **Outputs**: The sum of the values.

#### Modifiers

* **onlyEscrowOwner**: Restricts function calls to the owner of the escrow contract.

#### Events

* `ApproveTokensToEscrow`: Emitted when tokens are approved to the escrow.
* `DepositIntoEscrow`: Emitted upon a token deposit into the escrow.
* `TopUpDepositIntoEscrow`: Emitted when a deposit in the escrow is topped up.

#### Errors

* `ZeroAddress`: Thrown when a zero address is provided where it is not allowed.
* `ZeroValue`: Thrown when an ether transfer with a zero amount is attempted.
* `ZeroTokens`: Thrown when a token operation involves a zero amount.
* `InsufficientBalance`: Indicates the wallet has insufficient token balance for an operation.
* `InvalidNonce`: Thrown when an invalid nonce is used, preventing replay attacks.
* `InvalidSignature`: Thrown when a provided signature does not match the expected signer.
* `TokenApprovalFailed`: Indicates a failure in token approval to the escrow.
* `WithdrawalDelayNotPassed`: Thrown when a withdrawal is attempted before the delay period ends.
* `ERC20TransferFailed`: Indicates a failure in transferring ERC20 tokens.
* `EtherTransferFailed`: Indicates a failure in transferring ether.
* `OnlyEscrowOwner`: Restricts certain operations to the escrow contract owner.
