OffBlocksEscrow.sol

Protocol documentation for the OffBlocksEscrow.sol smart contract.

Contract Overview

Inherits:

  • ReentrancyGuardUpgradeable, OwnableUpgradeable & PausableUpgradeable from OpenZeppelin

  • Also imports IERC20 & IOffBlocksSmartWalletFactory interfaces which are used in the contract

Author: OffBlocks Team

Description: This escrow contract handles token deposits and withdrawals coming from smart wallets, specifically designed for the OffBlocks platform. It supports deposit operations, deposit status updates, withdrawals for rejected deposits, and settlement of approved deposits.

Main Features:

  • Handling token deposits from smart wallets.

  • Approval, rejection, and settlement of deposits.

  • Support for multiple tokens, with functionality to add or remove tokens.

  • Integration with OffBlocks smart wallet factory for smart wallet verification.

  • Emergency withdrawal mechanism for added security.

State Variables

  1. smartWalletFactory (IOffBlocksSmartWalletFactory): Address of the OffBlocks smart wallet factory contract. It is used to verify whether a depositor's address is a smart wallet.

  2. supportedTokens (mapping(IERC20 => bool)): A mapping that tracks which tokens are supported by the escrow. Only supported tokens can be deposited.

  3. deposits (mapping(address => uint256[])): A mapping from a depositor's address to an array of their deposit IDs. It keeps track of all deposits made by each depositor.

  4. depositById (mapping(uint256 => Deposit)): A mapping from a deposit ID to its corresponding Deposit struct. This struct contains details about each deposit.

  5. _nextDepositId (uint256): An internal variable that keeps track of the next available deposit ID. It ensures that each deposit has a unique identifier.

Structs

  1. Deposit:

    • depositId (uint256): Unique identifier for the deposit.

    • depositor (address): Address of the depositor, which must be a smart wallet.

    • token (address): Address of the token being deposited.

    • amount (uint256): Amount of the token deposited.

    • splitAmounts (uint256[]): Array of amounts that correspond to how the deposit should be split upon approval.

    • splitAddresses (address[]): Addresses to which the split amounts will be sent upon deposit approval.

    • status (DepositStatus): Current status of the deposit (Pending, Approved, or Rejected).

    • createdAt (uint256): Timestamp when the deposit was created.

    • updatedAt (uint256): Timestamp when the deposit was last updated.

  2. DepositStatus (enum): Represents the possible states of a deposit: Pending, Approved, or Rejected.

Events

  1. Deposited:

    • Emitted when a new deposit is made into the escrow.

    • Parameters: depositId, depositor, token, amount, createdAt.

  2. DepositToppedUp:

    • Emitted when an existing deposit is topped up with an additional amount.

    • Parameters: depositId, depositor, token, amount, updatedAt.

  3. DepositReduced:

    • Emitted when the amount of an existing deposit is reduced.

    • Parameters: depositId, depositor, token, amount, updatedAt.

  4. DepositStatusUpdated:

    • Emitted when the status of a deposit is updated to either Approved or Rejected.

    • Parameters: depositId, status, updatedAt.

  5. Withdrawal:

    • Emitted when a rejected deposit is withdrawn back to the depositor.

    • Parameters: depositId, depositor, token, amount, timestamp.

  6. Settlement:

    • Emitted when an approved deposit is settled, i.e., the deposited tokens are transferred according to the split configuration.

    • Parameters: depositId, depositor, token, amount, timestamp.

  7. NewSupportedToken:

    • Emitted when a new token is added to the list of supported tokens.

    • Parameter: token.

  8. RemovedSupportedToken:

    • Emitted when a token is removed from the list of supported tokens.

    • Parameter: token.

  9. SmartWalletFactoryUpdated:

    • Emitted when the smart wallet factory address is updated.

    • Parameter: smartWalletFactory.

  10. RescueTokens:

    • Emitted when the contract owner rescues ERC20 tokens sent to the contract by mistake.

    • Parameters: to, token, amount.

