---
# System prepended metadata

title: Smart Contracts
tags: [PORFI]

---

# PORFI Regenerative Finance Index Token
---

## Overview:

A smart contract token which represents claim to underlying basket assets.  The token is an ETF-like index; composed of wrapped Balancer multi-token pool held assets.  This allows us to align incentives and share liquidity between a small range of different tokens.  It enhances capital efficiency and naturally builds protocol owned liquidity over time.

The PORFI token is a wrapped claim to assets in an actively traded Balancer pool.  This makes the PORFI token a native yield bearing asset.

We apply a variable tax function to all transfers in order to drive value and utility towards both the index token itself as well as the underlying basket assets.

---
## Mechanics:

- Underlying assets are stored in a Balancer Multi-Token Smart Pool:
    - This allows ***all*** of the underlying index liquidity to be utilized for trading the individual bashet tokens.
    - Provides a huge amount of utility to underlying tokens.
    - Naturally maintains the portfolio's intended weight oriented balance.

- Index token has a variable supply cap; designed to act as a throttle control for the system's overall risk appetite.
- Index token supply is dynamic:
    - Index can be minted by wrapping the underlying asset.
    - Index can be redeemed (burned) for it's corresponding share of the underlying assets.

- Tax on transfer applies a variable basis point fee on any transfers of the index token:
    - Fee can vary but must be between 0.1% and 5%.
    - Half of the fees in index token are burned.  This reduces selling pressure on the index; and simultaneously removes redeemable circulating index - preventing selling pressure on the underlying assets.
    - The other half of the fees are used to provide liquidity for a stablecoin/PORFI pair.  This means that only 25% of the tax is returned as selling pressure.
    - Over time this will naturally drive an arbitrage between basket assets and the index token.  Naturally; the price of the index token will be slightly above the basket's assets.  If we remove any external market pressures or factors - the value of PORFI will grow 1.5% during each trading cycle corresponding to the volume of a trade.  As PORFI tends to float above the value of the underlying assets; this will express in the market as buying pressure on the basket assets and absorption into the index.

---
## Schematics
Mint:
```mermaid
graph TD;
    User-->|Start Mint|Wrapper
    User-->|Approve Basket Token|Wrapper
    Wrapper-->|Join|Balancer_Managed_Pool
    Balancer_Managed_Pool-->|minted BPT|Wrapper
    Wrapper-->|Deposit|Vault
    Vault-->|Request Mint|Porfi_Token
    Porfi_Token-->|New Tokens|User
```
Redemption:
```mermaid
graph TD;
    User-->|Approve Porfi|Wrapper
    User-->|Start Redemption|Wrapper
    Wrapper-->|Burn|Porfi_Token
    Wrapper-->|Withdraw|Vault
    Vault-->|Burn BPT|Balancer_Managed_Pool
    Balancer_Managed_Pool-->|Basket Tokens|User
```
---
## Tech Stack

- [Foundry](https://book.getfoundry.sh/)
    - Audit Readiness level unit testing and comprehensive documentation is included
- [OpenZeppelin SC Library](https://github.com/OpenZeppelin/openzeppelin-contracts)
- [PORFI Token](https://miro.com/app/board/uXjVM_CHXXQ=/)
    - [ERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol)
    - [IERC20](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/IERC20.sol)
    - [ERC20Permit](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Permit.sol)
    - [AccessControl](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol)
    - [ERC20Pausable](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Pausable.sol)
- Wrapper Contract
    - [Balancer Interfaces](https://github.com/balancer/balancer-v2-monorepo)
    - [Ownable](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol)
- Vault Contract
    - [ERC4626 Tokenized Vault](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC4626.sol)
    - [4626 Known "Inflation Attack Guard"](https://docs.openzeppelin.com/contracts/4.x/erc4626)
    - [AccessControl]((https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol))
- [Managed Balancer Pool](https://docs.balancer.fi/concepts/pools/managed.html)

---
## PORFI Token
---
#### Implementation:
- AccessControl roles:
    - `DEFAULT_ADMIN_ROLE` - initially will be a multisig of trusted community members; can eventually be transferred to governance.
    - `MINTER_ROLE` - is specifically for wrapper smart contracts that wrap or redeem the index tokens.  This role allows the address to mint and burn tokens.
    - `PAUSER_ROLE` - is designed for EOA's which can act as a safety feature to pause the protocol if there's ever a safety or security issue.
- Variable supply cap set by `setSupplyCap` which can only increase the maximum supply of the token and limits the ability to mint new tokens above the threshold.  Can only be called by `DEFAULT_ADMIN_ROLE`.
- Variable transfer tax set by `setTaxRate` which can only be called by `DEFAULT_ADMIN_ROLE`.  Enforces a lower and upper bound on the tax rate.
- `setTaxCollector` can only be called by `DEFAULT_ADMIN_ROLE` and enables changing the address which collects the protocol's taxes.
- `_transfer` override which directs the `variableTax` rate to the `taxCollector` during any PORFI transfers.
- `pause` function which toggles the pause status flag.  Callable by `PAUSER_ROLE` and prevents any transfer, wrapping or redemption of the PORFI token.  Consider implications for rebalancing or migrating liquidity.
#### Testing:

---
### Wrapper Contract 
---
#### Implementation: 
- `mintIndex` public function which executes `transferFrom` calls against each of the basket assets.  It derives the number of required assets of each type required; and joins the assets to the Balancer pool; while returning the Porfi index token to the user.  [Building a join using Balancer](https://docs.balancer.fi/guides/builders/join-pool.html#types-of-pools-in-balancer)
- `_vaultDeposit` internal function which deposits the BPT tokens to the ERC4626 vault
- `burnIndex` function which executes `burn` function against the Porfi token contract; and withdraws liquidity from the Balancer pool; in whatever token is desired.
- `_vaultWithdraw` internal function which extracts BLP tokens from the ERC4626 vault
- `_mintCheckSupply` internal function which is used to calculate the amount of PORFI tokens to mint during a deposit
- `_burnCheckSupply` internal function for calculating the amount of BLT tokens during a burn redemption
- Has been set as`grantRole(MINTER_ROLE)` on the Porfi token contract.
- Is `grantWrapper` on the Vault contract.
- Implement [IERC4626 interface](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/interfaces/IERC4626.sol)
#### Testing: 

---
### Vault 
---
#### Implementation: 
- Deployed with the address of the Porfi Balancer Managed Pool address and as such accepts only approved BPT.
- Design the `_decimalsOffet` in order to prevent any kind of "inflation attack"
- AccessControl roles:
    - `DEPOSITOR_ROLE` required addresses which are allowed to deposit; can be used to upradge the wrapper contract for a number of advanced purposes or strategies  
    - `DEFAULT_ADMIN_ROLE` for the multi-sig
#### Testing:

### Balancer Managed Pool

- Owned by the multisig
    - Complete documentation for how to execute contract interactions with the Balancer pool.
- `circuitBreaker` tolerance research and design.
- Swap fee research and discussion (Swap fees will impact the PORFI token's native yield)
- Dynamic gradual fee changes can be incredibly helpful when initializing the pool; or when unpausing the pool.  Otherwise value can be lost to arbitrageurs.
- Management fees; this is a fee leveraged on the entire AUM and is paid out to the owner of the pool.
- Protocol fees are paid on AUM to the Balancer protocol instead of having swap fees.

