# Principal Token

The Principal Token is the main contract of Spectra. It is EIP [5095](https://eips.ethereum.org/EIPS/eip-5095), and [2612](https://eips.ethereum.org/EIPS/eip-2612) compliant.&#x20;

Users deposit the [IBT](https://dev.spectra.finance/glossary#ibt) (or underlying token of the IBT) and receive the Principal Token (PT) and the [Yield Token](https://dev.spectra.finance/glossary#yield-token) (YT) in return. For example, user deposits aDAI (or DAI) and receives the PT and YT of the aDAI position with a certain expiry.

The user can also [withdraw](#withdraw) and [redeem](#redeem) after and before expiry. For more information, see the [Tokenising Yield](https://dev.spectra.finance/guides/tokenizing-yield) guide.

Code for PrincipalToken.sol can be found on [GitHub](https://github.com/perspectivefi/spectra-core/blob/main/src/tokens/PrincipalToken.sol).

## Methods

### deposit

```solidity
function deposit(
    uint256 assets,
    address receiver
) public returns (uint256 shares)
```

Deposits the amount of the underlying `assets` (e.g. DAI or USDC etc) and mints an amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) and [Yield Tokens](https://dev.spectra.finance/glossary#yield-token) for the `receiver`.

{% hint style="warning" %}
`msg.sender` must approve the relevant allowance of the underlying asset before calling this method.
{% endhint %}

{% hint style="warning" %}
`deposit` must be called before the [`expiry`](#maturity) of the Principal Token.
{% endhint %}

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="115">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>assets</code></td><td>uint256</td><td><p>The amount of the underlying assets to deposit. </p><p>See also <a href="#asset"><code>asset()</code></a></p></td></tr><tr><td><code>receiver</code></td><td>address</td><td>The address that will receive the minted <a href="../../../glossary#principal-token">PT</a> and <a href="../../../glossary#yield-token">YT</a>.<br>Note: This can be different from <code>msg.sender</code> if depositing on behalf of another address.</td></tr></tbody></table>

<table><thead><tr><th width="189.33333333333331">Return Parameter</th><th width="121">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of shares (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) and <a href="../../../glossary#yield-token">Yield Tokens</a> that were minted for the <code>receiver</code>.</td></tr></tbody></table>

### deposit

```solidity
function deposit(
        uint256 assets,
        address ptReceiver,
        address ytReceiver
) external returns (uint256 shares);
```

Deposits amount of `assets` in the PT vault specifying the PT receiver (`ptReceiver`) and the YT receiver (`ytReceiver`).

{% hint style="warning" %}
`msg.sender` must approve the relevant allowance of the underlying asset before calling this method.
{% endhint %}

{% hint style="warning" %}
`deposit` must be called before the [`expiry`](#maturity) of the Principal Token.
{% endhint %}

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="115">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>assets</code></td><td>uint256</td><td><p>The amount of the underlying assets to deposit. </p><p>See also <a href="#asset"><code>asset()</code></a></p></td></tr><tr><td><code>ptReceiver</code></td><td>address</td><td>The address that will receive the minted <a href="../../../glossary#principal-token">PT</a><br>Note: This can be different from <code>msg.sender</code> if depositing on behalf of another address.</td></tr><tr><td><code>ytReceiver</code></td><td>address</td><td>The address that will receive the minted <a href="yield-token">YT</a><br>Note: This can be different from <code>msg.sender</code> if depositing on behalf of another address.</td></tr></tbody></table>

<table><thead><tr><th width="189.33333333333331">Return Parameter</th><th width="121">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of shares (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) and <a href="../../../glossary#yield-token">Yield Tokens</a> that were minted for the <code>receiver</code>.</td></tr></tbody></table>

### deposit

```solidity
function deposit(
    uint256 assets,
    address ptReceiver,
    address ytReceiver,
    uint256 minShares
) external returns (uint256 shares);
```

Deposits amount of `assets` with a lower bound on shares received (`minShares`).

{% hint style="warning" %}
`msg.sender` must approve the relevant allowance of the underlying asset before calling this method.
{% endhint %}

{% hint style="warning" %}
`deposit` must be called before the [`expiry`](#maturity) of the Principal Token.
{% endhint %}

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="115">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>assets</code></td><td>uint256</td><td><p>The amount of the underlying assets to deposit. </p><p>See also <a href="#asset"><code>asset()</code></a></p></td></tr><tr><td><code>ptReceiver</code></td><td>address</td><td>The address that will receive the minted <a href="../../../glossary#principal-token">PT</a><br>Note: This can be different from <code>msg.sender</code> if depositing on behalf of another address.</td></tr><tr><td><code>ytReceiver</code></td><td>address</td><td>The address that will receive the minted <a href="yield-token">YT</a><br>Note: This can be different from <code>msg.sender</code> if depositing on behalf of another address.</td></tr><tr><td><code>minShares</code></td><td>uint256</td><td>The minimum amount of shares the caller expect to receive from the posit</td></tr></tbody></table>

<table><thead><tr><th width="189.33333333333331">Return Parameter</th><th width="121">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of shares (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) and <a href="../../../glossary#yield-token">Yield Tokens</a> that were minted for the <code>receiver</code>.</td></tr></tbody></table>

### depositIBT

```solidity
function depositIBT(
    uint256 ibts,
    address receiver
) public returns (uint256 shares)
```

Deposits the `ibts` of the [Interest Bearing Token](https://dev.spectra.finance/glossary#ibt) (e.g. aDAI or aUSDC etc) and mints an amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) and [Yield Tokens](https://dev.spectra.finance/glossary#yield-token) for the `receiver`.

{% hint style="warning" %}
`msg.sender` must approve the relevant allowance of the IBT before calling this method.
{% endhint %}

{% hint style="warning" %}
`deposit` must be called before the [`expiry`](#maturity) of the Principal Token.
{% endhint %}

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>ibts</code></td><td>uint256</td><td><p>The amount of the PrincipalToken's IBT assets to deposit. </p><p>See also <a href="#getibt">getIBT()</a></p></td></tr><tr><td><code>receiver</code></td><td>address</td><td>The address that will receive the minted <a href="../../../glossary#principal-token">PT</a> and <a href="../../../glossary#yield-token">YT</a>.<br>Note: This can be different from <code>msg.sender</code> if depositing on behalf of another address.</td></tr></tbody></table>

<table><thead><tr><th width="197.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of shares (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) and <a href="../../../glossary#yield-token">Yield Tokens</a> that were minted for the <code>receiver</code>.</td></tr></tbody></table>

### depositIBT

```solidity
function depositIBT(
        uint256 ibts,
        address ptReceiver,
        address ytReceiver
) external returns (uint256 shares);
```

Deposits the `ibts` of the [Interest Bearing Token](https://dev.spectra.finance/glossary#ibt) (e.g. aDAI or aUSDC etc) and mints an amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) for the `ptReceiver` and [Yield Tokens](https://dev.spectra.finance/glossary#yield-token) for the `ytReceiver`.

{% hint style="warning" %}
`msg.sender` must approve the relevant allowance of the IBT before calling this method.
{% endhint %}

{% hint style="warning" %}
`deposit` must be called before the [`expiry`](#maturity) of the Principal Token.
{% endhint %}

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="115">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>ibts</code></td><td>uint256</td><td><p>The amount of the PrincipalToken's IBT assets to deposit. </p><p>See also <a href="#getibt">getIBT()</a></p></td></tr><tr><td><code>ptReceiver</code></td><td>address</td><td>The address that will receive the minted <a href="../../../glossary#principal-token">PT</a><br>Note: This can be different from <code>msg.sender</code> if depositing on behalf of another address.</td></tr><tr><td><code>ytReceiver</code></td><td>address</td><td>The address that will receive the minted <a href="yield-token">YT</a><br>Note: This can be different from <code>msg.sender</code> if depositing on behalf of another address.</td></tr></tbody></table>

<table><thead><tr><th width="189.33333333333331">Return Parameter</th><th width="121">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of shares (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) and <a href="../../../glossary#yield-token">Yield Tokens</a> that were minted for the <code>receiver</code>.</td></tr></tbody></table>

### depositIBT

```solidity
function depositIBT(
        uint256 ibts,
        address ptReceiver,
        address ytReceiver,
        uint256 minShares
) external returns (uint256 shares);
```

Deposits the `ibts` of the [Interest Bearing Token](https://dev.spectra.finance/glossary#ibt) (e.g. aDAI or aUSDC etc) and mints an amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) for the `ptReceiver` and [Yield Tokens](https://dev.spectra.finance/glossary#yield-token) for the `ytReceiver`.

{% hint style="warning" %}
`msg.sender` must approve the relevant allowance of the IBT before calling this method.
{% endhint %}

{% hint style="warning" %}
`deposit` must be called before the [`expiry`](#maturity) of the Principal Token.
{% endhint %}

<table><thead><tr><th width="190.33333333333331">Input Parameter</th><th width="115">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>ibts</code></td><td>uint256</td><td><p>The amount of the PrincipalToken's IBT assets to deposit. </p><p>See also <a href="#getibt">getIBT()</a></p></td></tr><tr><td><code>ptReceiver</code></td><td>address</td><td>The address that will receive the minted <a href="../../../glossary#principal-token">PT</a><br>Note: This can be different from <code>msg.sender</code> if depositing on behalf of another address.</td></tr><tr><td><code>ytReceiver</code></td><td>address</td><td>The address that will receive the minted <a href="yield-token">YT</a><br>Note: This can be different from <code>msg.sender</code> if depositing on behalf of another address.</td></tr><tr><td><code>minShares</code></td><td>uint256</td><td>The minimum amount of shares the caller expect to receive from the posit</td></tr></tbody></table>

<table><thead><tr><th width="189.33333333333331">Return Parameter</th><th width="121">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of shares (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) and <a href="../../../glossary#yield-token">Yield Tokens</a> that were minted for the <code>receiver</code>.</td></tr></tbody></table>

### redeem

```solidity
function redeem(
    uint256 shares,
    address receiver,
    address owner
) returns (uint256 assets)
```

Redeems (by burning tokens) the amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) from `owner`, redeeming an amount of `assets` of the underlying [asset](#asset).

{% hint style="warning" %}
The first caller to Redeem after expiry will make an implicit call to [`StoreRatesAtExpiry()`](#storeratesatexpiry)to store the rates after expiry. This is done only once for all.
{% endhint %}

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that the user wants to redeem/burn.</td></tr><tr><td><code>receiver</code></td><td>address</td><td>The address that will receive the redeemed <a href="#asset">assets</a>.</td></tr><tr><td><code>owner</code></td><td>address</td><td>The address of the owner of the <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that are to be redeemed.<br>This must be the same as <code>msg.sender</code>.</td></tr></tbody></table>

<table><thead><tr><th width="197.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>assets</code></td><td>uint256</td><td>The amount of underlying <a href="#asset">assets</a> that are redeemed.</td></tr></tbody></table>

*Conforms to* [*ERC-5095*](https://eips.ethereum.org/EIPS/eip-5095) *standards.*

### redeem

```solidity
function redeem(
        uint256 shares,
        address receiver,
        address owner,
        uint256 minAssets
) external returns (uint256 assets);
```

Redeems (by burning tokens) the amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) from `owner`, redeeming an amount of `assets` of the underlying [asset](#asset), while also specifying the minimum asset (`minAssets`) amount that the caller expects the `receiver` to receive.

I.e. converts PT to the underlying asset, using the number of PT to burn, after expiry.

{% hint style="warning" %}
The first caller to Redeem after expiry will make an implicit call to [`StoreRatesAtExpiry()`](#storeratesatexpiry)to store the rates after expiry. This is done only once for all.
{% endhint %}

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that the user wants to redeem/burn.</td></tr><tr><td><code>receiver</code></td><td>address</td><td>The address that will receive the redeemed <a href="#asset">assets</a>.</td></tr><tr><td><code>owner</code></td><td>address</td><td>The address of the owner of the <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that are to be redeemed.<br>This must be the same as <code>msg.sender</code>.</td></tr><tr><td><code>minAssets</code></td><td>uint256</td><td>The minimum asset amount that the caller expects the <code>receiver</code> to receive.</td></tr></tbody></table>

<table><thead><tr><th width="197.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>assets</code></td><td>uint256</td><td>The amount of underlying <a href="#asset">assets</a> that are redeemed.</td></tr></tbody></table>

### redeemForIBT

```solidity
function redeemForIBT(
    uint256 shares,
    address receiver,
    address owner
) returns (uint256 ibts)
```

Redeems (by burning tokens) the amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) from `owner`, redeeming an amount of `ibts` of the [IBT](https://dev.spectra.finance/glossary#ibt).

{% hint style="warning" %}
The first caller to Redeem after expiry will make an implicit call to [`StoreRatesAtExpiry()`](#storeratesatexpiry)to store the rates after expiry. This is done only once for all.
{% endhint %}

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that the user wants to redeem/burn.</td></tr><tr><td><code>receiver</code></td><td>address</td><td>The address that will receive the redeemed tokens.</td></tr><tr><td><code>owner</code></td><td>address</td><td>The address of the owner of the <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that are to be redeemed.<br>This must be the same as <code>msg.sender</code>.</td></tr></tbody></table>

<table><thead><tr><th width="197.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>ibts</code></td><td>uint256</td><td>The amount of <a href="../../../glossary#ibt">IBT</a>s that are redeemed.</td></tr></tbody></table>

### redeemForIBT

```solidity
function redeemForIBT(
        uint256 shares,
        address receiver,
        address owner,
        uint256 minIbts
) external returns (uint256 ibts);
```

Redeems (by burning tokens) the amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) from `owner`, redeeming an amount of `ibts` of the [IBT](https://dev.spectra.finance/glossary#ibt), while also specifying the minimum asset (`minIbts`) amount that the caller expects the `receiver` to receive.

{% hint style="warning" %}
The first caller to Redeem after expiry will make an implicit call to [`StoreRatesAtExpiry()`](#storeratesatexpiry)to store the rates after expiry. This is done only once for all.
{% endhint %}

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that the user wants to redeem/burn.</td></tr><tr><td><code>receiver</code></td><td>address</td><td>The address that will receive the redeemed tokens.</td></tr><tr><td><code>owner</code></td><td>address</td><td>The address of the owner of the <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that are to be redeemed.<br>This must be the same as <code>msg.sender</code>.</td></tr><tr><td><code>minIbts</code></td><td>uint256</td><td>The minimum asset amount that the caller expects the <code>receiver</code> to receive.</td></tr></tbody></table>

<table><thead><tr><th width="197.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>ibts</code></td><td>uint256</td><td>The amount of <a href="../../../glossary#ibt">IBT</a>s that are redeemed.</td></tr></tbody></table>

### withdraw

```solidity
function withdraw(
    uint256 assets,
    address receiver,
    address owner
) returns (uint256 shares)
```

Withdraws the amount of underlying `assets` of a position of `owner`, withdrawing those `assets` to `receiver`.  This is done by burning `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) and remaining [Yield Tokens](https://dev.spectra.finance/glossary#yield-token) of `owner`.

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>assets</code></td><td>uint256</td><td>The amount of <a href="#asset">assets</a> that the user wants to withdraw.</td></tr><tr><td><code>receiver</code></td><td>address</td><td>The address that will receive the redeemed <a href="#asset">assets</a>.</td></tr><tr><td><code>owner</code></td><td>address</td><td>The address of the owner of the <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that are to be withdrawn/burned.<br>This must be the same as <code>msg.sender</code>.</td></tr></tbody></table>

<table><thead><tr><th width="197.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of the <code>owner</code> shares (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that were burned from the withdrawal.</td></tr></tbody></table>

*Conforms to* [*ERC-5095*](https://eips.ethereum.org/EIPS/eip-5095) *standards.*

### withdraw

```solidity
function withdraw(
        uint256 assets,
        address receiver,
        address owner,
        uint256 maxShares
) external returns (uint256 shares)
```

Withdraws the amount of underlying `assets` of a position of `owner`, withdrawing those `assets` to `receiver`.  This is done by burning `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) and remaining [Yield Tokens](https://dev.spectra.finance/glossary#yield-token) of `owner`, while specifying the maximum amount (`maxShares`) of shares to withdraw.

I.e. converts PT and YT to the underlying asset, using the number of underlying assets to withdraw, before expiry.

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>assets</code></td><td>uint256</td><td>The amount of <a href="#asset">assets</a> that the user wants to withdraw.</td></tr><tr><td><code>receiver</code></td><td>address</td><td>The address that will receive the redeemed <a href="#asset">assets</a>.</td></tr><tr><td><code>owner</code></td><td>address</td><td>The address of the owner of the <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that are to be withdrawn/burned.<br>This must be the same as <code>msg.sender</code>.</td></tr><tr><td><code>maxShares</code></td><td>uint256</td><td>The maximum amount of shares allowed to be burnt</td></tr></tbody></table>

<table><thead><tr><th width="197.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of the <code>owner</code> shares (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that were burned from the withdrawal.</td></tr></tbody></table>

### withdrawIBT

```solidity
function withdrawIBT(
    uint256 ibts,
    address receiver,
    address owner
) returns (uint256 shares)
```

Withdraws the amount of [IBT](https://dev.spectra.finance/glossary#ibt)s of a position of `owner`, withdrawing those `ibts` to `receiver`.  This is done by burning `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) and remaining [Yield Tokens](https://dev.spectra.finance/glossary#yield-token) of `owner`.

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>ibts</code></td><td>uint256</td><td>The amount of <a href="../../../glossary#ibt">IBT</a>s that the user wants to withdraw.</td></tr><tr><td><code>receiver</code></td><td>address</td><td>The address that will receive the withdrawn tokens.</td></tr><tr><td><code>owner</code></td><td>address</td><td>The address of the owner of the <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that are to be withdrawn/burned.<br>This must be the same as <code>msg.sender</code>.</td></tr></tbody></table>

<table><thead><tr><th width="197.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of the <code>owner</code> shares (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that were burned from the withdrawal.</td></tr></tbody></table>

### withdrawIBT

```solidity
function withdrawIBT(
        uint256 ibts,
        address receiver,
        address owner,
        uint256 maxShares
) external returns (uint256 shares)
```

Withdraws the amount of [IBT](https://dev.spectra.finance/glossary#ibt)s of a position of `owner`, withdrawing those `ibts` to `receiver`.  This is done by burning `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) and remaining [Yield Tokens](https://dev.spectra.finance/glossary#yield-token) of `owner`, while specifying the maximum amount (`maxShares`) of shares to withdraw.

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>ibts</code></td><td>uint256</td><td>The amount of <a href="../../../glossary#ibt">IBT</a>s that the user wants to withdraw.</td></tr><tr><td><code>receiver</code></td><td>address</td><td>The address that will receive the withdrawn tokens.</td></tr><tr><td><code>owner</code></td><td>address</td><td>The address of the owner of the <code>shares</code> (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that are to be withdrawn/burned.<br>This must be the same as <code>msg.sender</code>.</td></tr><tr><td><code>maxShares</code></td><td>uint256</td><td>The maximum amount of shares allowed to be burnt</td></tr></tbody></table>

<table><thead><tr><th width="197.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>shares</code></td><td>uint256</td><td>The amount of the <code>owner</code> shares (i.e. <a href="../../../glossary#principal-token">Principal Tokens</a>) that were burned from the withdrawal.</td></tr></tbody></table>

### claimYield

```solidity
function claimYield(address _receiver) public returns (uint256)
```

Claims the yield of `msg.sender` based on their current balance of YT. Send the yield as underlying tokens.

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>_receiver</code></td><td>address</td><td>The address that will receive the yield.</td></tr></tbody></table>

<table><thead><tr><th width="214.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>yieldInAsset</code></td><td>uint256</td><td>The amount of yield claimed in the underlying <a href="#asset">asset</a>.</td></tr></tbody></table>

### claimYieldInIBT

```solidity
function claimYieldInIBT(address _receiver) public returns (uint256)
```

Claims the yield of `msg.sender` based on their current balance of YT. Send the yield as [IBT](https://dev.spectra.finance/glossary#ibt) tokens.

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>_receiver</code></td><td>address</td><td>The address that will receive the yield.</td></tr></tbody></table>

<table><thead><tr><th width="214.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>yieldInIBT</code></td><td>uint256</td><td>The amount of yield claimed (in <a href="../../../glossary#ibt">IBT</a>).</td></tr></tbody></table>

### updateYield

```solidity
function updateYield(address _user) external returns (uint256 updatedUserYieldInRay)
```

Updates `_user` yield with the latest yield in IBT generated since the previous update.&#x20;

{% hint style="info" %}
This method should not be used by users. This method is called implicitely before each action to deposit, redeem, withdraw and sending receiving YT tokens.
{% endhint %}

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="124">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>_user</code></td><td>address</td><td>The address of the user to compute the yield</td></tr></tbody></table>

<table><thead><tr><th width="274.3333333333333">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>updatedUserYieldInRay</code></td><td>uint256</td><td>The unclaimed yield (amount of <a href="../../../glossary#ibt">IBT</a> tokens) of the <code>_user</code> in Ray decimals. The user can get this yield by calling <a href="#claimyield"><code>claimYield()</code></a> .</td></tr></tbody></table>

### flashLoan

```solidity
function flashLoan(
        IERC3156FlashBorrower _receiver,
        address _token,
        uint256 _amount,
        bytes calldata _data
    ) external override returns (bool)
```

The flashLoan method is used to swap PT for YT tokens by borrowing the IBT of the PT contract to swap PT for YTs.

{% hint style="warning" %}
The transaction reverts if the trade is not profitable and the borrower is unable to repay the loan.
{% endhint %}

<table><thead><tr><th width="195.33333333333331">Input Parameter</th><th width="227">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>_receiver</code></td><td>IERC3156FlashBorrower</td><td>The receiver of the tokens in the loan, and the receiver of the callback.</td></tr><tr><td><code>_token</code></td><td>address</td><td>The loan currency.</td></tr><tr><td><code>_amount</code></td><td>uint256</td><td>The amount of tokens lent.</td></tr><tr><td><code>_data</code></td><td>bytes calldata</td><td>Arbitrary data structure, intended to contain user-defined parameters.</td></tr></tbody></table>

<table><thead><tr><th width="214.33333333333331">Return Parameter</th><th width="125">Type</th><th>Description</th></tr></thead><tbody><tr><td></td><td>bool</td><td>If successful, <code>flashLoan</code> return <code>true</code>.</td></tr></tbody></table>

*Conforms to* [*EIP-3156*](https://eips.ethereum.org/EIPS/eip-3156) *standards.*

### StoreRatesAtExpiry

Store the rates at the time of expiry.&#x20;

{% hint style="warning" %}
This can only be called **after** [expiry](#maturity)[/maturity](#maturity) of the position.&#x20;
{% endhint %}

```solidity
function storeRatesAtExpiry() external
```

## View Methods

### previewDeposit

```solidity
function previewDeposit(uint256 assets) public view returns (uint256)
```

Calculates the amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) and [Yield Tokens](https://dev.spectra.finance/glossary#yield-token) that would be minted for [depositing](#deposit) amount of `assets.`Only available if position is not [expired/reached maturity.](#maturity)

### maxDeposit

```solidity
function maxDeposit(address) public view returns (uint256)
```

This function returns the maximum amount of underlying assets that can be deposited in a single [`deposit`](#deposit) call by the `receiver`.

### previewDepositIBT

```solidity
function previewDepositIBT(uint256 ibts) public view returns (uint256)
```

Calculates the amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) and [Yield Tokens](https://dev.spectra.finance/glossary#yield-token) that would be minted for [depositing](#deposit) amount of `ibts.`Only available if position is not [expired/reached maturity.](#maturity)

### previewWithdraw

```solidity
function previewWithdraw(uint256 assets) public view returns (uint256)
```

Calculates the amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) that would be burned for [withdrawing](#withdraw) an amount of `assets`.

*Conforms to* [*ERC-5095*](https://eips.ethereum.org/EIPS/eip-5095) *standards.*

### previewWithdrawIBT

```solidity
function previewWithdrawInIBT(uint256 ibts) public view returns (uint256)
```

Calculates the amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) that would be burned for [withdrawing](#withdraw) an amount of `ibts`.

### maxWithdraw

```solidity
function maxWithdraw(address owner) public returns (uint256)
```

Calculates the maximum amount of underlying [assets](#asset) that can [withdrawn](#withdraw) by the `owner`.

*Conforms to* [*ERC-5095*](https://eips.ethereum.org/EIPS/eip-5095) *standards.*

### maxWithdrawIBT

```solidity
function maxWithdraw(address owner) public returns (uint256)
```

Calculates the maximum amount of [IBT](https://dev.spectra.finance/glossary#ibt)s that can [withdrawn](#withdraw) by the `owner`.

### previewRedeem

```solidity
function previewRedeem(uint256 shares) public view returns (uint256)
```

Calculates the amount of [assets](#asset) that would be [redeemed](#redeem) for an amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)).

*Conforms to* [*ERC-5095*](https://eips.ethereum.org/EIPS/eip-5095) *standards.*

### previewRedeemForIBT

```solidity
function previewRedeemForIBT(uint256 shares) public view returns (uint256)
```

Calculates the amount of IBTs that would be [redeemed](#redeem) for an amount of `shares` (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)).

### maxRedeem

```solidity
function maxRedeem(address owner) public view returns (uint256)
```

Calculations the maximum amount of shares (i.e. [Principal Tokens](https://dev.spectra.finance/glossary#principal-token)) that the `owner` can currently [redeem](#redeem)/burn.

*Conforms to* [*ERC-5095*](https://eips.ethereum.org/EIPS/eip-5095) *standards.*

### convertToPrincipal

```solidity
function convertToPrincipal(uint256 underlyingAmount) public view returns (uint256 principalAmount)
```

Calculates the amount of principal tokens that are equivalent to the amount of `underlyingAmount`.&#x20;

*Conforms to* [*EIP-5095*](https://eips.ethereum.org/EIPS/eip-5095) *standard.*

### convertToUnderlying

```solidity
function convertToUnderlying(uint256 principalAmount) public view returns (uint256)
```

Same as [`convertToAssets()`](#converttoassets).

*Conforms to* [*ERC-5095*](https://eips.ethereum.org/EIPS/eip-5095) *standard.*

### underlying

```solidity
function underlying() public view virtual override returns (address)
```

Returns the address of the underlying ERC20 or ERC777 asset.&#x20;

E.g. if the IBT is aDAI, then the asset is DAI. If the IBT is cUSDC, then the asset is USDC.

*Conforms to* [*ERC-5095*](https://eips.ethereum.org/EIPS/eip-5095) *standard.*

### totalAssets

```solidity
function totalAssets() public view virtual override returns (uint256)
```

Returns the total balance of the underlying assets in the [Principal Token](https://dev.spectra.finance/glossary#principal-token). Useful for TVL calculations.

### decimals

```solidity
function decimals() public view returns (uint8)
```

Returns the decimals of the [IBT](#ibt).

### maturity

```solidity
function maturity() public view returns (uint256)
```

Returns the expiry/maturity of the position in unix timestamp, at or after which the [Principal Tokens](https://dev.spectra.finance/glossary#principal-token) can be redeemed for their underlying [asset](#asset).

*Conforms to* [*ERC-5095*](https://eips.ethereum.org/EIPS/eip-5095) *standard.*

### getDuration

```solidity
function getDuration() public view returns (uint256)
```

Returns the total duration of the principal token period in seconds.

### getIBT

```solidity
function getIBT() public view returns (address)
```

Returns the address of the IBT ([Interest Bearing Token](https://dev.spectra.finance/glossary#ibt)).

E.g. if the underlying asset is DAI, the IBT could be aDAI (for Aave deposited DAI) or cDAI (for Compound deposited DAI), etc.

### getYT

```solidity
function getYT() public view returns (address)
```

Returns the address of the YT ([Yield Token](https://dev.spectra.finance/glossary#yield-token)).

### getIBTRate

```solidity
function getIBTRate() public view returns (uint256)
```

Returns the ibtRate.

### getPTRate

```solidity
function getPTRate() public view returns (uint256)
```

Returns the ptRate.

### getIBTUnit

```solidity
function getIBTUnit() public view returns (uint256)
```

Returns the number used for one unit (10^decimals) of the [IBT](#ibt).

### getAssetUnit

```solidity
function getAssetUnit() public view returns (uint256)
```

Returns the number used for one unit (10^decimals) of the [asset](#asset).

### getIBTRateAtExpiry

```solidity
function getIBTRateAtExpiry() public view returns (uint256)
```

Returns the IBT rate at expiry. Only valid after [maturity](#maturity).

### getPTRateAtExpiry

```solidity
function getPTRateAtExpiry() public view returns (uint256)
```

Returns the PT rate at expiry. Only valid after [maturity](#maturity).

### getCurrentYieldOfUserInIBT

```solidity
function getCurrentYieldOfUserInIBT(address _user) public view returns (uint256 _yieldOfUserInIBT)
```

Returns the yield of `_user` in [IBT](https://dev.spectra.finance/glossary#ibt) tokens.

## Internal Methods

### \_computeYield

```solidity
function _computeYield(
    address _user,
    uint256 _oldIBTRate,
    uint256 _ibtRate,
    uint256 _oldPTRate,
    uint256 _ptRate
) internal view returns (uint256)
```

Computes the yield generated by a user given old and new rates. For more information, see the [Yield Calculations](https://dev.spectra.finance/technical-reference/yield-calculations) page.
