Meson is the faster and safer way to execute low-cost, zero-slippage universal cross-chain swaps across all leading blockchains and layer-2 rollups.
This repository contains the Rust implementation for the Meson protocol on Solana. See Meson Docs for the design details of Meson.
Execute the code below to run the unit tests:
cargo build-sbf
RUST_LOG=error cargo test-sbf --test functional -- --nocapture # See the logs from functional.rs
The file structure of the contract code is as follows:
src
├── entrypoint.rs
├── error.rs
├── instruction.rs
├── lib.rs
├── mesonpools.rs
├── mesonswap.rs
├── processor.rs
├── state.rs
└── utils.rs
entrypoint.rs
: the entrypoint of the contract, which is called by the Solana runtime.error.rs
: defines the error types of the contract.instruction.rs
: defines the instruction types of the contract. For more details see the next chapter.lib.rs
: lists all the modules of the contract.mesonpools.rs
: defines the data structure of the Meson Pools, and the functions that the source chain of the cross-chain swap needs to call.mesonswap.rs
: defines the data structure of the Meson Swap, and the functions that the target chain of the cross-chain swap needs to call.processor.rs
: defines the processor of the contract, which is called by the entrypoint.state.rs
: mainly defines the functions that will change the state of the contract.utils.rs
: mainly defines the utility view functions of the contract, which won't change the state.
As a developer, you need to know how to interact with the contracts. The following sections will introduce the instructions and the data structures of the contracts. You can find more details in the annotations of the code file instruction.rs.
There are currently 13 instructions in the contract, indexed from 0 to 12. When calling a instruction, you need to pass the accounts list as the accounts: &[AccountInfo]
params, and the related data as the data: &[u8]
params (starting with the instruction index). The accounts list and the data are defined in the instruction.rs file.
You can find the examples of all the instructions in the unit tests.
InitContract
The admin(deployer) must call this init function first, to set the admin address and the supported coin list well. Here are the accounts list to pass to the instruction:
- payer_account: the contract deployer, also the admin
- system_program: that is
11111111111111111111111111111111
- authority_account: to save the address of admin
- save_token_list_account: to save the supported coin list
TransferPremiumManager
The admin can transfer the premium manager to another address. Here are the accounts list to pass to the instruction:
- admin_account: the admin account, must be a signer
- authority_account
- new_admin: the new admin address
AddSupportToken { coin_index: u8 }
The admin can add a new coin to the supported coin list. Here are the accounts list to pass to the instruction:
- admin_account
- authority_account
- save_token_list_account
- token_mint_account: the mint address of the coin to add to support list
RegisterPool { pool_index: u64 }
The LP can register a new pool. Here are the accounts list:
- payer_account
- system_program
- authorized_account: the address to add to LP pools
- save_poaa_account_input: the data account to save
authorized address -> pool index
pair (8-bytes long) - save_oop_account_input: the data account to save
pool index -> authorized address
pair (32-bytes long)
PostSwap {
encoded_swap: [u8; 32],
signature: [u8; 64],
initiator: [u8; 20],
pool_index: u64,
}
The user can post a swap, which is the Step 1 of the cross-chain swap. Here are the accounts list:
- payer_account
- system_program
- user_account: the user who wants to swap
- token_mint_account
- token_program_info: that is "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
- save_token_list_account
- save_ps_account_input: the data account to save
encoded -> postedSwap
pair (60-bytes) - ta_user_input: the token account for the user
- ta_program_input: the token account for the program
BondSwap {
encoded_swap: [u8; 32],
pool_index: u64,
}
The LP can bond a swap after the user called PostSwap
. Here are the accounts list:
- sender_account: same as
authorized_account
- save_poaa_account_input
- save_ps_account_input
CancelSwap { encoded_swap: [u8; 32] }
The user can cancel a swap after he/she called PostSwap
. Here are the accounts list:
- token_mint_account
- token_program_info
- save_ps_account_input
- ta_user_input
- ta_program_input
- contract_signer_account_input
ExecuteSwap {
encoded_swap: [u8; 32],
signature: [u8; 64],
recipient: [u8; 20],
deposit_to_pool_bool: bool,
}
The LP can execute a swap after the user called PostSwap
and the LP called BondSwap
. This is the Step 4 of the cross-chain swap. Here are the accounts list:
- token_mint_account
- token_program_info
- save_ps_account_input
- save_oop_account_input
- save_balance_lp_account_input: the data account to save
pool_index & coin_index -> balance
pair (8-bytes long to save u64 balance) - ta_lp_input: the token account for lp (the owner of pool_index)
- ta_program_input
- contract_signer_account_input: the account as a singer of the program contract
DepositToPool {
pool_index: u64,
coin_index: u8,
amount: u64,
}
The LP can deposit some tokens to his/her pool. Here are the accounts list:
- payer_account
- system_program
- authorized_account_input: the address to add to LP pools
- token_mint_account
- token_program_info
- save_token_list_account
- save_poaa_account_input
- save_balance_lp_account_input: the data account to save
pool_index & coin_index -> balance
pair (8-bytes long to save u64 balance) - ta_lp_input
- ta_program_input
WithdrawFromPool {
pool_index: u64,
coin_index: u8,
amount: u64,
}
The LP can withdraw some tokens from his/her pool. Here are the accounts list:
- authorized_account_input
- token_mint_account
- token_program_info
- save_token_list_account
- save_poaa_account_input
- save_balance_lp_account_input
- ta_lp_input
- ta_program_input
- contract_signer_account_input
Lock {
encoded_swap: [u8; 32],
signature: [u8; 64],
initiator: [u8; 20],
recipient: Pubkey,
}
The LP can lock the tokens on the target chain, which is the Step 2 of the cross-chain swap. Here are the accounts list:
- payer_account
- system_program
- authorized_account_input
- token_mint_account
- save_si_account_input: the data account to save
swapId -> lockedSwap
pair (48-bytes) - save_token_list_account
- save_poaa_account_input
- save_balance_lp_account_input
- ta_user_input
- ta_program_input
Unlock {
encoded_swap: [u8; 32],
initiator: [u8; 20],
}
The LP can unlock the tokens on the target chain if the user hasn't released the tokens before the specified time. Here are the accounts list:
- save_si_account_input
- save_balance_lp_account_input
Release {
encoded_swap: [u8; 32],
signature: [u8; 64],
initiator: [u8; 20],
}
The user can release the tokens on the target chain, which is the Step 3 of the cross-chain swap. Here are the accounts list:
- payer_account
- system_program
- token_mint_account
- token_program_info
- save_si_account_input
- save_oop_admin_account_input: the data account to save
pool_index=0(the manager) -> authorized address
pair (32-bytes long) - save_balance_manager_account_input: the data account to save
pool_index=0(the manager) & coin_index -> balance
pair (8-bytes long to save u64 balance) - ta_user_input
- ta_program_input
- contract_signer_account_input