Skip to main content

Synthetics

User can join enters the debt pool by minting synthetic assets . To do it, they need to deposit some collateral first.

Debt#

Debt is stored as debt_shares in ExchangeAccount. To convert it to the actual amount, fraction got by dividing user's debt_shares by total amount of debt_shares from state has to be multiplied by total debt calculated from the sum of supplies of minted tokens (excluding borrowed and swapline supplies).

Total debt is calculated here as a sum of all minted assets converted to USD.

Interest rate#

Every time total debt is calculated, interest rate is added to it. It's compounded of every minute since last_debt_adjustment stored in state.

Max debt#

The maximum amount of debt a user can have before they can be liquidated.

Mint limit#

The maximum amount of tokens a user can mint is their mint limit. It's calculated by multiplying max debt by health factor

Mint#

A user can get xUSD by minting it. Afterward, it can be swapped for other synthetics. The method responsible for minting is defined here. It checks if the sum of debt and amount is less than mint_limit and if so, mints token to the specified account.

It takes amount (u64) and following context

struct Mint<'info> {
pub state: Loader<'info, State>,
pub assets_list: Loader<'info, AssetsList>,
pub exchange_authority: AccountInfo<'info>,
pub usd_token: Info<'info, anchor_spl::token::Mint>,
pub to: Account<'info, TokenAccount>,
pub token_program: AccountInfo<'info>,
pub exchange_account: Loader<'info, ExchangeAccount>,
pub owner: AccountInfo<'info>,
}
  • state - account with data of the program
  • assets_list - list of assets structured as this
  • exchange_authority - pubkey of the exchange program
  • usd_token - address of xUSD token
  • to - account, to which xUSD is minted
  • token_program - address of Solana's Token Program
  • exchange_account - account with user's data
  • owner - owner of the exchange account

Burn#

User can burn only xUSD. Burning reduces user's debt and allows them to withdraw tokens used as collateral. Burning tokens reduces rewards in current_round. Method responsible for burning is defined here. It takes amount (u64) and this context:

struct BurnToken<'info> {
pub state: Loader<'info, State>,
pub exchange_authority: AccountInfo<'info>,
pub assets_list: Loader<'info, AssetsList>,
pub token_program: AccountInfo<'info>,
pub usd_token: Account<'info, anchor_spl::token::Mint>,
pub user_token_account_burn: Account<'info, TokenAccount>,
pub exchange_account: Loader<'info, ExchangeAccount>,
pub owner: AccountInfo<'info>,
}
  • state - account with data of the program
  • exchange_authority - pubkey of the exchange program
  • assets_list - list of assets structured as this
  • token_program - address of Solana's Token Program
  • usd_token - address of xUSD token
  • user_token_account_burn - account, from which tokens will be burned
  • exchange_account - account with user's data
  • owner - owner of the exchange account

Swap#

Synthetic tokens can be swapped in the Exchange. The fee is 0.3% for all pairs and is fixed. Having SNY as collateral gives the user a discount.

Discount#

Discount is calculated here as a percentage of fee.

0-100 => 0%
100-200 => 1%
200-500 => 2%
500-1,000 => 3%
1,000-2,000 => 4%
2,000-5,000 => 5%
5,000-10,000 => 6%
10,000-25,000 => 7%
25,000-50,000 => 8%
50,000-100,000 => 9%
100,000-250,000 => 10%
250,000-500,000 => 11%
500,000-1,000,000 => 12%
1,000,000-2,000,000 => 13%
2,000,000-5,000,000 => 14%
5,000,000+ => 15%

Swap method#

Method responsible for swap is defined here. It burns one token, charges fee and mints reduced amount of the other token. It takes amount (u64) and a following context:

struct Swap<'info> {
pub state: Loader<'info, State>,
pub exchange_authority: AccountInfo<'info>,
pub assets_list: Loader<'info, AssetsList>,
pub token_program: AccountInfo<'info>,
pub token_in: Account<'info, anchor_spl::token::Mint>,
pub token_for: Account<'info, anchor_spl::token::Mint>,
pub user_token_account_in: Account<'info, TokenAccount>,
pub user_token_account_for: Account<'info, TokenAccount>,
pub exchange_account: Loader<'info, ExchangeAccount>,
pub owner: AccountInfo<'info>,
}
  • state - account with data of the program
  • exchange_authority - pubkey of the exchange program
  • assets_list - list of assets structured as this
  • token_program - address of Solana's Token Program
  • token_in - token, which is sent to the Exchange
  • token_for - token, which is sent back to the user
  • user_token_account_in - user's account, from which tokens will be taken
  • user_token_account_for - user's account, to which tokens will be sent
  • exchange_account - account with user's data
  • owner - owner of the exchange account

Settlement#

Admin can set a settlement slot (stored in the state). When it is reached (or passed), settlement will be triggered.

Settlement data#

Data needed for settlement is stored in this structure:

struct Settlement {
pub bump: u8,
pub reserve_address: Pubkey,
pub token_in_address: Pubkey,
pub token_out_address: Pubkey,
pub decimals_in: u8,
pub decimals_out: u8,
pub ratio: Decimal,
}
  • bump - seed used to ensure the generated address doesn't collide with any other existing one
  • reserve_address - account belonging to the exchange, where deposited collateral is kept
  • token_in_address - token, which was settled
  • token_out_address - token, in which settlement will be sent (equal to xUSD token)
  • decimals_in - number of decimal places in the settled token
  • decimals_out - the number of decimal places in the target token
  • ratio - ratio of prices of both tokens at the moment of settlement (for xUSD just price of token)

Swapping settled synthetic#

Method swap_settled_synthetic is defined here. It gets specified amount and uses below structure to swap it for xUSD. It takes single number amount (u64) and a following context:

struct SwapSettledSynthetic<'info> {
pub settlement: Loader<'info, Settlement>,
pub state: Loader<'info, State>,
pub token_to_settle: Account<'info, anchor_spl::token::Mint>,
pub user_settled_token_account: Account<'info, TokenAccount>,
pub user_usd_account: Account<'info, TokenAccount>,
pub settlement_reserve: Account<'info, TokenAccount>,
pub usd_token: Account<'info, anchor_spl::token::Mint>,
pub exchange_authority: AccountInfo<'info>,
pub token_program: AccountInfo<'info>,
pub signer: AccountInfo<'info>,
}
  • settlement - Settlement structure with data needed for settlement (about settlement data)
  • state - account with data of the program
  • token_to_settle - address of the settled token
  • user_settled_token_account - user's account with settled tokens belonging to the user
  • user_usd_account - user's account with xUSD
  • settlement_reserve - account, from which xUSD is transferred (specified in Settlement structure)
  • usd_token - address of xUSD token
  • exchange_authority - pubkey belonging to the program
  • token_program - address of Solana's Token Program
  • signer - owner of the account with settled tokens