> For the complete documentation index, see [llms.txt](https://docs.kpk.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kpk.io/funds/kpk-fund-integration/redemption-request.md).

# Redemption request

Create a redemption request on the shares contract to exit a fund.

Redeeming is a single step; no approval is needed, because the shares contract pulls the shares you already hold into escrow:

```solidity
function requestRedemption(
    uint256 sharesIn,       // amount of shares to redeem
    uint256 minAssetsOut,   // slippage protection, applied AFTER the redemption fee
    address redemptionAsset,// must be approved for redemptions (canRedeem = true)
    address receiver        // who receives the assets
) external returns (uint256 requestId);
```

{% hint style="warning" %}
`minAssetsOut` is **slippage protection** measured **after** the redemption fee. The operator's settlement must yield at least `minAssetsOut` assets or the request fails. Derive it from the fund's current share price, see [Calculate share price](/funds/kpk-fund-integration/calculate-share-price.md), then deduct the redemption fee (`redemptionFeeRate`), convert the remainder with `sharesToAssets`, and apply a tolerance. The 0.5% used below is only an example; set it to how much slippage you are willing to accept.
{% endhint %}

## Example

Redeeming **500 shares** (18 decimals) for USDC. We read the fund's current share price (see [Calculate share price](/funds/kpk-fund-integration/calculate-share-price.md)), deduct the redemption fee, convert the remainder with `sharesToAssets`, and apply a 0.5% example tolerance to get `minAssetsOut`.

{% tabs %}
{% tab title="viem" %}

```typescript
import { createWalletClient, createPublicClient, http, parseAbi, parseUnits } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { mainnet } from "viem/chains";

const SHARES = "0x...";  // fund shares contract
const USDC   = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";

const sharesAbi = parseAbi([
  "function sharesToAssets(uint256 shares, uint256 sharesPrice, address redemptionAsset) view returns (uint256)",
  "function redemptionFeeRate() view returns (uint256)",
  "function requestRedemption(uint256 sharesIn, uint256 minAssetsOut, address redemptionAsset, address receiver) returns (uint256)",
]);

const account = privateKeyToAccount("0x...");
const pub = createPublicClient({ chain: mainnet, transport: http() });
const wallet = createWalletClient({ account, chain: mainnet, transport: http() });

const sharesIn = parseUnits("500", 18); // 500 shares

// 1. Current share price in 8-decimal USD — compute it onchain per Calculate share price.
const sharePrice = await getSharePrice(pub); // bigint, 8 decimals — see Calculate share price

// 2. Deduct the redemption fee, convert the remainder, then apply your tolerance.
const feeRate = await pub.readContract({ address: SHARES, abi: sharesAbi, functionName: "redemptionFeeRate" });
const netShares = sharesIn - (sharesIn * feeRate) / 10000n;
const expectedAssets = await pub.readContract({
  address: SHARES, abi: sharesAbi, functionName: "sharesToAssets",
  args: [netShares, sharePrice, USDC],
});
const minAssetsOut = (expectedAssets * 9950n) / 10000n; // 0.5% is only an example — set your own tolerance

const hash = await wallet.writeContract({
  address: SHARES, abi: sharesAbi, functionName: "requestRedemption",
  args: [sharesIn, minAssetsOut, USDC, account.address],
});
```

{% endtab %}

{% tab title="ethers.js" %}

```typescript
import { ethers } from "ethers";

const SHARES = "0x...";  // fund shares contract
const USDC   = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";

const sharesAbi = [
  "function sharesToAssets(uint256 shares, uint256 sharesPrice, address redemptionAsset) view returns (uint256)",
  "function redemptionFeeRate() view returns (uint256)",
  "function requestRedemption(uint256 sharesIn, uint256 minAssetsOut, address redemptionAsset, address receiver) returns (uint256)",
];

const provider = new ethers.JsonRpcProvider("https://eth.llamarpc.com");
const signer = new ethers.Wallet("0x...", provider);
const shares = new ethers.Contract(SHARES, sharesAbi, signer);

const sharesIn = ethers.parseUnits("500", 18);

const sharePrice = await getSharePrice(provider); // 8-dec USD — see Calculate share price
const feeRate = await shares.redemptionFeeRate();
const netShares = sharesIn - (sharesIn * feeRate) / 10000n;
const expectedAssets = await shares.sharesToAssets(netShares, sharePrice, USDC);
const minAssetsOut = (expectedAssets * 9950n) / 10000n; // 0.5% is only an example — set your own tolerance

const tx = await shares.requestRedemption(sharesIn, minAssetsOut, USDC, await signer.getAddress());
await tx.wait();
```

{% endtab %}

{% tab title="Python" %}

```python
from web3 import Web3

SHARES = "0x..."  # fund shares contract
USDC   = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"

shares_abi = [
    {"name": "sharesToAssets", "type": "function", "stateMutability": "view",
     "inputs": [{"name": "shares", "type": "uint256"}, {"name": "sharesPrice", "type": "uint256"},
                {"name": "redemptionAsset", "type": "address"}],
     "outputs": [{"type": "uint256"}]},
    {"name": "redemptionFeeRate", "type": "function", "stateMutability": "view",
     "inputs": [], "outputs": [{"type": "uint256"}]},
    {"name": "requestRedemption", "type": "function", "stateMutability": "nonpayable",
     "inputs": [{"name": "sharesIn", "type": "uint256"}, {"name": "minAssetsOut", "type": "uint256"},
                {"name": "redemptionAsset", "type": "address"}, {"name": "receiver", "type": "address"}],
     "outputs": [{"type": "uint256"}]},
]

w3 = Web3(Web3.HTTPProvider("https://eth.llamarpc.com"))
acct = w3.eth.account.from_key("0x...")
shares = w3.eth.contract(address=SHARES, abi=shares_abi)

shares_in = 500 * 10**18  # 500 shares

share_price = get_share_price(w3)  # 8-decimal USD — see Calculate share price
fee_rate = shares.functions.redemptionFeeRate().call()
net_shares = shares_in - (shares_in * fee_rate) // 10000
expected_assets = shares.functions.sharesToAssets(net_shares, share_price, USDC).call()
min_assets_out = expected_assets * 9950 // 10000  # 0.5% is only an example — set your own tolerance

req = shares.functions.requestRedemption(
    shares_in, min_assets_out, USDC, acct.address
).build_transaction({"from": acct.address})
# ... sign & send req ...
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}

## Events

Creating a redemption request emits a `RedemptionRequest` event containing the `requestId`, `cancelableFrom`, and `expiryAt`. Track it as described in [Monitor a request](/funds/kpk-fund-integration/monitor-a-request.md).
{% endhint %}

<figure><picture><source srcset="/files/QZEgPpXU4vmjED4jf0xO" media="(prefers-color-scheme: dark)"><img src="https://1699303810-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FUsQM4bzcmOPSgkWddkeN%2Fuploads%2FB7Nh2cj2ZpJjw9T1Lmbu%2Fkpk_funds_redemption_request.png?alt=media&amp;token=6754993f-4675-4cac-94f0-f945000ebc4e" alt=""></picture><figcaption><p>Redemption flow example</p></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.kpk.io/funds/kpk-fund-integration/redemption-request.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
