# redeem

Redeem user collateral locked under yToken token of `tokenId`, burning `amount` of users yTokens.

{% hint style="warning" %}
The `yToken` contract expects that underlying token info of `tokenId` and all borrowed by user before `tokenId`s are updated by calling [PriceFeed.getPrice](https://yupana-finance.gitbook.io/yupana-document-portal/developer-space/pricefeed-contract/getprice) and [updateInterest](https://yupana-finance.gitbook.io/yupana-document-portal/developer-space/ytoken-contract-methods/updateinterest) in the same block **before** this contract method
{% endhint %}

{% hint style="info" %}
If `amount` passed `0n` than `amount` calculated as&#x20;

`amount = userBalance * token.liquidity / token.totalSupply`
{% endhint %}

### Types

```pascaligo
type yAssetParams       is [@layout:comb] record [
  tokenId                 : nat; // yToken token Id
  amount                  : nat; // amount tokens to burn
]
```

| Parameter | Type | Description               |
| :-------: | :--: | ------------------------- |
|  tokenId  |  nat | yToken identifier         |
|   amount  |  nat | amount of yTokens to burn |

### Usage

{% tabs %}
{% tab title="🌮 Taquito" %}

```typescript
const redeemTokenId = 0; // or new BigNumber(0) or "0"
const amount = 10_000_000; // amount of yTokens to burn, pass 0 to burn all.
const yupana = await tezos.contract.at(yTokenAddress);
const proxy = await tezos.contract.at(proxyAddress);
const borrowedTokenIds = [1, 2]; // user borrowed tokens
const updBorrowed = borrowedTokenIds.reduce(
  (batch, tokenId) => {
    batch.push({
        kind: "transaction",
        ...yupana.methods.updateInterest(tokenId).toTransferParams(),
      },
      {
        kind: "transaction",
        ...proxy.methods.getPrice([tokenId]).toTransferParams(),
      });
      return batch;
    }
const batchArray = [
      ...updBorrowed,
      {
        kind: "transaction",
        ...yupana.methods.updateInterest(redeemTokenId).toTransferParams(),
      },
      {
        kind: "transaction",
        ...proxy.methods.getPrice([redeemTokenId]).toTransferParams(),
      },
      {
        kind: "transaction",
        ...yupana.methods.redeem(redeemTokenId, amount).toTransferParams(),
      },
    ];
const batch = await tezos.wallet.batch(batchArray);
const operation = await batch.send();
await operation.confirmation();
```

{% endtab %}

{% tab title="🐍   Pytezos" %}

```python
token_id = 0
amount = 10_000_000 # amount of yTokens to burn, pass 0 to burn all.
yupana = ContractInterface.from_michelson(code) # or client.contract(contract_address)...
proxy = ContractInterface.from_michelson(prx_code) # or client.contract(prx_contract_address)...borrow_ids = [1, 2] # user borrowed tokens
borrow_ids = [1, 2] # user borrowed tokens
borrow_updates = [yupana.updateInterest(borrowTokenId) for borrowTokenId in borrow_ids]
borrow_updates.append(proxy.getPrice([borrowTokenId for borrowTokenId in borrow_ids]))
call = pytezos.bulk(
        *borrow_updates,
        yupana.updateInterest(token_id),
        proxy.getPrice([token_id]),
        yupana.redeem(token_id, amount)
    ).autofill().sign()
opg = call.inject()
```

{% endtab %}
{% endtabs %}

### Errors

{% hint style="info" %}
`burnAmount = amount * token.totalSupply / token.liquidity`
{% endhint %}

* `yToken/not-enough-tokens-to-burn` - not enough balance of tokens to burn `burnAmount` wanted by user.
* `underflow/totalSupplyF` - total supply less than `burnAmount`.
* `underflow/totalLiquidF` - total liquidity less than `amount`.
* `token/cant-get-contract-token` - FA12 token contract address does not contain `transfer` entrypoint from FA12 interface.
* `token/cant-get-contract-fa2-token` - FA2 token contract address does not contain `transfer` entrypoint from FA2 interface.
* `yToken/exceeds-allowable-redeem` - raised when outstanding borrow value greater than max collateral value.
* `underflow/liquidity - reserves` - liquidity more than reserves.
* `ceil-div-error` - division of two numbers fails.
* `yToken/need-update` - token price and interest not updated (see <mark style="color:orange;">warning</mark> above)
* `yToken/yToken-undefined` - token identifier is not assigned to any known yTokens.
