logo

OneDex

Published on

OneDex

Website: https://onedex.app

DApp: https://swap.onedex.app

Github: Private

Audit Status: Arda Private Audit Report

1. Summary

  • Permissionless DEX that is accessible to everyone within and outside of MultiversX ecosystem.
  • Uniswap v2 AMM(Automated Market Maker) platform for cryptocurrency trading.
  • All-in-One DeFi provider including Swap, Farms, Staking, Launchpad and Bridge.

2. Responsibility

As a Rust Blockchain Lead Developer, I had built smart contract for OneDex.

The following code is the swap function of OneDex smart contract.

multiversx_sc::imports!();
multiversx_sc::derive_imports!();

use crate::constants::{ TOTAL_PERCENT };
use crate::proxy;

#[multiversx_sc::module]
pub trait SwapLogicModule:
    crate::storage::common_storage::CommonStorageModule
    + crate::storage::pair_storage::PairStorageModule
    + crate::logic::common::CommonLogicModule
    + crate::logic::amm::AmmLogicModule
    + crate::logic::liquidity::LiquidityLogicModule
    + crate::event::EventModule
{
  /**
    * SWAP Fixed Input
    */
  fn swap_fixed_input(
    &self,
    token_in: &TokenIdentifier,
    token_out: &TokenIdentifier,
    amount_in: &BigUint,
    old_reserve_in: &BigUint,
    old_reserve_out: &BigUint,
    fee_in: bool,
  ) -> (BigUint, BigUint, BigUint) {
    let total_fee_percent = self.total_fee_percent().get();

    if fee_in {
      let total_fee_amount = amount_in * &BigUint::from(total_fee_percent) / &BigUint::from(TOTAL_PERCENT);
      let left_amount_in = amount_in - &total_fee_amount;
      let left_fee_amount = self.manage_special_fee(token_in, &total_fee_amount);

      let amount_out = self.get_amount_out_no_fee(&left_amount_in, old_reserve_in, old_reserve_out);
      let new_reserve_in = old_reserve_in + &left_amount_in + &left_fee_amount;
      let new_reserve_out = old_reserve_out - &amount_out;

      (amount_out, new_reserve_in, new_reserve_out)
    } else {
      let amount_out = self.get_amount_out_no_fee(amount_in, old_reserve_in, old_reserve_out);
      let total_fee_amount = amount_out.clone() * &BigUint::from(total_fee_percent) / &BigUint::from(TOTAL_PERCENT);
      let left_amount_out = amount_out.clone() - &total_fee_amount;
      let left_fee_amount = self.manage_special_fee(token_out, &total_fee_amount);

      let new_reserve_in = old_reserve_in + amount_in;
      let new_reserve_out = old_reserve_out - &amount_out + &left_fee_amount;

      (left_amount_out, new_reserve_in, new_reserve_out)
    }
  }
}

3. Technical Overview

3.1 Automated Market Maker

There are two main types of decentralized exchanges:

  • Order Book DEX: This type of DEX uses an order book system to match buyers with seller, a process very similar to how the underlying mechanics of a centralized exchange works. Orders are placed to the order book and once they are matched with a sufficient offer, the order is then completed as a mutual agreement is reached.
  • Automated Market Maker (AMM) DEX: This type of DEX uses algorithms to automatically match buyers and sellers without the need for an order book style system. Prices of an asset are determined by suppy and demand, controlled by market dynamics.

OneDex had been designed and built as an Automated Market Maker DEX (AMM).

Constant Product Formula

The success of AMMs revolves around a simple mathematical formula. The most common of these was proposed by Ethereum's co-founder Vitalik Buterin.

token_a_balance * token_b_balance = k and more commonly popularised within the DeFi industry as: x * y = k

constant product formula

3.2 DeFi Services

The complete package that OneDex offers to new ESDT projects building on MultiversX is not solely limited to the swap function.

In addition to this essential function, OneDex also offers the ability for teams to setup and enable the following:

  • Yield Farming
  • ESDT Staking
  • ESDT Launchpad
  • Bridge (MultiversX-Solana)

The most important aspect of OneDex DeFi services is permissionless: Anybody can list their tokens and create their pools. Try yourself

It is also integrated with DefiLlama.

4. Challenge

Protocol security is of primary importance to the OneDex team and to investors entrusting their funds in the OneDex project.

To ensure that a high level of security is maintained throughout the development, testing and operational phases of the OneDex platform, ARDA's auditing services have been utilized to ensure that all Smart Contracts are watertight in design and final deployment, ready for sale community use.

The following code is the multiversx_sc_scenario test cases.

mod contract_setup;
mod contract_interactions;

use contract_setup::*;
use multiversx_sc_scenario::DebugApi;

mod constant;
use constant::*;
use num_traits::FromPrimitive;

use std::ops::Mul;

use multiversx_sc::types::BigUint;

use multiversx_sc_scenario::{rust_biguint};


#[test]
fn init_test() {
    let _ = OneDexContractSetup::new(onedex_sc::contract_obj, multiversx_wegld_swap_sc::contract_obj);
}

#[test]
fn create_pair_test() {
    let _ = DebugApi::dummy();

    let mut sc_setup = OneDexContractSetup::new(onedex_sc::contract_obj, multiversx_wegld_swap_sc::contract_obj);

    let pair_owner = sc_setup.setup_new_user(1u64);
    let big_zero = rust_biguint!(0);

    let first_token_id = ONE_TOKEN_ID;
    let second_token_id = WEGLD_TOKEN_ID;

    sc_setup.create_pair(&pair_owner, first_token_id, second_token_id);

    sc_setup.check_pool_state(1, &pair_owner, first_token_id, second_token_id, big_zero.clone(), big_zero.clone(), big_zero.clone());
}