npm package: @hedgefarm/alpha3-sdk
Description: Automated market-making Strategies.
Latest version: 0.2.2

# Project overview

Automated market-making Strategies.

The purpose of this project is to allocate as efficiently as possible two assets in a Concentrated Liquidity Market Maker pool to generate a real yield.
Indeed, the narrower the price range, the greater the fees but also the impermanent loss.
Thus managing Concentrated Liquidity Market Maker position can be tricky, you can still lose money even if the APR is big.

Our quantitative model tracks price and volatility to find the best bounds of our position to maximize returns while minimizing impermanent loss, so that you don't have to constantly monitor the market.

Rebalancing a Concentrated Liquidity Market Maker position can be really costly because impermanent loss becomes realized loss.
If you add swap fees/price impact on top of that it can be really hard to be profitable, this is why we use Jupiter to rebalance our position.

Jupiter being a web2 solution, Orca pools can be used in case of web2 unavailability .

This project is build on top of Orca-Whirlpool on Solana.

```mermaid
flowchart LR
  subgraph Alpha4
  subgraph Alpha4Vault
    direction RL
    acc1([TokenAccountA])
    acc2([TokenAccountB])
    acc3([LpMint])
    acc4([PositionTokenAccount])
  end
  end
  subgraph User
      fn1(deposit)
      fn2(withdraw)
  end
  subgraph Admin
      direction RL
      fn3(initializeVault)
      fn4(setVaultParameters)
      fn5(pause/unPause)
      fn6(panic)
  end
  subgraph PositionChanger/Admin/Bot
      fn7(changePosition)
      fn8(rebalance)
      fn9(addLiquidity)
  end
  subgraph Whirlpool
      acc5([Position])
  end
  User -.-> Alpha4Vault
  Admin -.-> Alpha4Vault
  PositionChanger/Admin/Bot -.-> Alpha4Vault
  Alpha4Vault --rebalance using--> Orca
  Alpha4Vault --rebalance using--> Jupiter
  Alpha4Vault --manage liquidity--> Whirlpool

  api((Jupiter v4 API))--swap quote--> fn8
  style api fill:#b2ff66,stroke:#333,stroke-width:3px

  style User fill:#66ff66,stroke:#333,stroke-width:3px
  style Admin fill:#ff0,stroke:#333,stroke-width:3px
  style PositionChanger/Admin/Bot fill:#3399ff,stroke:#333,stroke-width:3px

  classDef vault fill:#b266ff,stroke:#333,stroke-width:3px
  Alpha4Vault:::vault

  classDef fn stroke:#333,stroke-width:2px
  fn1:::fn
  fn2:::fn
  fn3:::fn
  fn4:::fn
  fn5:::fn
  fn6:::fn
  fn7:::fn
  fn8:::fn
  fn9:::fn
  classDef acc stroke:#333,stroke-width:2px
  acc1:::acc
  acc2:::acc
  acc3:::acc
  acc4:::acc
  acc5:::acc

  classDef program fill:#ff6666,stroke:#333,stroke-width:3px
  Alpha4:::program
  Whirlpool:::program
  Jupiter:::program
  Orca:::program


```

Noticeable Accounts :

- TokenAccountA : token account of token A to handle deposit/withdraw and unused liquidity
- TokenAccountB : token account of token B to handle deposit/withdraw and unused liquidity
- LpMint : mint to represent the shares of a vault.
- PositionTokenAccount : account which owns the current opened position on Whirlpool

TokenAccountA, TokenAccountB, LpMint and PositionTokenAccount are owned by an Alpha4Vault. Thus their behavior is strictly defined by the program, even admin can't have possession of it.

See doc on [lib.rs](./programs/alpha4-contracts-dev/src/lib.rs) for more explanation.

## Setup

