# Stake

Staking into a Rewards Manager, provides users with the opportunity to earn rewards. Different stake pools will have a different underlying stake asset and provide a different reward profile.

Stakers receive receipt tokens, which can be used to claim rewards.

### Using CozyRouter to stake assets

The recommended way to programmatically stake assets is to call `CozyRouter.stake` (see [CozyRouter](https://csm-docs.cozy.finance/developer-guides/stake-into-a-rewards-manager/broken-reference)):

```solidity
function stake(IRewardsManager rewardsManager_, uint16 stakePoolId_, uint256 stakeAssetAmount_, address receiver_)
    external
    payable
    returns (uint256 stakeReceiptTokenAmount_);
```

This method will:

* Transfer the underlying stake assets from the `msg.sender` to the Rewards Manager.
* Internally call `RewardsManager.stakeWithoutTransfer.`&#x20;

Prior to calling this function, the user must have approved `CozyRouter` to a spend sufficient amount of their `StakePool.asset` balance.

### Stake mechanics

`RewardsManager.stakeWithoutTransfer` assumes that the assets to be stakes have already been transferred to the Rewards Manager. Any excess assets transferred will be kept by the Rewards Manager.&#x20;

On stake, we follow the following steps:

* Check it the Rewards Manager is `PAUSED`. If so, revert.
* Check the Rewards Manager's asset balance to determine if the stake amount was transferred. If not, revert.
* Update the `StakePool.amount` value.
* Drip and apply any pending rewards to get `claimableRewards[stakePoolId_]` up to date.
* Update `userRewards[stakePoolId_][receiver_]`.
* Mint the `receiver_` address stake receipt tokens.
* Emit a `Staked` event.