Errors

  1. ZeroAddress:

    • Thrown when a function receives the zero address where it is not allowed.

  2. ZeroAmount:

    • Thrown when an operation involving tokens or Ether is attempted with a zero amount.

  3. InsufficientBalance:

    • Thrown when a depositor does not have enough balance of a token to make a deposit.

  4. InsufficientAllowance:

    • Thrown when the contract does not have enough allowance to transfer tokens on behalf of a depositor.

  5. UnsupportedToken:

    • Thrown when an attempt is made to deposit a token not supported by the escrow.

    • Parameter: token.

  6. InvalidStatus:

    • Thrown when an invalid status is passed to a function.

    • Parameter: status.

  7. DepositNotPending:

    • Thrown when an operation that requires a deposit to be in the Pending status is attempted on a deposit with a different status.

  8. DepositNotApproved:

    • Thrown when an operation that requires a deposit to be in the Approved status is attempted on a deposit with a different status.

  9. DepositNotRejected:

    • Thrown when an operation that requires a deposit to be in the Rejected status is attempted on a deposit with a different status.

  10. InvalidDepositId:

    • Thrown when an operation is attempted on a deposit with an ID that does not exist.

    • Parameter: depositId.

  11. ERC20TransferFailed:

    • Thrown when a transfer of ERC20 tokens fails.

  12. ArrayLengthMismatch:

    • Thrown when the lengths of two arrays expected to match do not match.

  13. InvalidSplitAddressIncluded:

    • Thrown when a split address included in a deposit is invalid (e.g., the zero address).

  14. MsgSenderIsNotASmartWallet:

    • Thrown when a function that expects the caller to be a smart wallet is called by an address that is not a smart wallet.

  15. NewAmountLessThanOldAmount:

    • Thrown when an attempt is made to top up a deposit with an amount less than the existing deposit amount.

  16. NewAmountGreaterThanOldAmount:

    • Thrown when an attempt is made to reduce a deposit with an amount greater than the existing deposit amount.

  17. DepositUnchanged:

    • Thrown when an attempt is made to modify a deposit amount, but the new amount is the same as the old amount.

  18. ZeroTokens:

    • Thrown when an operation involving the rescue of tokens is attempted, but there are no tokens to rescue.

  19. ArrayLengthOfZero:

    • Thrown when an operation involving an array is attempted with an array of length zero.

Modifiers

There are no custom modifiers defined in the contract beyond what's inherited from OpenZeppelin's ReentrancyGuard, Ownable, and Pausable contracts, which include standard modifiers like nonReentrant, onlyOwner, and whenNotPaused/whenPaused.

Initializer

initialize

function initialize(address _smartWalletFactory, address[] memory _initiallySupportedTokens, address _owner) external initializer
  • Description: Since the OffBlocksEscrow contract is intended to be upgradeable through the use of TransparentUpgradeableProxy pattern, it needs an initializer function. It initializes the escrow contract with a smart wallet factory, a list of initially supported tokens, and sets the contract owner.

  • Inputs:

    • _smartWalletFactory: Address of the OffBlocks smart wallet factory contract.

    • _initiallySupportedTokens: Array of token addresses initially supported by the escrow.

    • _owner: Address of the contract owner.

  • Notes: This function replaces the constructor for upgradeable contracts and can only be called once.

Functions

addSupportedToken

function addSupportedToken(address _token) external onlyOwner
  • Description: Adds a token to the list of tokens supported by the escrow for deposit.

  • Inputs:

    • _token: The address of the token to be added to the list of supported tokens.

  • Modifiers: onlyOwner - Ensures that only the contract owner can add supported tokens.

removeSupportedToken

function removeSupportedToken(address _token) external onlyOwner
  • Description: Removes a token from the list of tokens supported by the escrow.

  • Inputs:

    • _token: The address of the token to be removed from the list of supported tokens.

  • Modifiers: onlyOwner - Restricts this function to the contract owner.

updateSmartWalletFactory

function updateSmartWalletFactory(address _smartWalletFactory) external onlyOwner
  • Description: Updates the address of the OffBlocks smart wallet factory.

  • Inputs:

    • _smartWalletFactory: New address of the OffBlocks smart wallet factory.

  • Modifiers: onlyOwner - Only the contract owner can update the smart wallet factory address.

deposit

function deposit(address _token, uint256[] memory _splitAmounts, address[] memory _splitAddresses) external nonReentrant whenNotPaused
  • Description: Allows a smart wallet to deposit tokens into the escrow, specifying how the tokens should be split upon approval.

  • Inputs:

    • _token: Address of the token being deposited.

    • _splitAmounts: Array of amounts for each split.

    • _splitAddresses: Corresponding addresses for each split amount.

  • Modifiers:

    • nonReentrant: Prevents re-entrancy attacks.

    • whenNotPaused: Function can only be called when the contract is not paused.