Install Rust, Solana, (Yarn or NPM) and Anchor, check [here](https://www.anchor-lang.com/docs/installation)

`yarn install` or `npm install`

Build smart contract: `anchor build`

At the build time, this error appears, we ignore it.

`Error: Function _ZN10whirlpools81_$LT$impl$u20$core..default..Default$u20$for$u20$whirlpools..state..TickArray$GT$7default17h09c7cd609a105921E Stack offset of 9944 exceeded max offset of 4096 by 5848 bytes, please minimize large stack variables`

Make sure the sdk is correctly building by running `npm run build`

## Architecture

This smart contract is build in `bpf` - default with our anchor version at the moment. (The other architecture is sbf).

To be sure that anchor is building at the right place, you can run: `anchor build --arch bpf`.

## Run test

The test are run in local net. Since the test uses Orca, Whirlpool and Jupiter, we need to download their associated program.
We place them in `programs-to-load` at the root of the project.

To do so we need to dump the program on-chain :
`solana program dump -u https://api.mainnet-beta.solana.com <ACCOUNT_ADDRESS> <OUTPUT_FILEPATH>`

- orca: `9W959DqEETiGZocYWCQPaJ6sBmUzgfxXfqGeTEdp3aQP`, file `programs-to-load/orca.so`
- whirlpool : `whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc`, file `programs-to-load/whirlpool.so`
- jupiter : `JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB`, file `programs-to-load/jupiter.so`

The address that own those program in the Anchor.toml [doc is here](https://www.anchor-lang.com/docs/manifest)

## Run on localnet

- Unit tests in rust: `cargo test`
- Unit tests in Javascript: `anchor run sdk-test`
- Smart contract integration tests: `anchor test --detach`. Then you can browse the transactions [here](https://explorer.solana.com/?cluster=custom&customUrl=http%3A%2F%2Flocalhost%3A8899)

## Run on devnet

We really do not encourage to run the tests on devnet.  
You will encounter rate limitation for getting enough dev SOl on your wallet, test will be slower to run, etc...

- Be sure that the contract is deployed in devnet
- Uncomment the devnet part in `Anchor.toml`
- Comment the localnet part in `Anchor.toml`
- Export env vars :

```sh
export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com
export ANCHOR_WALLET=path_to_your_json_wallet
```

- Don't forget to use the Alpha4Config corresponding. Look for `alpha4TestConfig`
- Use a custom keypair for `anchorFaucetKeypair`.
- Be sure to have enough money in `anchorFaucetKeypair`. We encourage you to use [this repo](https://github.com/flxxyz/solana-airdrop-devnet) to get enough token and not be limited by `solana airdrop`
- Smart contract integration tests: `anchor test --skip-deploy`

## Push new version on Npm

Follow the installation process of [np](https://github.com/sindresorhus/np) and run at the root of the project:

```shell
npm login
npm run build
np
```

Update the version and changes in [changelog](./CHANGELOG.md)

## Formatting

Rust: `cargo fmt`
Typescript : `npx prettier --write .`

## Expand code generated by anchor

Used for `create_idl`
```shell
cargo install cargo-expand
anchor expand
```

The code will be generated in `.anchor/expanded-macros/[your_program]`

## Testing contract in mainnet / testnet / devnet

### Interact with testing contract

See `script` folder. You will need to update `pathToKeypair` and the `alpha4Config`.

Airdrop some SOL to be able to deploy the program on devnet (to do several time):
`solana airdrop 2 deploy/deployment-devnet-keypair.json --url devnet`

You can create your own token and whirlpool see [setupTestEnvironment](./test/utils/setup-test-environment.ts)

#### Deploy contract

First make sure the `declare_id` of the program is the same as `solana address -k target/deploy/alpha4_contracts_dev-keypair.json`.

For testing in mainnet, we can use:

```shell
ts-node scripts/deploy.ts -u mainnet-beta -k 'path/to/payer' -p target/deploy/alpha4_contracts_dev.so -i target/deploy/alpha4_contracts_dev-keypair.json
```

Sometimes, the transaction can be dropped, so you'll get this error : `SendTransactionError: failed to send transaction: Transaction simulation failed: Blockhash not found`, the only solution is to retry.
If the deploy fails, close the temporary buffer account and retry.

# Publish IDL

- use our function create_idl to create an idl account (This allocates an account of exactly MAX_PERMITTED_DATA_INCREASE bytes for the idl). Needs to be called by the admin
- `anchor idl upgrade --provider.cluster mainnet --provider.wallet [admin] -f target/idl/alpha4_contracts_dev.json [program_id]` For publishing with the multisig will probably require the use of: `anchor idl write-buffer ...` and `anchor idl set-buffer ...`

## Orca whirlpool notes

Whirlpools is concentrated liquidity automated market maker (CLAMM) program build on solana. It allows adding liquidity in specified range to maximize fees (like UniV3 pools).

A Whirlpool is a concentrated liquidity pool between a token pair (A & B). [(docs link)](https://orca-so.gitbook.io/orca-developer-portal/whirlpools/architecture-overview/account-architecture)

[GH link to on-chain instructions that we can call on Whirlpools](https://github.com/orca-so/whirlpools/tree/main/programs/whirlpool/src/instructions)

## Multisig

[Squads](https://squads.so/) seems to be a really nice solution

Pros :

- code open-source [link](https://github.com/Squads-Protocol/squads-mpl)
- program not upgradable [link](https://explorer.solana.com/address/SMPLecH534NA9acpos4G6x7uf3LWbCAwZQE9e8ZekMu)
- code audited
- no fees
- really smooth UI
- you can directly interact though the UI with programs that have a on-chain deployed IDL.

Cons :

- transaction cost higher because of rent
- transaction is stored on chain before execution so it can be more easily front run

To upgrade contract with multisig, first deploy the buffer update:

```shell
solana program write-buffer --url mainnet-beta --buffer-authority <multisig-address> <path-to-program-updated.so>
```

Then create an upgrade transaction proposal on squads in the develop section and sign it.

## Contract monitoring/Alerting

Not done for the at the moment, you can find here some possible solution

### 1) Substreams

Check [here](https://github.com/streamingfast/streamingfast-client) and the current work [here](https://github.com/HedgeFarm/alpha4-graph)

Pros :

- mapping done in Rust => really easy to extract complex schema
- can access past data

Cons :

- cannot access account's data
- you have to host the data extraction and the storage

### 2) Event publisher/listener

Anchor provides a way to publish event from smart-contract and to listen to it, check [here](https://docs.rs/anchor-lang/latest/anchor_lang/macro.emit.html) and [here](https://coral-xyz.github.io/anchor/ts/classes/Program.html#addEventListener)

Pros :

- easy to use
- you extract data later in logs by parsing block
- react to live event

Cons :

- you cannot access to past data
- event are stored on chain but you may need to handle data storage for fast and easy access

### 3) Indexer

[Solana FM](https://portal.solana.fm/indexer) and [Helius](https://docs.helius.xyz/welcome/what-is-helius) provides some solutions for data monitoring

Pros :

- hosted
- "plug and play"

Cons :

- not powerful at the moment, can't extract complex data

## Useful docs

Whirlpools source code [here](https://github.com/orca-so/whirlpools/tree/main/programs/whirlpool/src)

Orca documentation [here](https://docs.orca.so/faqs-and-troubleshooting/master)

Orca Developer Portal [here](https://orca-so.gitbook.io/orca-developer-portal/orca/welcome)

Airdrop tool [here](https://github.com/singerhedged/solana-airdrop-devnet)

Orca Sandbox repo [here](https://github.com/everlastingsong/solsandbox)

Jupiter CPI repo [here](https://github.com/jup-ag/jupiter-cpi)