@hedgefarm/alpha3-sdk
v0.2.2
Published
Automated market-making Strategies.
Downloads
20
Readme
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.
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 for more explanation.
Setup
Install Rust, Solana, (Yarn or NPM) and Anchor, check here
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
, fileprograms-to-load/orca.so
- whirlpool :
whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc
, fileprograms-to-load/whirlpool.so
- jupiter :
JUP4Fb2cqiRUcaTHdrPC8h2gNsA2ETXiPDD33WcGuJB
, fileprograms-to-load/jupiter.so
The address that own those program in the Anchor.toml doc is here
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
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 :
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 to get enough token and not be limited bysolana airdrop
- Smart contract integration tests:
anchor test --skip-deploy
Push new version on Npm
Follow the installation process of np and run at the root of the project:
npm login
npm run build
np
Update the version and changes in changelog
Formatting
Rust: cargo fmt
Typescript : npx prettier --write .
Expand code generated by anchor
Used for create_idl
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
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:
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 ...
andanchor 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)
GH link to on-chain instructions that we can call on Whirlpools
Multisig
Squads seems to be a really nice solution
Pros :
- code open-source link
- program not upgradable link
- 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:
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 and the current work here
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 and here
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 and 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
Orca documentation here
Orca Developer Portal here
Airdrop tool here
Orca Sandbox repo here
Jupiter CPI repo here