September - October 2021
- Added the ability to find and close (release SOL and return to the pool owner's address) unused temporary accounts for calculating collateral
- Made Oxygen even faster with caching layer for market data
- Added cancel button for pending lends
- Pending liabilities cancel button now cancells orders grouped by 3 instead of all orders together
- Dashboard page updated with liquidation info and translations fixes
- Fixed: SOL action amount of deposited funds was subtracted from transaction cost field of the Deposit
- UI minor fixes and updates
- Implemented a set of instructions for close pool and refund SOLs
- Rework fetching data for render pool summary, pool management, my pools page. Now, we get this information directly from Solana on UI instead of backend API. This feature allows users to receive more responsive updates because we can read recent data. Also, in the future, we plan to put in open source our JS client like serum-ts
- Make a lot of fixes on the Trade page:
- Balance sync
- Decimal precision in inputting conversion from / to
- In lend/borrow agreements used clock.timestamp instead of clock.slot
May - July 2021
- Developed UI for adaptive version
- On Pool Management: added borrow re-roll functionality
- Added transaction error dictionary to show readable message instead of error codes
- app.oxygen.org prepared for translation to multiple languages
- Developed UI for pool liquidation summary
- Added tooltips on all important columns for desktop, mobile
- Oxygen now supports external wallets (Sollet.io, Sollet.io extension, Ledger, Phantom, MathWallet).
- Added instruction for the set end date of lend re-roll
- Added instructions for close pool and release allocated space, so all spent SOLs are returned to the pool owner
- Move from clock.slot to clock.unix_timestamp in lend/borrow agreements, so customers can see more precise time instead of a number of slots
- Developed off-chain program for lend, borrow re-rolling
- Implemented pool liquidation by a margin call
- Created liquidator program which can be used in CLI mode (pass the pool address which must be liquidated) or run like a demon which polls API feed
March - April 2021
- Added Local QR generation on web & mobile. Now customer can see which instruction would be executed and how much it costs. See the progress on transactions confirmation process.
- Reworked deposit/withdraw/borrow/repay
- Fixed calculation for available borrow, withdraw values
- Enhanced UI
- [WIP] Start works on adaptive version of app.oxygen.org
- Added support page for report issues
- Added balance structure on PoolManagement page
- Added market stats (TVL) on main page
- LTV / NetYield chart shows correct values
- Change borrow rate for multiples borrows
- Moved to Serum dex v3 in lending, spot trading functions
- Added running “event queue” for settle operation after trade between
Necessary for lending market crank
- Added protocol base currency as entity (USDC)
- Added borrow reroll instruction
- Added borrow change rate instruction
- Improved oxygen test kit for support liquidation test cases
- Developed service for monitoring pools which should be liquidated
- Developed rust client for oxygen protocol
January - February 2021
- Liquidation discount based on how many liabilities must be liquidated
- Tests for liquidation happy path
- JS Client for liquidation instructions
- Make tests for trade module
- Fix bugs for pool balance held amount in trade
- Add validation on max available to trade
- Test on withdrawing for assets with zero iltv
- Make it possible to run pool viability accounting in parallel for liquidators race purpose
- Ability to change price oracle program vendor
- Change protocol asset risk params
- Add unique error codes for each instruction
- Store oxygen fee in full scale instead of native asset decimal
- Fix from cargo clippy recommendation
- Add field updated_at_slot for caching pool state
- Use solana_program instead of solana_sdk
- TestKit for remove boilerplate code in tests
- State versioning
- Make able to enter on trade page and choose any asset pair
- Add orders summary tab
Pool assets balance structure
- Stopped wait for trx confirmation on backend check only from Solana
- Add i18n to support more languages
- Fix various bugs with pool management & trade pages
- Developing oxygen client on java lang for infrastructure services
- Read events about oxygen pools transaction directly from Solana (socket, http)
- Read prices from price oracle on every price update
- Read pool state directly from Solana
- [API] Calculation pool state on the backend side
- [API] In case of unavailability Solana fetch pool data from the cache
- QR transaction service rework to guaranteeing more stability
QACreate selenium tests for:
- Creating pool & wallet
- Deposit assets to pool with various lend out, APR rate settings
- Withdraw assets from the pool
Instant assets exchange
Previously, all liquidators had to wait until the end of liquidation to receive bought pool assets(proportional). In the new version, the liquidator can immediately acquire funds from the pool under liquidation.
We have implemented the exchange state for store information about amount of bought pool assets and the number of tokens he had already drawn from the pool. Each exchange state stores in a separate address.
Default scenario (debt overdue)
We have implemented a liquidation scenario, which occurs if the pool is overdue on its loan. In this scenario, the liquidation initiator provides an agreement book on which the pool has an outstanding debt. In the course of liquidation, the pool must, first of all, pay off all overdue debts. It is also important to note that as in the case of margin call the liquidation pool LTV will be decreased to reset LTV value if it exceeds it.
Liquidation discount table specific for each asset
Based on the size of the position, estimated daily move (based on a weighted average of short-term and medium-term intraday move)
Discount is calculated for the amount required for liquidation and is distributed proportionally among all liquidators depending on the provided liquidator's value.
Reward system for liquidation initiator
To quickly start the liquidation process, we have developed a bonus system for the user who began the liquidation.
- The initiator can carry out liquidation on his own until X slots have passed since the moment the pool was transit to the liquidation state. X slots are specified in the protocol settings.
- The initiator also receives a liquidation discount from the amount that came out due to the netting step.
This module implements Serum DEX trading with available (funds that are not in lent out or held) pool assets. The exchange can be made for any protocol assets, even if it was not already in the pool before. An essential part of risk management is that with trade, the LTV pool indicator does not change. We have done it by adding a new concept of asset hold to the balance sheet. As the asset hold value increases, the available amount decreases and vice versa. In this case, the hold is not taken into account to calculate the protocol's risk indicators.Available operations:
- Place a new order
- Cancel exists order
Also added a vault to the protocol to get a rebate fee when executing the settle instruction.
Reset loan to value
Added parameter reset LTV. This parameter is the target LTV ratio to be achieved after exiting liquidation.
Support borrowing operation for high-risk assets.
Now assets that have a high risk can be added to the oxygen protocol, which does not allow them to be used as collateral, but at the same time, users can borrow them. To do this, when adding a new asset, protocol owner must set the initial LTV to 0%.
Previously, the protocol determined buying power value (USDC) based on calculations for the current pool state, which could lead to the fact that iLTV could increase and make it possible to borrow even more. The new formula considers the iLTV borrowed asset and limits the maximum allowable amount within a given asset.
We have developed a possibility to provide information about changes in the internal states (of the pool) within the statement. It generates events (for example, which reflect changes in the state of assets/liabilities). These events are encoded in base64 and sent to transaction log. After that, the client, upon receiving the transaction, can perform deserialization followed by data processing. This mechanism allows you to enrich transactions with useful meta information for building statistics and a detailed history of the pool.
Fault tolerance for data read ops.
We have implemented a possibility to ensure the availability of reading data on the states of the pools of the oxygen system, regardless of Solana node rpc health. Now we have a mechanism based on the consume event oxygen protocol, which reflects the pool's state to the last received event in the pool. Using this data source instead of requesting directly from the Solana node also significantly speeds up page loading. Since the data is stored in reading optimized structures, it can be displayed on the pools, pool detail pages and does not require creating dozens of queries to collect all the necessary data about the pool assets.
- Added output to transaction log error detail, before that the client received only error_code
- For operations cancel all lend/borrow orders; you can now specify a limit. Previously, the instruction tried to cancel all orders, but hypothetically it could reach the limits of the maximum number of vm instructions.