This repository contains smart contracts for Hikaru Dex.
Hikaru finance is DeX platform that enables integration of any imaginable DeX project as long as it follows implements pre-defined interfaces.
This repository contains following:
-
Smart contracts:
-
Tests for smart contracts:
Basic smart-contract system structure:
┌────────┐ ┌────────────┐ Pool creation
│ User │ │Pool Factory├────────────────────────────────┐
└───┬────┘ │ contract │ │
│ └─┬─────────▲┘ │
│ request │ │ │
│ to information│ │Checking │
│ perform about │ │ wether ┌───▼───┐
│operation new │ │ pool │ Pools │
│ pools │ │ is └▲─────┬┘
│ │ │ from calculation│ │calculation
│ │ │ known request │ │ result
│ │ │factory │ │
┌───▼────┐ user request ┌▼─────────┴┐ │ │
│ Router └──────────────────────► Vault └─────────────────────────────┘ │
│contract◄──────────────────────┐ contract ◄───────────────────────────────────┘
└────────┘ user request result └┬─────────▲┘
│ │
transfers│ │balance
│ │ info
│ │
┌▼─────────┴┐
│ TRC20 │
│ token │
└───────────┘
Pool contracts are parameter storage and calculators of the system. They implement required math and store parameters that are specific to the pool.
Pools consist of 3 components:
┌──────────────────────┐
│ Pool's storage │
│ │
├──────────────────────┤
├──────────────────────┤
│ Pool's math library │
│ │
├──────────────────────┤
├──────────────────────┤
│ Pool's layer for │
│interacting with vault│
└──────────────────────┘
Where:
- Pool's storage -> storage that hold constant parameters that are set during pool creation process and parameters that can be changed (swap fee coefficient, manager address)
- Pool's math library -> library that implements calculations logic
- Pool's layer for interacting with vault -> this layer performs pre-checks, ensures that correct parameters are passed to math library and interacts with vault
All interactions with pool are done in following manner:
Get required paramters ┌──────────────┐
┌───────────────────────────────────► │
│ │Pool's storage│
│ ┌───────────────────────────┤ │
│ │ Return parameters └──────────────┘
│ │
┌─────┐ Calculation request ┌─┴───────▼─┐
│ ├───────────────────────────►Interaction│
│Vault│ │ │
│ ◄───────────────────────────┤ Layer │
└─────┘ Calculation result └─▲───────┬─┘
│ │ Calculate with provided
│ │ and checked parameters ┌─────────────┐
│ └────────────────────────────► Pool's math │
│ │ │
└────────────────────────────────────┤ library │
Return calculation └─────────────┘
results
Step-by-step description:
- Valid request is received from Vault smart-contract
- Interaction layer receives request and pre-processes it - checks that parameters are valid and brings them to the right form for math library
- With known parameters math library performs calculations and returns results to interaction layer
- Results are returned to the vault that requested calculations by interaction layer
Pools allow performing operations only through vault. If any other contract/user tries to call contract to perform operation - transaction will fail.
┌─────────────┐ Operation forbidden ┌────┐
│ Random user ├──xxxxxxxxxxxxxxxxxxx──► │
└─────────────┘ │ │
│ │
│Pool│
┌─────────────┐ │ │
│Corresponding│ Operation permitted │ │
│ Vault ├───────────────────────► │
└─────────────┘ └────┘
Vault contracts are token-storages for pools and are gateways to interact with pools.
Developed vault consists of:
┌────────────────┐
│ Vault's storage│
├────────────────┤
├────────────────┤
│ Pool's balances│
│ storage │
├────────────────┤
├────────────────┤
│ Layer for pools│
│ interaction │
├────────────────┤
├────────────────┤
│ Layer for user │
│ interaction │
├────────────────┤
├────────────────┤
│ Flashloans │
└────────────────┘
Where:
- Vault's storage -> stores vault-specific variables
- Pool's balance storage -> stores and modifies pool balances
- Layer for pools interaction -> implements interaction with pools for performing calculations
- Layer for user interaction -> implmenets interaction with users via standart interfaces
- Flashloans -> vault allows users to use this tool using implemented interfaces
Vaults track and store balances of pools, so in vault's token balance consists of pool's token balances:
┌────────────────────────────┐
│ ┌───────┐ │
│ │ Pool1 │ │
│ │virtual│ │
│ │ token │ │
│ │balance│ │
│ ├───────┤ │
│ │ Pool2 │ │
│ │virtual│ │
│ Vault │ token │ │
│ token │balance│ │
│ balance ├───────┤ │
│ │ ..... │ │
│ ├───────┤ │
│ │ PoolN │ │
│ │virtual│ │
│ │ token │ │
│ │balance│ │
│ └───────┘ │
└────────────────────────────┘
Pools in this system have virtual tokens balances, but it may depend on implementation.
While processing operations vaults perform following operations:
- Transfer tokens to/from user
- Calls pool to calculate operation result
- Transfer tokens to/from user (as operation result)
┌─────┐ Calculation request to pool ┌────┐
│ ├─────────────────────────────────► │
│Vault│ │Pool│
│ ◄─────────────────────────────────┤ │
└┬───▲┘ Calculation result └────┘
│ │
│ │ token balances ┌─────┐
│ └──────────────────────────────────┤ │
│ │ERC20│
│ transfer operations │token│
└──────────────────────────────────────► │
└─────┘
Vaults can only interact with pools that were created by known factory:
┌───────┐ Pool creation
│Unknown├───────────────────────┐
│facotry│ │
└───────┘ │
│
┌────▼────┐
│Pool from│
┌─xxxxxxxxx─► unknown │
│ │ factory │
│ └─────────┘
┌───────┐ │
│ Vault ├──────┤
└───┬───┘ │
│ │
Pool │ │ ┌─────────┐
origin │ │ │Pool from│
check │ └───────────► known │
│ │ factory │
│ └────▲────┘
┌───▼───┐ │
│ Known │ Pool creation │
│factory├───────────────────────┘
└───────┘
Pool factory contracts are contracts that create new pools and can confirm that pool was deployed by factory.
When new pool is created, factory calls vault to register new pool. During this call vault performs necessary preparations for pool to function correctly.
┌───────┐ New pool registration ┌─────┐
│Factory├────────────────────────────►Vault│
└───────┘ └─────┘
Router contracts are used as single entry point for users to intract with system, reducing amount of required approvals for tokens and performing required checks.
┌─────────────┐ ┌────────────┐
│ │ │Pool1 type 1│
┌──►Vault type 1 ├──►... │
│ │ │ │PoolN type 1│
│ ├─────────────┤ ├────────────┤
┌──────┐ ┌──────┐ │ ├─────────────┤ ├────────────┤
│ │ │ │ │ │ │ │Pool1 type 2│
│ User ├───►Router├─┼──►Vault type 2 ├──►... │
│ │ │ │ │ │ │ │PoolN type 2│
└──────┘ └──────┘ │ ├─────────────┤ ├────────────┤
│ ├─────────────┤ ├────────────┤
│ │ │ │Pool1 type 3│
└──►Vault type 3 ├──►... │
│ │ │PoolN type 3│
└─────────────┘ └────────────┘
User perspective:
- User sets allowances for tokens to router
- User calls router to perform operation
- Router checks if Vault can perform selected operation using IERC165
- Router transfers tokens from user
- If necessary router performs calculations for operation
- Router calls vault with receiver set to msg.sender so user will receive operation result tokens
Router smart contract: TYqRA6CyCYMTwzZv7hSotiudMRxMHJBZKY
Vault smart contract: TUw7TvNHGZJGMFm3RxUtKxYfBKafVHVFBf
Factory smart contract: TXrsYxtgenb722F8sWJkR8HH3diSBEWtrn
Pool smart contracts:
- TQyKsMAHNNL4fypUJzc8wy9m5zGk5jxcKA
- TWYniMuTc11cW9Sk6gY5NAbKoq7Lpmot3T
- TDe1yuD647gM9bfmwLsZBHS1g1JpWVtJ4V
TRC20 token contracts:
- TApJzmfyYrXd6afvfWLKpqqeBxa7hwS9Cw
- TH9pNgBcqsSV6NNGQr1EHRbnQ29RJQipA1
- TAHLygq9zmpSASCkwvExVgxNfGMwjuqQ1u
- TSF96eswa74vJPpeUuPt9mGdPhs5Ahooi4
There are specific tweaks in system to operate with tokens that implement comission on transfers.
To deal with the problem of difference in passed parameter and real transfer sum, contracts use calculated values as results of token transfers:
- If transferFrom() is called than received amount is calculated as:
receivedAmount = balanceAfter - balanceBefore
- If transfer() is called than transferred amount is calculated as:
transferredAmount = balanceBefore - balanceAfter
You will need to account for this when using tokens with comissions.
balanceOf() ┌─────┐ balanceOf()
┌──────────────┤ERC20├───────────────┐
│ │token│ │
│ └──┬──┘ │
│ │ │
│ │ │
│ │ │
┌───▼───┐ ▼ ┌───▼───┐
│Initial│ transfer operation │ Final │
│ token ├────────────────────────────► token │
│balance│ (transferFrom/tranfer) │balance│
└───┬───┘ └───┬───┘
│ │
│ ┌───┐ │
└───────────────►-/+◄────────────────┘
└─┬─┘
│
┌─────────▼──────────┐
│received/transferred│
│ amount of tokens │
└────────────────────┘
You can find smart contract error descriptions here: Errors