The protocol needs a place to store persistent data. Most of it is stored inside the State structure, that is passed to methods just like any other account.
State is structured like this:
Respectively, these fields are :
- admin - pubkey of the admin. Only admin can modify state using setters
- halted - if set to true, access to methods is blocked
- nonce - one of the seeds of the exchangeAuthority. Used to sign transactions
- debt_shares - total amount of debt shares. Together with user debt shares, it allows calculating debt. More on that here
- assets_list - address used to confirm the correctness of asset list passed to a method
- health_factor - ratio of mint limit to max debt as a decimal
- max_delay - maximum amount of slots a price can be outdated by
- fee - percentage paid as a fee on swap
- swap_tax_ratio - percentage of the fee going to the tax reserve
- swap_tax_reserve - part of the total amount of charged tax. Can be withdrawn by admin
- liquidation_rate - maximum part of user's debt repaid on liquidation
- penalty_to_liquidator - penalty on liquidation going to the user that is liquidating
- penalty_to_exchange - liquidation penalty going to liquidation fund
- liquidation_buffer - number of slots between exceeding max debt and liquidation
- debt_interest_rate - amount of interest rate charged on debt (yearly percentage, charged minutely)
- accumulated_debt_interest - total amount charged as interest
- last_debt_adjustment - timestamp of the last charge of interest
- staking - structure with all data needed for staking. Details are here
- exchange_authority - pubkey belonging to the exchange, used to sign transactions
- bump - seed used to ensure the generated address doesn't collide with any other existing one
- padding - used as padding to reserve space up to 2kB for future use
The state is initialized here. It can be changed later using admin methods signed by the admin.
All assets used in the platform are stored here. Data about prices comes from Pyth and is aggregated here. It also keeps data about decimal point's placing, addresses of tokens and total supply.
Data related to assets is kept inside AssetsList:
The first three are indexes of corresponding arrays, pointing to the last element and used as length. The next three keep data and are described below:
Synthetify uses Pyth oracles to get accurate prices of all assets and stores them in one place for ease of use. Data related to the prices is kept inside Asset structure:
- feed_address - address of Pyth oracle account
- price - price multiplied by 10 to the power of PRICE OFFSET equaling 8
- last_update - the slot of the last price update
- twap - stands for Time-weighted average price
- twac - stands for Time-weighted average confidence
- status - status taken from oracle and saved as PriceStatus. Tokens can be swapped only if status is equal to 1
- confidence - confidence interval representing asset's price uncertainty. The tighter the interval the lower possible price variation.
Every collateral and synthetic asset has to have a corresponding Asset but they can share it. For example, BTC and xBTC will have common Asset as they share the same price.
Data representing collateral is stored inside a Collateral structure:
- asset_index - index of the corresponding asset used to get its price
- collateral_address - address of a token used as collateral
- reserve_address - address of an account, where the exchange keeps deposited tokens
- liquidation_fund - address of an account, where liquidation penalty is kept until it is withdrawn
- reserve_balance - amount of tokens in the reserve account
- collateral_ratio - ratio of collateral to debt user can have
- max_collateral - maximum amount that can be used as collateral
Synthetic assets created by Synthetify keep their data inside this structure:
- asset_index - index of the corresponding asset
- asset_address - address of the synthetic token
- supply - total amount of minted tokens
- max_supply - limit of tokens that can be minted. It exists to increase safety of the platform (can be changed by the admin)
- borrowed_supply - amount of tokens minted using vaults
- swapline_supply - amount of tokens swapped using the swapline
- settlement_slot - slot, when an asset will have a settlement (never by default)
AssetsList can be fetched by using:
Where the exchange is an instance of Exchange singleton. The argument of the assetsList is PublicKey, which can be found in the state. The whole structure is similar, but arrays are trimmed to the correct length.
In many places in the Synthetify code, there is a need for numbers with decimal point, ie. fractions of tokens, the interest rate percentage. To avoid floating point numbers Decimal was created.
Here val is the value of the decimal. Scale can be interpreted as a position of the point in decimal notation. Val can be divided by 10 to the power of scale to get a regular number.
To make Decimal easier to use it also contains a few methods defined here, ie. simple math methods like add and div and their rounding up counterparts like mul_up. It also contains few factory methods like from_price and from_percent.
Inside SDK, Decimal is stored as a simple object of the following interface: