# Introduction to Port Finance

Port Finance is a non-custodial money market protocol on Solana. Its goals are to bring a whole suite of interest rate product including: variable rate lending, fixed rate lending and interest rate swap to the Solana blockchain.

The current variable rate product features variable interest rates based on supply & demand, cross collateral lending, and flash loans.

The fixed-rate lending product uses the model of zero coupon bond. We allow lender to lend at a fixed rate and allow borrower to take on fixed-rate, fixed-term loan.

Port Finance seeks to be the liquidity gateway for the Solana DeFi ecosystem through simpler user interfaces, lower collateral requirements, and adjustable liquidation thresholds based on volatility and liquidity.&#x20;

Port’s native token will enable users to participate in governance and share in protocol fees derived from all protocol products.&#x20;


# Deposit and withdrawal

A step by step guide on how to use Port Finance.

1\) Head over to our website at <https://port.finance/> (make sure you bookmark the link to fend off against phishing scams.\
\
![](https://lh6.googleusercontent.com/98NHJ9E-oxA1-VdSM7GOKZBWyqZAV48J1xQjlCKStLfV2Kdn6Kq6bm3nAkigRjDNM1_SVVmMXeDd5fdpJdVMFqL0CZsxDD4awAXW6OzFG8g5q4tyquZoO_XrYKU6gGElWGp_KG1KUgFWT0dbGw)\
2\) Click on “APP” on the top right corner of the screen and connect your wallet to our site. There are quite a few wallets that you can choose from, it all works fine. I personally recommend using phantom. Phantom has one of the smoothest UI and it is super easy to navigate around it with a page solely for your NFTs as well.<br>

Link to Phantom download: <https://phantom.app/> (make sure you bookmark the link to fend off against phishing scams.

