# Safety Module Deposits

Assets deposited into a Safety Module can be tapped by controllers if the Safety Module is triggered (see [Safety Module Raising](https://csm-docs.cozy.finance/developer-guides/safety-module-raises)). In return, depositors are minted receipt tokens which may be used to earn rewards (see [Stake into a Rewards Manager](https://csm-docs.cozy.finance/developer-guides/stake-into-a-rewards-manager)) and withdraw their assets.

To deposit assets, `SafetyModule.depositReserveAssets` or `SafetyModule.depositReserveAssetsWithoutTransfer` can be used.

**Note:** The `SafetyModule.depositReserveAssetsWithoutTransfer` is only designed to be used by integrators or the [CozyRouter](#using-cozyrouter-to-deposit-assets) contract, where assets are atomically transferred into the SafetyModule and deposited on behalf of a user. Otherwise, assets that have been transferred and sitting in the SafetyModule are at risk of being claimed as a deposit by someone who front-runs the call to `depositReserveAssetsWithoutTransfer`.

```solidity
/// @notice Deposits reserve assets into the SafetyModule and mints deposit receipt tokens.
/// @dev Expects `msg.sender` to have approved this SafetyModule for `reserveAssetAmount_` of
/// `reservePools[reservePoolId_].asset` so it can `transferFrom` the assets to this SafetyModule.
/// @param reservePoolId_ The ID of the reserve pool to deposit assets into.
/// @param reserveAssetAmount_ The amount of reserve assets to deposit.
/// @param receiver_ The address to receive the deposit receipt tokens.
function depositReserveAssets(uint8 reservePoolId_, uint256 reserveAssetAmount_, address receiver_)
    external
    returns (uint256 depositReceiptTokenAmount_);
    
/// @notice Deposits reserve assets into the SafetyModule and mints deposit receipt tokens.
/// @dev Expects depositer to transfer assets to the SafetyModule beforehand.
/// @param reservePoolId_ The ID of the reserve pool to deposit assets into.
/// @param reserveAssetAmount_ The amount of reserve assets to deposit.
/// @param owner_ The owner of the deposited assets (for event logging purposes).
/// @param receiver_ The address to receive the deposit receipt tokens.
function depositReserveAssetsWithoutTransfer(
  uint8 reservePoolId_,
  uint256 reserveAssetAmount_,
  address owner_,
  address receiver_
) external returns (uint256 depositReceiptTokenAmount_)
```

`SafetyModule.depositReserveAssets` requires `msg.sender` to have approved `SafetyModule` to a spend sufficient amount of their `SafetyModule.reservePools(reservePoolId).asset` balance.

`SafetyModule.depositReserveAssetsWithoutTransfer` requires the `SafetyModule.reservePools(reservePoolId).asset` amount being deposited to be transferred to the Safety Module beforehand.

## Using CozyRouter to deposit assets

Using the [CozyRouter](https://csm-docs.cozy.finance/developer-guides/broken-reference) may be preferable in cases where integrators would like to batch several Safety Module related function calls into a single transaction (e.g. wrap ETH to WETH and deposit).

To deposit assets using the CozyRouter, integrators can use `CozyRouter.depositReserveAssets`:

```solidity
/// @notice Deposits assets into a `safetyModule_` reserve pool by transferring `reserveAssetAmount_` of the reserve
/// assets from the caller to the `safetyModule_` and minting `depositReceiptTokenAmount_` receipt tokens to the
/// `receiver_`.
/// @dev This will revert if the router is not approved for at least `reserveAssetAmount_` of the reserve asset.
/// @dev The `receiver_` must be set to the msg.sender to mantain the custody invariant.
function depositReserveAssets(
  ISafetyModule safetyModule_,
  uint8 reservePoolId_,
  uint256 reserveAssetAmount_,
  address receiver_
) public payable returns (uint256 depositReceiptTokenAmount_);
```

This method will:

* Transfer the underlying reserve assets from the `msg.sender` to the Safety Module.
* Call `SafetyModule.depositReserveAssetsWithoutTransfer.`

`CozyRouter.depositReserveAssets` requires the depositor to have approved `CozyRouter` to a spend sufficient amount of their `SafetyModule.reservePools(reservePoolId).asset` balance.

## Deposit mechanics

On deposit, high-level the Safety Module does the following:

* Check if the Safety Module is `PAUSED`. If so, revert.
* Check the Safety Module's asset balance to determine if the total deposit amount was transferred to it. If not, revert.
* Update the relevant reserve pool's internal accounting.
* Mint the `receiver_` address deposit receipt tokens.
* Emit a `Deposited` event.
