# Withdraw Rewards

### Withdrawing rewards from a Rewards Manager

To allow depositors to reclaim unutilized incentives, the Rewards Manager supports withdrawals of undripped reward assets. A depositor can withdraw rewards they have previously contributed to a reward pool, provided those rewards have not yet dripped.

Depositors may call `RewardsManager.withdrawRewardAssets` directly:

```solidity
/// @notice Withdraw undripped reward assets.
/// @param rewardPoolId_ The ID of the reward pool to withdraw from.
/// @param rewardAssetAmount_ The amount of reward assets to withdraw.
/// @param receiver_ The address that will receive the withdrawn assets.
function withdrawRewardAssets(
  uint16 rewardPoolId_,
  uint256 rewardAssetAmount_,
  address receiver_
) external;
```

This method will:

1. **Preview withdrawable rewards**: Check the caller’s current withdrawable rewards using `_previewCurrentWithdrawableRewards`.
2. **Validate request**: Revert if `rewardAssetAmount_` exceeds the caller’s withdrawable rewards.
3. **Update accounting**: Reduce the caller’s `depositorRewards` balance and the pool’s `undrippedRewards` and asset totals.
4. **Transfer assets**: Send the specified reward assets to the `receiver_`.
5. **Emit event**: Log the withdrawal in a `Withdrawn` event.

To withdraw on behalf of another user, you may use `RewardsManager.withdrawRewardAssetsBySig`

```solidity
bytes32 public constant WITHDRAW_REWARD_ASSETS_BY_SIG_TYPEHASH = keccak256("WithdrawRewardAssetsBySig(address owner,uint16 rewardPoolId,uint256 rewardAssetAmount,address caller,address receiver,uint256 deadline,uint256 nonce)")

/// @notice Returns the domain separator.
function domainSeparator() external view returns (bytes32);

/// @notice Tracks per-owner nonces for EIP-712 signed operations.
/// @param owner_ the owner of this nonce
/// @param actionKey_ typehash used for this call (i.e. WITHDRAW_REWARD_ASSETS_BY_SIG_TYPEHASH)
function eip712Nonces(address owner_, bytes32 actionKey_) external view returns (uint256);

/// @notice Withdraw undripped reward assets on behalf of the owner via permit-style authorization.
/// @dev Signature binds to (owner, rewardPoolId, rewardAssetAmount, caller=msg.sender, receiver, deadline).
/// @param rewardPoolId_ The ID of the reward pool to withdraw from.
/// @param rewardAssetAmount_ The amount of reward assets to withdraw.
/// @param owner_ The owner of the reward assets.
/// @param receiver_ The address that will receive the withdrawn assets.
/// @param deadline_ The time at which the signature expires.
/// @param signature_ The owner's signature over the EIP-712 structured data.
function withdrawRewardAssetsBySig(
  uint16 rewardPoolId_,
  uint256 rewardAssetAmount_,
  address owner_,
  address receiver_,
  uint256 deadline_,
  bytes calldata signature_
) external {

  bytes32 digest_ = keccak256(
    abi.encodePacked(
      "\x19\x01",
      keccak256(
        abi.encode(
         domainSeparator()
        )
      ),
      keccak256(
        abi.encode(
          WITHDRAW_REWARD_ASSETS_BY_SIG_TYPEHASH,
          owner_,
          rewardPoolId_,
          rewardAssetAmount_,
          msg.sender,
          receiver_,
          deadline_,
          nonce_
        )
      )
    )
  );

  if (!SignatureChecker.isValidSignatureNow(owner_, digest_, signature_)) revert InvalidSignature();
}
```

* The owner must sign a digest that matches the above.
* Fetch Domain Separator via external `domainSeparator()` getter and nonce via external `eip712Nonces(owner, actionKey)`(actionKey is the relevant typehash) getter. Both are exposed in IRewardsManager. &#x20;
* The above `withdrawRewardAssetsBySig` function is truncated to only show the relevant structure of the digest.&#x20;

***

Before withdrawing, users may use `previewCurrentWithdrawableRewards` to determine how many rewards a depositor is eligible to withdraw:

```solidity
/// @notice Preview the current withdrawable rewards for the depositor.
/// @param rewardPoolId_ The ID of the reward pool.
/// @param depositor_ The address of the depositor.
/// @return The depositor's current withdrawable rewards.
function previewCurrentWithdrawableRewards(
  uint16 rewardPoolId_,
  address depositor_
) external view returns (uint256);
```

This function accounts for:

* **Epoch changes**: If the depositor’s rewards belong to an expired epoch, withdrawable rewards are set to 0.
* **Drip updates**: If rewards have dripped since the last update, withdrawable rewards are scaled down accordingly.
* **Stable snapshots**: If no drip has occurred since the depositor’s last update, withdrawable rewards remain unchanged.