Once you are connected you will be directed to our main page.\
![](https://2642926184-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MaBnhYO5U0xRgxJs7vp%2Fuploads%2FxDaVlbUvEwHGo2UogdW5%2Fimage.png?alt=media\&token=22adede3-4501-4d90-92b8-eca919b8c8f4)\
Before any transactions are done, make sure to have at least 0.1 SOL in your wallet for approvals of transactions. You will not utilize the entire 0.1 sol for 1 transaction so not to worry.\
\
**Deposit & Withdrawals**

Select the asset that you will want to deposit on our platform. Click on deposit.\
![](https://2642926184-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MaBnhYO5U0xRgxJs7vp%2Fuploads%2FsIuX3T7WA9aXpsQQi5SJ%2Fimage.png?alt=media\&token=db787e7f-21ba-4962-ad1b-c37e93d3fbb3)\
You will be redirected to our deposit page, select the amount you would want to deposit, click on confirm and approve the transaction on the pop up wallet.\
![](https://2642926184-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MaBnhYO5U0xRgxJs7vp%2Fuploads%2FlfuETnPZcMJN9U94iYu1%2Fimage.png?alt=media\&token=c69b33e8-df89-410a-a425-2b314126d6f2)\
Once approved, you are done! Congratulations on making your first deposit!

For withdrawals, it is the total opposite of process. Under the asset that you have deposited, click on withdraw, select how much you would want to withdraw and approve it. Done deal!


# Borrow

A step by step guide on how to use Port Finance.

Before you are able to borrow, you will firstly have to deposit your tokens and use that asset as your collateral to borrow.\
![](https://2642926184-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MaBnhYO5U0xRgxJs7vp%2Fuploads%2F6bkvtodxfYcS7KGxGGCu%2Fport%20borrow.jpg?alt=media\&token=333076f4-597e-4e5b-be6c-b6cb410608ca)\
Make sure you click and switch on so that you will be able to use it as a collateral to borrow.\
![](https://2642926184-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MaBnhYO5U0xRgxJs7vp%2Fuploads%2FCuPpdvJU6ghSC3gxw0D4%2Fimage.png?alt=media\&token=51df8232-89a7-4d38-b572-2126af90983d)\
Once you are done, head over to the borrow tab and determine how much you would want to borrow. Before you borrow, understand the risks behind borrowing, take note of your risk factor as well as your liquidation LTV before borrowing.\
\
Once you have fully understood it, proceed to selection of how much you will want to borrow and confirm,\
\
You will then need to approve and confirm the transaction on your wallet and you are good to go!


# Terminologies

Introduce the users to some of the terminologies in the port finance

For each assets that Port Finance supports, it has the following parameters:

* **Loan to Value Ratio**: the max ratio between loan to collateral that the users are allowed to borrow
* **Liquidation Threshold**: the ratio between loan to collateral at which the collateral can be bought by liquidator at a discount
* **Liquidation Bonus**: the discount at which the liquidator can come in and buy the collateral
* **Borrow Fee**: the fee that is changed to the protocol
* **Flash Loan Fee**: the fee percentage that is charged for flash loan

For each wallet they have the following statistics:

* **Total borrowing power**: the total monetary value in USD that the users are allowed to borrowed
* **Risk factor**: represents the safety of the your deposited asset against borrowed assets, the higher the risk factor the riskier is your loan. When the risk factor reaches 100%, your loan will be liquidated.
* **Loan to Value ratio**: the ratio of how much users have borrowed compared to their deposited asset

Concretely, the above statistics are calculated as followed:

$$
Total BorrowPower
\= \Sigma\_{collateral} LTV\_{collateral} \* MarketValue\_{collateral}
$$

$$
RiskFactor = \frac{ \Sigma\_{borrow}  MarketValue\_{borrow}}{ \Sigma\_{collateral} LiquidationThreshold\_{collateral} \* MarketValue\_{collateral}}
$$

$$
LTV = \frac{\Sigma\_{borrow}  MarketValue\_{borrow}}{\Sigma\_{collateral} LTV\_{collateral} \* MarketValue\_{collateral}}
$$


# Protocol Math

The Port Finance protocol represents the number as mantissa, an unsigned integer divided by 10 ^ 18. That is the raw representation of 1 is actually 1 \* 10 ^ (-18). All the calculation that is related to deposit, withdraw, borrow and repay is calculated using this system.


# Risks & Parameters

We want to remind our users that there are many risks when using Defi products, our team will try our best to mitigate these risks. However, humans err. So do make sure that you are aware of the risks associated.

The risks involves using our protocols includes:

* Port Finance Contract Risk: we try our best to write safe code and we do internal and external code review as well as audits by reputable auditing firm. However, we do want to remind our users that issue could arise
* Oracle Risk: we choose Pyth Oracle as our providers. They are backed by some of the most reputable trading firms. However, there could still be risk of an inaccurate or wrong price data is feed into our lending products
* Underlying Asset Risk: we support some synthetic assets or asset issued by other protocols. We are very selective when listing new assets and we make sure the contracts are audited and also the team is trustworthy. We still want to remind our users that in the unfortunate event, that these synthetic assets greatly depreciate in value, protocol users might suffer loss.

We choose the below risk parameters of the asset with the above risks in mind:

| Asset | LTV | Liquidation Threshold | Liquidation Bonus | Optimal Utilisation | Optimal Interest Rate | Highest Interest Rate |
| ----- | --- | --------------------- | ----------------- | ------------------- | --------------------- | --------------------- |
| USDC  | 85% | 90%                   | 3%                | 80%                 | 8%                    | 80%                   |
| USDT  | 85% | 90%                   | 3%                | 80%                 | 8%                    | 60%                   |
| SOL   | 80% | 85%                   | 6%                | 65%                 | 12%                   | 120%                  |
| MER   | 50% | 55%                   | 10%               | 55%                 | 10%                   | 250%                  |
| mSOL  | 70% | 75%                   | 10%               | 65%                 | 12%                   | 120%                  |
| pSOL  | 60% | 65%                   | 15%               | 65%                 | 12%                   | 120%                  |

#### Loan To Value (LTV):&#x20;

LTV is the ratio between the maximum allowed borrow value and the collateral value.&#x20;

Concretely, say that a user deposit 100 USD worth of SOL, according to the currently LTV of 85% for Solana the users are able to borrow up to 85 USD worth of assets

#### Liquidation Threshold:&#x20;

Liquidation threshold is the ratio between borrow amount and the collateral value at which the users are subject to liquidation.

Concretely, say that a user deposit 100 USD worth of SOL and borrow 85 USD worth of assets, according to the currently liquidation threshold of 90%, the user is subject to liquidation if the value of the assets that they borrow has increased 90 USD.

#### Liquidation Bonus

Liquidation bonus is the **extra** amount of collateral that the liquidator will get for taking the risk of liquidating the users.

As an example, if the user has put in 100 USD worth of SOL and borrow 85 USD. If the value of the borrowed asset has reached 90 USD. The liquidator can comes in and pay 50 USD worth of SOL and it will be able to get back 50 \* (1 + 2%) =  51 USD worth of SOL.

&#x20;


# Fees

We charge two fees:

* borrow fee
* flash loan fee

50% of the fee goes to buy and burn the $PORT token, 50% goes to insurance fund.

The exact borrow and flash loan fee can be found in the app.


# Interest Rate Curve

Port Finance uses Aave's interest rate model where the rate is determined by the utilization of the protocol. It employs a two segment interest rate model, where the second slope is steeper than the first to incentivize more depositing when utilization ratio is high.

Mathematically, we use the following interest rate model:

$$
U < U\_{optimal}: R\_{curr} = R\_{0}  + \frac{U\_{t}}{U\_{optimal}} R\_{slope1}
$$

$$
U \geq U\_{optimal}: R\_{t} = R\_{0} + R\_{slope1} + \frac{U\_{t} - U\_{optimal}}{1 - U\_{optimal}} R\_{slope2}
$$

When U < U Optimal, the rate increases slowly with utilization.

When U >= U Optimal the borrow interest rate increases sharply to incentivizes more deposit and avoid liquidity risk.


# Liquidation

Liquidation occurs when a user's total borrow has reached a threshold, i.e. the risk factor is greater than or equal to 100%.

$$
RiskFactor = \frac{ \Sigma\_{borrow}  MarketValue\_{borrow}}{ \Sigma\_{collateral} LiquidationThreshold\_{collateral} \* MarketValue\_{collateral}}
$$

Risk factor represents the overall liquidation risk for a given users. When the users add more collateral into the protocol, the risk reduces. Conversely when the users borrow more, the risk increases.

When a user has reached its liquidation threshold, up to 50% (in terms of market value) of the total borrowed asset is sold to the liquidator at a discounted price to repay a portion of the loan.&#x20;


# Principal Tokens and Yield Tokens

We have introduced a new program which tokenizes the position deposited into our variable rate lending program into principal tokens and yield tokens.

* **Principal Tokens**: maps one-to-one to the underlying token
* **Yield Tokens**: maps to the actual yield of the underlying protocols over the period
* **Maturity:** the time after which users are allowed to perform the redemption

In order to make the yield token fungible with each other, we reduce the amount of principal tokens released when minting to take into account the interest that've already accrued to make sure that the yield tokens are fungible.<br>

For example, when users deposit 1000 USDC, they might receive 999 principal USDC and 1000 yield USDC. This will happen when the interest between pools starts at the moment that the user deposit is already 0.1%. At this point, we are sure that the 1000 yield token can redeem for 1 USDC. Adding up with 999 principle USDC which can be redeemed for 999 USDC, this adds up to 1000 USDC. If we don't do this reduction, then the yield token will not be fungible.

#### Fixed-Rate Lending & Borrowing

Using Principal tokens we can implement fixed-rate borrowing and lending using a zero-coupon bond model since principal tokens can always be redeemed one to one to the underlying.

Users can trade principal tokens in various DEX. The seller of the principal tokens can be considered a borrower while the buyers can be considered a lender. The lender buys the principal tokens (e.g. USDC) using underlying tokens (e.g. ppUSDC). The borrower buys the underlying tokens (e.g. USDC) using the principal tokens (ppUSDC).

Due to the time value of money, 1 principal token should always be traded at less than 1 underlying token. Concretely, 1 principal USDC should be traded at less than 1 USDC.

The interest rate of lending and borrowing can be calculated as:

Interest Paid = the difference between the Principal USDC price and 1

Say 1 Principal USDC (ppUSDC) is traded at 0.95 USDC. Then the interest that the lender is going to receive or borrower is going to pay is (1 - 0.95) = 0.05 USDC. Users can then annualize it to calculate the APY.


# Arbitrage Opportunities

**Arbitrage Opportunities for Principal USDC**&#x20;

Sometimes you might see that the fixed rate APY is negative, this means great arbitrage opportunities! A negative APY means that ppUSDC is trading at a price that is more expensive than USDC. However, since that ppUSDC only allows the holders to redeem USDC at the end of maturity, considering its time value it shouldn’t be priced like this.

One can take this opportunity by minting ppUSDC and pyUSDC in the “Mint” Tab. And then sell the ppUSDC for USDC using Atrix, while still keeping their pyUSDC(which is the interest)!

**Arbitrage Opportunities for Yield USDC**&#x20;

Suppose that pyUSDC is traded at 0.01 USDC, assuming a 90 day maturity implies a 1 % \* 90 (days) / 365 (days per year) = 24.6% APY. And if you believe that the current variable APY is **unlikely** to be this high, you can sell your yield token for USDC and gain some profits.


# Principal Token Trading Venues

We created markets on Serum to allow users to trade the principal tokens. The serum market is configured as followed:

* Minimum Order Size: 0.01
* Tick Size: 0.0001
* Base token: Principal Tokens
* Quote token: Yield bearing tokens from Port Finance such as pUSDC, pUSDT, etc.

USDC July 2022 Sundial

Sundial Key: `5HHuVfysqPhdexQXRVcJnoAGSocZfXWv4MHFTua2FHAW`\
Serum: `skGujYm3UcaPuxewpaWx8oG6ZqRssPZcxhkKbUpAsdh`\
Atrix: `FdgieZWCLHrHwneV4wsmNqgRUNNdRKjmXUGUGb2b9LCs`\
Principal Mint: `7AfuD3nqZEJSF7oaQgEPmeo7zJi1n8Dh7BedYtgRugFk`\
Yield Mint: `4Fo8dh9kHn7WGxPy3MdhaBXLjY5DYStbRPwZudCTo5W4`

USDC October 2022 Sundial

Sundial Key: `5HHuVfysqPhdexQXRVcJnoAGSocZfXWv4MHFTua2FHAW`\
Serum: `GLSZpnUZ6z1SgoyKS37EM4tQGEGo5dTNEz5yfUMx5R77`\
Atrix: `ALmfhDPnuMx1PGDqfkXvq2JcEmDkdWj4UspbJV3HBcHL`\
Principal Mint: `2h2AVtKGd1zqfsP3GmL9u5kmVdLSRh7rW6Q6zFtkYx1R`\
Yield Mint: `2tbmTYoKeYebWXqox3UG3ASbT8ybnALikSVHLj3fgkjk`


# Bug Bounty

Bug bounty for Port Finance.

![](https://2642926184-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MaBnhYO5U0xRgxJs7vp%2F-MeOFxpKPBmXXQXc0cXZ%2F-MeOGxUeTBJY3Gansgvg%2FIMG_5730.PNG?alt=media\&token=b4bf65fd-bcda-44b6-a3c0-c022e6901e38)

Welcome to Port Finance’s Bug Bounty Program. We want Port Finance to be as secure as it can be, so we're calling on our community to help us find any bugs and vulnerabilities. Submit a bug to **<bug@port.finance>** and earn rewards of up to $100,000 USD.

Please see below our program details and rules for reporting a bug!

## Bug Bounty Program Details

Rewards for Bug Bounties will be assessed based on an internal rated scale

* Critical: Up to $100,000
* High: Up to $10,000
* Medium: Up to $1,000
* Low: Up to $250

## Bug Bounty Rules

* Public disclosure of a vulnerability would make it ineligible for a reward
* Duplicated issues are not eligible for rewar&#x64;*,* only the first submission will be eligible
* Rewards will be distributed at the full discretion of the Port Finance team based on the criteria
* Discovered vulnerability of the bug must be reported only to the Port Finance team via email to **<bug@port.finance>**
* For UI related issues and feature request please report using Github Issues [here](https://github.com/port-finance/bug-bounty) for best response time and prize distribution

## Suggested Bug Bounty Report Template

*Name:*

*Discord ID:*

*SPL Wallet Address:*

*Description:*

*Vulnerability:*

*Components that are affected:*

*Any other details:*

*(Attach any relevant screenshots or documentation)*<br>


# Developer Resources

A list of resources for developers to interact with Port Finance Program

To improve the developer productivity, we have released several Rust crates (including handy CPI crate for [Anchor](https://github.com/project-serum/anchor) program) and Typescript SDK.

* [**Port Finance Anchor CPI Crate**](https://crates.io/crates/port-anchor-adaptor): Anchor CPI Instructions for Interacting with Port Finance Program
* [**Port Finance Typescript SDK**](https://github.com/port-finance/port-sdk): A Typescript SDK for fetching and parsing Port Finance related on-chain accounts
* [**Port Finance Variable Rate Lending Instructions**](https://crates.io/crates/port-variable-rate-lending-instructions): A crate that helps users interact with Port Finance variable rate lending program
* [**Port Finance Staking Instructions**](https://crates.io/crates/port-finance-staking-instructions): A crate that help users interact with Port Finance liquidity mining program
* [**Solana Maths Utilities**](https://crates.io/crates/solana-maths): Math crate for preserving precision of token amounts
* [**Port Finance Statistics Typescript SDK**](https://www.npmjs.com/package/@port.finance/port-stats): A Typescript SDK for fetching the on-chain statistics for Port Finance
* **Restful API for checking all the reserve parameters**: <https://api-v1.port.finance/reserves>
* **Restful API for checking all the staking pool parameters**: <https://api-v1.port.finance/activeStakingPools>

Our developer team is happy to provide help with integration or directly contributing code to integrate with Port Finance. Submit the grant application by emailing: **<hello@port.finance>** or reach us through our [Discord Channel](https://t.co/klocNVKHmW?amp=1).


# Interacting with Port Finance via Rust

We have two crates for interacting with Port Finance program via Rust:&#x20;

{% embed url="<https://crates.io/crates/port-variable-rate-lending-instructions>" %}

{% embed url="<https://crates.io/crates/port-finance-staking-instructions>" %}

## Token-lending program

A lending protocol for the Token program on the Solana blockchain inspired by Aave and Compound.

## Public Keys for Port Finance

### Mainnet

Lending Market: `6T4XxKerq744sSuj3jaoV6QiZ8acirf4TrPwQzHAoSy5` Lending program id: `port_variable_rate_lending_instructions::id()` Staking program id: `port_staking_instructions::id()`

#### Reserve Public Keys

| Asset Name |                              Reserve Address |
| ---------- | -------------------------------------------: |
| SOL        |  X9ByyhmtQH3Wjku9N5obPy54DbVjZV7Z99TPJZ2rwcs |
| USDC       | DcENuKuYd6BWGhKfGr7eARxodqG12Bz1sN5WA8NwvLRx |
| USDT       | 4tqY9Hv7e8YhNQXuH75WKrZ7tTckbv2GfFVxmVcScW5s |
| PAI        | DSw99gXoGzvc4N7cNGU7TJ9bCWFq96NU2Cczi1TabDx2 |
| SRM        |  ZgS3sv1tJAor2rbGMFLeJwxsEGDiHkcrR2ZaNHZUpyF |
| BTC        | DSST29PMCVkxo8cf5ht9LxrPoMc8jAZt98t6nuJywz8p |
| MER        | BnhsmYVvNjXK3TGDHLj1Yr1jBGCmD1gZMkAyCwoXsHwt |
| mSOL       | 9gDF5W94RowoDugxT8cM29cX8pKKQitTp2uYVrarBSQ7 |
| pSOL       | GRJyCEezbZQibAEfBKCRAg5YoTPP2UcRSTC7RfzoMypy |
| SBR        | 7dXHPrJtwBjQqU1pLKfkHbq9TjQAK9jTms3rnj1i3G77 |

You can get all the information below by parsing the reserve data. We provide the account data here for your convenience.

#### pToken Mint

| Asset Name |                                  pToken Mint |
| ---------- | -------------------------------------------: |
| SOL        | 8ezDtNNhX91t1NbSLe8xV2PcCEfoQjEm2qDVGjt3rjhg |
| USDC       | FgSsGV8GByPaMERxeQJPvZRZHf7zCBhrdYtztKorJS58 |
| USDT       | 3RudPTAkfcq9Q9Jk8SVeCoecCBmdKMj6q5smsWzxqtqZ |
| PAI        | GaqxUwFGGrDouYLqghchmZU97Y1rNhyF7noMTJNvpQPa |
| SRM        | 77TBgKmTNtMdGrt1ewNRb56F2Xw6fNLZZj33JZ3oGwXh |
| BTC        |  QN2HkkBaWHfYSU5bybyups9z1UHu8Eu7QeeyMbjD2JA |
| MER        | 6UgGnLA3Lfe8NBLAESctsUXWdP3zjMFzSLEZxS3tiaKh |
| mSOL       | Dt1Cuau5m5CSmun8hZstjEh9RszxAmejnq7ZaHNcuXfA |
| SBR        | FhraFicS7fGxHn8jfzuZ6TeTpCu8PAnQNZiT2tqM5xvv |

#### Oracle Public Keys

| Asset Name |                                Oracle Pubkey |
| ---------- | -------------------------------------------: |
| SOL        | H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG |
| USDC       |                                        N / A |
| USDT       | 3vxLXJqLqF3JG5TCbYycbKWRBbCJQLxQmBGCkyqEEefL |
| PAI        |                                          N/A |
| SRM        | 3NBReDRTLKMQEKiLD5tGcx4kXbTf88b7f2xLS9UuGjym |
| BTC        | GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU |
| MER        | G4AQpTYKH1Fmg38VpFQbv6uKYQMpRhJzNPALhp7hqdrs |
| pSOL       | H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG |
| SBR        | 8Td9VML1nHxQK6M8VVyzsHo32D7VBk72jSpa9U861z2A |

#### Supply Public Keys

| Asset Name |                           Supply Public Keys |
| ---------- | -------------------------------------------: |
| SOL        | BLAFX12cDmsumyB6k3L6whJZqNqySaWeCmS5rVuzy3SS |
| USDC       | 2xPnqU4bWhUSjZ74CibY63NrtkHHw5eKntsxf8dzwiid |
| USDT       |  QyvfrbqH7Mo8W5tHN31nzbfNiwFwqPqahjm9fnzo5EJ |
| PAI        | 42kNZrAuwZHLtuc7jvVX7zMfkfgwbPynqzFB3zdkAEGM |
| SRM        | DjhMNdgdbxNud1gmc4DUwrQqJxNbjhxiwNnhc4usSXmQ |
| BTC        | FZKP27Zxz9GbW86hhq3d1egzpBH5ZnYkyjQZVf86NQJ8 |
| MER        | 6UmrawFZgdPvMe6BLZdZCNRFz9u2TWsu5enFbTufA3a1 |
| SBR        | HTwd3VaDQphZgh2x7wqE2Qdndo4TT5C8fpvhKFcNh1Rt |

### Dev Net

Lending Program id: `pdQ2rQQU5zH2rDgZ7xH2azMBJegUzUyunJ5Jd637hC4`&#x20;

Staking program id: `port_staking_instructions::id()`&#x20;

Lending Market: `H27Quk3DSbu55T4dCr1NddTTSAezXwHU67FPCZVKLhSW`

#### Reserve Public Keys

| Asset Name |                              Reserve Address |
| ---------- | -------------------------------------------: |
| SOL        | 6FeVStQAGPWvfWijDHF7cTWRCi7He6vTT3ubfNhe9SPt |
| USDC       | G1CcAWGhfxhHQaivC1Sh5CWVta6P4dc7a5BDSg9ERjV1 |
| USDT       | B4dnCXcWXSXy1g3fGAmF6P2XgsLTFYaQxYpsU3VCB33Q |
| BTC        | A8krqNC1WpWYhqUe2Y5WbLd1Zy4y2rRN5wJC8o9Scbyk |
| MER        | FdPnmYS7Ma8jfSy7UHAN5QM6teoqwd3vLQtoU6r2Umwy |

You can get all the information below by parsing the reserve data. We provide the account data here for your convenience.

#### Fake token Mint

| Asset Name |                                  pToken Mint |
| ---------- | -------------------------------------------: |
| SOL        |  So11111111111111111111111111111111111111112 |
| USDC       | G6YKv19AeGZ6pUYUwY9D7n4Ry9ESNFa376YqwEkUkhbi |
| USDT       | 9NGDi2tZtNmCCp8SVLKNuGjuWAVwNF3Vap5tT8km5er9 |
| BTC        | EbwEYuUQHxcSHszxPBhA2nT2JxhiNwJedwjsctJnLmsC |
| MER        |  Tm9LcR74uJHPw3zY3j3nSh5xfcyaLbvXgAtTJwbqnnp |

#### pToken Mint

| Asset Name |                                  pToken Mint |
| ---------- | -------------------------------------------: |
| SOL        | Hk4Rp3kaPssB6hnjah3Mrqpt5CAXWGoqFT5dVsWA3TaM |
| USDC       | HyxraiKfdajDbYTC6MVRToEUBdevBN5M5gfyR4LC3WSF |
| USDT       | 4xEXmSfLFPkZaxdL98XkoxKpXEvchPVs21GYqa8DvbAm |
| BTC        | 95XGx3cM83Z1Bbx8pJurAHwxJjvShTJE4BtfgMWfV6NB |
| MER        | FQzruvtLTk6qtPNEAJHQWMVs4M9UMP9T3cGAVfUskHfP |

#### Oracle Public Keys

| Asset Name |                                Oracle Pubkey |
| ---------- | -------------------------------------------: |
| SOL        | J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix |
| USDC       |                                          N/A |
| USDT       | 38xoQ4oeJCBrcVvca2cGk7iV1dAfrmTR1kmhSCJQ8Jto |
| BTC        | HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J |
| MER        | 6Z3ejn8DCWQFBuAcw29d3A5jgahEpmycn7YDMX7yRNrn |

#### Supply Public Keys

| Asset Name |                           Supply Public Keys |
| ---------- | -------------------------------------------: |
| SOL        | AbKeR7nQdHPDddiDQ71YUsz1F138a7cJMfJVtpdYUSvE |
| USDC       | GAPyFes3o7S7coY9nsuhaRZBEA7DdQPHBfVdY2DdgNua |
| USDT       | AeGbAqYZUURTykyCsgAUfopBMqQ3eAwrDxYhXoRhiw8q |
| BTC        | 75iyCxiPoj3MaUVo3SynmhaN3cbLDEhd4d9VHik6Kkvr |
| MER        | AMjhzse1TtTcKBFw5tQPLGtVoEsL4gt9YowNnzMKEGUr |

#### Create StakeAccount

For assets that have liquidity mining reward, you need to first create a stake account in order to collateralize and get the reward.&#x20;

First, get the data of the reserve you want deposit into and unpack it to get the field `reserve.config.deposit_staking_pool` which is the staking pool id, and generates the seed and keypair by using the Solana built in `sha256` hashing function `solana_sdk::hash::hashv(&[owner.as_ref(), staking_pool.as_ref(), staking_program_id.as_ref()])`, where the owner should be your wallet's public key, and generate the keypair for stake account by `solana_sdk::signer::keypair::keypair_from_seed`.&#x20;

Then call `create_account` and `create_stake_account` instruction to create the stake account. Owner need to sign the instruction of claiming reward. If you are using a program to create the stake account, you can use an PDA account. Actually, you can use any address to create the stake account, as long as you make sure that there is a one-one mapping between (owner, staking\_pool) and stake\_account, which means that for every owner and staking\_pool, you only have one stake account.

```rust
let account_seed = hashv( & [owner.as_ref(), staking_pool.as_ref(), staking_program_id.as_ref()]);
let stake_account_key_pair = keypair_from_seed(account_seed.as_ref()).unwrap();
let instructions = vec![
    create_account(
        &payer.pubkey(),
        &stake_account_key_pair.pubkey(),
        stake_account_rent,
        StakeAccount::LEN as u64,
        &staking_program_id
    ),
    create_stake_account(
        staking_program_id,
        stake_account_key_pair.pubkey(),
        staking_pool,
        owner
    )
];
```

#### Refresh Reserves and Obligation

Assuming that you already have your stake account or you are depositing to a reserve without liquidity mining reward, you need to refresh all the reserves the obligation has interacted with and the obligation itself in the same instruction before you depositing / withdrawing / repaying / liquidating.

```rust
let mut refresh_instructions = vec![];
//reserve_map is a map of reserve pubkey of reserve data, you can get the oracle pubkey from the reserve data or can hard code it in a config file.
let to_refresh = reserve_map.iter().filter( | (k, _) | {
        obligation
        .borrows
        .iter()
        .map(| li | li.borrow_reserve)
        .chain(obligation.deposits.iter().map(| ob | ob.deposit_reserve))
        .any( | r | r == * * k)
    });
refresh_instructions.extend(
    to_refresh.map( | (k, v) | refresh_reserve(lending_program_id, * k, v.liquidity.oracle_pubkey)),
);
refresh_instructions.push(
    refresh_obligation(
        program_id,
        obligation_pubkey,
        obligation
        .deposits
        .iter()
        .map(|d| d.deposit_reserve)
        .chain(obligation.borrows.iter().map(|b| b.borrow_reserve))
        .collect(),
    )
);
```

#### Initialize Obligation

```rust
let mut transaction = Transaction::new_with_payer(
    &[
        create_account(
            &payer.pubkey(),
            &obligation_keypair.pubkey(),
            rent.minimum_balance(Obligation::LEN),
            Obligation::LEN as u64,
            &port_finance_variable_rate_lending::id(),
        ),
        init_obligation(
            port_finance_variable_rate_lending::id(),
            obligation.pubkey,
            lending_market.pubkey,
            user_accounts_owner.pubkey(),
        ),
    ],
    Some( & payer.pubkey()),
);
```

#### Deposit Liquidity / Collateralize

```rust
deposit_reserve_liquidity(
    port_variable_rate_lending::id(),
    liquidity_amount,
    user_liquidity_token_account_pubkey,
    user_collateral_token_account_pubkey,
    reserve_pubkey,
    reserve.liquidity.supply_pubkey,
    reserve.collateral.mint_pubkey,
    self.pubkey,
    user_transfer_authority.pubkey()
)
```

```rust
deposit_obligation_collateral(
    port_variable_rate_lending::id(),
    liquidity_amount,
    user_collateral_token_account_pubkey,
    reserve.collateral.supply_pubkey,
    reserve_pubkey,
    obligation_pubkey,
    lending_market.pubkey,
    obligation.owner,
    user_transfer_authority.pubkey(),
    Some(stake_account_pubkey),
    Some(staking_pool_pubkey),
)
```

```rust
deposit_reserve_liquidity_and_obligation_collateral(
    port_variable_rate_lending::id(),
    liquidity_amount,
    user_liquidity_token_account_pubkey,
    user_collateral_token_account_pubkey,
    reserve_pubkey,
    reserve.liquidity.supply_pubkey,
    reserve.collateral.mint_pubkey,
    lending_market_pubkey,
    reserve.collateral.supply_pubkey,
    obligation_pubkey,
    obligation.owner,
    user_transfer_authority.pubkey(),
    Some(stake_account_pubkey),
    Some(staking_pool_pubkey),
)
```

#### Withdraw

There will be a coming `withdrawAndRedeem` instruction soon, while it is under auditing. So now, you need first uncollateralized the asset then withdraw.

```rust
withdraw_obligation_collateral(
    port_finance_variable_rate_lending::id(),
    WITHDRAW_AMOUNT,
    reserve.collateral.supply_pubkey,
    sol_test_reserve.user_collateral_pubkey,
    sol_test_reserve.pubkey,
    test_obligation.pubkey,
    lending_market.pubkey,
    test_obligation.owner,
    Some(stake_account_pubkey),
    Some(staking_pool_pubkey),
)
```

```rust
redeem_reserve_collateral(
    port_finance_variable_rate_lending::id(),
    COLLATERAL_AMOUNT,
    user_collateral_token_account_pubkey,
    user_liquidity_token_account_pubkey,
    reserve_pubkey,
    reserve.collateral.mint_pubkey,
    reserve.liquidity.supply_pubkey,
    lending_market.pubkey,
    user_transfer_authority.pubkey(),
)
```

#### Repay

To repay, you can pass number greater then amount you borrow to repay all, for example you can pass `u64::MAX` in to repay all.

```rust
repay_obligation_liquidity(
    port_finance_variable_rate_lending::id(),
    liquidity_amount,
    user_liquidity_token_account_pubkey,
    reserve.liquidity.supply_pubkey,
    reserve_pubkey,
    obligation_pubkey,
    lending_market.pubkey,
    user_transfer_authority.pubkey(),
)
```

#### Liquidation

Please refer to `https://github.com/port-finance/liquidator`

#### Flash loan

We have an instruction with the following signature for flash loan:

```rust
pub enum LendingInstruction {
    // ....
    /// Make a flash loan.
    ///
    /// Accounts expected by this instruction:
    ///
    ///   0. `[writable]` Source liquidity token account.
    ///                     Minted by reserve liquidity mint.
    ///                     Must match the reserve liquidity supply.
    ///   1. `[writable]` Destination liquidity token account.
    ///                     Minted by reserve liquidity mint.
    ///   2. `[writable]` Reserve account.
    ///   3. `[]` Lending market account.
    ///   4. `[]` Derived lending market authority.
    ///   5. `[]` Flash loan receiver program account.
    ///             Must implement an instruction that has tag of 0 and a signature of `(repay_amount: u64)`
    ///             This instruction must return the amount to the source liquidity account.
    ///   6. `[]` Token program id.
    ///   7. `[writable]` Flash loan fee receiver account.
    ///                     Must match the reserve liquidity fee receiver.
    ///   8. `[writable]` Host fee receiver.
    ///   .. `[any]` Additional accounts expected by the receiving program's `ReceiveFlashLoan` instruction.
    FlashLoan {
        /// The amount that is to be borrowed
        amount: u64,
    },
}
```

In the implementation, we do the following in order:

1. Perform safety checks and calculate fees
2. Transfer `amount` from the source liquidity account to the destination liquidity account
3. Call the `ReceiveFlashLoan` function (the flash loan receiver program is required to have this function with tag `0`).

   The additional account required for `ReceiveFlashLoan` is given from the 10th account of the `FlashLoan` instruction, i.e. after host fee receiver.
4. Check that the returned amount with the fee is in the reserve account after the completion of `ReceiveFlashLoan` function.

The flash loan receiver program should have a `ReceiveFlashLoan` instruction which executes the user-defined operation and return the funds to the reserve in the end.

```rust
pub enum FlashLoanReceiverInstruction {

    /// Receive a flash loan and perform user-defined operation and finally return the fund back.
    ///
    /// Accounts expected:
    ///
    ///   0. `[writable]` Source liquidity (matching the destination from above).
    ///   1. `[writable]` Destination liquidity (matching the source from above).
    ///   2. `[]` Token program id
    ///   .. `[any]` Additional accounts provided to the lending program's `FlashLoan` instruction above.
    ReceiveFlashLoan {
        // Amount that is loaned to the receiver program
        amount: u64
    }
}
```

You can view a sample implementation [here](https://github.com/solana-labs/solana-program-library/tree/master/token-lending/program/tests/helpers/flash_loan_receiver.rs).


# Tokenomics

Port token distribution.

\
**Total Supply: 100 million.** \
• Ecosystem: 33%. \
• Liquidity Incentives: 31%. \
• Team: 20% . \
• Fund raising: 10% \
• Initial Liquidity: 4%. \
• Advisors: 2%.

![](https://2642926184-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MaBnhYO5U0xRgxJs7vp%2Fuploads%2Fq7SN7jU718tUs1NckCQk%2Fimage.png?alt=media\&token=c5103225-590a-4be7-9262-980e71acc60b)


# Community Links

Website: <https://port.finance/>\
Discord: <https://discord.com/invite/nAMXAYhTb2>\
Telegram: <https://t.me/port_finance>\
Twitter: <https://twitter.com/port_finance>\
Documentation: <https://docs.port.finance/>\
Litepaper: <https://port.finance/docs/litepaper.pdf>\
Github: <https://github.com/port-finance/><br>