topUpDeposit

function topUpDeposit(uint256 _depositId, uint256[] memory _splitAmounts) external nonReentrant whenNotPaused
  • Description: Tops up an existing deposit with additional tokens.

  • Inputs:

    • _depositId: ID of the deposit to be topped up.

    • _splitAmounts: New split amounts, updating the deposit's split configuration.

  • Modifiers:

    • nonReentrant

    • whenNotPaused

reduceDeposit

function reduceDeposit(uint256 _depositId, uint256[] memory _splitAmounts) external nonReentrant onlyOwner
  • Description: Reduces the amount of an existing deposit and adjusts the split configuration.

  • Inputs:

    • _depositId: ID of the deposit to be reduced.

    • _splitAmounts: Adjusted split amounts.

  • Modifiers:

    • nonReentrant

    • onlyOwner

batchUpdateDepositStatuses

function batchUpdateDepositStatuses(uint256[] calldata _depositIds, uint256 _status) external onlyOwner
  • Description: Batch updates the statuses of multiple deposits.

  • Inputs:

    • _depositIds: Array of deposit IDs to update.

    • _status: New status for the deposits (Pending, Approved, Rejected).

  • Modifiers: onlyOwner

reject

function reject(uint256 _depositId) external nonReentrant onlyOwner
  • Description: Rejects a deposit, enabling the depositor to withdraw the tokens.

  • Inputs:

    • _depositId: ID of the deposit to be rejected.

  • Modifiers:

    • nonReentrant

    • onlyOwner

settle

function settle(uint256 _depositId) external nonReentrant onlyOwner
  • Description: Transfers tokens from an approved deposit according to its split configuration.

  • Inputs:

    • _depositId: ID of the deposit to be settled.

  • Modifiers:

    • nonReentrant

    • onlyOwner

batchSettle

function batchSettle(uint256[] calldata _depositIds) external onlyOwner
  • Description: Batch settles approved deposits, distributing tokens per their split configurations.

  • Inputs:

    • _depositIds: Array of deposit IDs to be settled.

  • Modifiers: onlyOwner

pause

function pause() external onlyOwner
  • Description: Pauses the contract, disabling deposits and status updates.

  • Modifiers: onlyOwner

unpause

function unpause() external onlyOwner
  • Description: Unpauses the contract, enabling deposits and status updates.

  • Modifiers: onlyOwner

rescueTokens

function rescueTokens(address _token) external onlyOwner
  • Description: Allows the contract owner to rescue mistakenly sent ERC20 tokens.

  • Inputs:

    • _token: Address of the token to be rescued.

  • Modifiers: onlyOwner

  • Emits: RescueTokens event on success.

getSmartWalletFactory

function getSmartWalletFactory() external view returns (address)
  • Description: Returns the address of the smart wallet factory.

  • Outputs:

    • address: The address of the smart wallet factory used by the escrow.

getDepositsOfUser

function getDepositsOfUser(address _depositor) external view returns (uint256[] memory)
  • Description: Retrieves the array of deposit IDs associated with a depositor.

  • Inputs:

    • _depositor: Address of the user whose deposit IDs are being queried.

  • Outputs:

    • uint256[]: Array of deposit IDs belonging to the depositor.

getDepositById

function getDepositById(uint256 _depositId) public view returns (Deposit memory)
  • Description: Fetches the details of a deposit by its ID.

  • Inputs:

    • _depositId: ID of the deposit to fetch.

  • Outputs:

    • Deposit: A struct containing the details of the deposit.

getNextDepositId

function getNextDepositId() public view returns (uint256)
  • Description: Retrieves the ID that will be assigned to the next deposit.

  • Outputs:

    • uint256: The ID to be assigned to the next deposit.

_checkForInvalidAddress

function _checkForInvalidAddress(address[] memory _splitAddresses) internal pure returns (bool)
  • Description: Checks if the provided array of split addresses contains any invalid (zero) addresses.

  • Inputs:

    • _splitAddresses: Array of addresses to check.

  • Outputs:

    • bool: true if all addresses are valid; otherwise, false.

_getSum

function _getSum(uint256[] memory _values) internal pure returns (uint256)
  • Description: Calculates the sum of an array of uint256 values.

  • Inputs:

    • _values: Array of uint256 values to sum.

  • Outputs:

    • uint256: Sum of the values in the array.

Last updated