Factory is a utility contract used by front application and other contracts to get the code of a pool contract or a farm contract.
get_pool_code(token1_address, token2_address, pool_address, lp_token_address, state_address)Return the code to create a pool for a pair of tokens.
token1_addressis the first token address of the pairtoken2_addressis the second token address of the pairpool_addressis the genesis address of the pool chainlp_token_addressis the address of the lp token (it should be the creation address of the pool)state_addressis the address holding the state of a pool (will be soon removed)
get_farm_code(lp_token, start_date, end_date, reward_token, farm_genesis_address)Return the code to create a farm for a LP token and a reward token.
lp_tokenis the lp token to provide in the farmstart_dateis the timestamp (in sec) where the farm starts to give reward (should be between 2 hours and 1 week from farm creation date)end_dateis the timestamp (in sec) where the farm ends to give reward (should be between 1 month and 1 year from start date)reward_tokenis the reward token address or "UCO"farm_genesis_addressis the genesis address of the farm contract chain
get_lp_token_definition(token1_address, token2_address)Return the lp token definition to use when creating a pool. Returns a JSON stringified
token1_addressis the address of the first tokentoken2_addressis the address of the second token
Pool is the main contract of the AMM model. It hold the liquidity of a pair of token and expose all functionnality to add / remove liquidity and swap.
get_pool_infos()Returns infos of the pool as:
{
"token1": {
"address": "00001234...",
"reserve": 1021.45
},
"token2": {
"address": "00005678...",
"reserve": 894.565
},
"lp_token": {
"address": "0000ABCD...",
"supply": 950.45645
},
"fee": 0.25,
"protocol_fee": 0.25,
"stats": {
"token1_total_fee": 0.025,
"token1_total_protocol_fee": 0.025,
"token1_total_volume": 10,
"token2_total_fee": 0.075,
"token2_total_protocol_fee": 0.075,
"token2_total_volume": 30
}
}In next function, token1 and token2 represent the one returned by this function
get_equivalent_amount(token_address, amount)Returns the equivalent amount of the other token of the pool. This should be used in the process of adding liquidity
token_addressis the token you want to provide (result amount will be the other token)amountis the amount of token_address you want to provide
get_ratio(token_address)Returns the pool ratio
token_addressis the token you want to provide (result amount will be the other token)
get_lp_token_to_mint(token1_amount, token2_amount)Returns the amount of LP token that will be minted if the amount of tokens are provided
token1_amountAmount of token1 to providetoken2_amountAmount of token2 to provide
get_output_swap_infos(token_address, input_amount)Returns the info about a swap: expected output_amount, fee and price impact
token_addressOne of the 2 tokens of the poolinput_amountAmount of this token you want to swap
{ "fee": 0.006, "protocol_fee": 0.003, "output_amount": 1.48073705, "price_impact": 0.997 }get_input_swap_infos(token_address, output_amount)Returns the info about a swap: expected input_amount, fee and price impact
token_addressOne of the 2 tokens of the pooloutput_amountAmount of this token swapped
{ "fee": 0.006, "protocol_fee": 0.003, "input_amount": 1.48073705, "price_impact": 0.997 }get_remove_amounts(lp_token_amount)Returns amounts of token to get back when removing liquidity
lp_token_amountNumber of lp token to remove
{ "token1": 11.662465, "token2": 8.54834787 }add_liquidity(token1_min_amount, token2_min_amount)This action allow user to add liquidity to the pool. User must send tokens to the pool's genesis address. The amounts sent should be equivalent to the pool ratio. User can specify a slippage tolerance by providing the minimum amount by token that the pool can use. If there is more fund sent by the user than the needed liquidity, the excedent is returned to the user. In exchange of the liquidity, the user will receive some LP token.
token1_min_amountis the minimum amount of token1 to add in liquiditytoken2_min_amountis the minimum amount of token2 to add in liquidity
remove_liquidity()This action allow user to remove the liquidity he previously provided. User must send the lp token he wants to remove to the burn address ("000...000") (don't forget to add the pool in recipient otherwise lp token will only be burned). The pool will calculate the share of the user and return the corresponding amount of both pool tokens.
swap(min_to_receive)This action allow user to swap a token of the pool against the other token. User must send the input token to the pool's genesis address. The pool will calculate the output amount and send it to the user. User can specify a slippage tolerance by providing the minimum amount of the output token to receive.
min_to_receiveis the minimum amount of the output token to receive
update_code()This action can be triggered only by the Router contract of the dex. It allow the Router to request the pool to update it's code. The pool will request the new code using the function get_pool_code of the Factory (see above).
set_protocol_fee(new_protocol_fee)This action can be triggered only by the Master chain of the dex. It allow to update the protocol fee of the pool.
Farm is a contract allowing users to deposit lp token from a pool and to receive reward for a period of time.
get_farm_infos()Returns the informations of the farm
{
"lp_token_address": "0000ABCD...",
"reward_token": "00001234...", // or "UCO"
"start_date": 1705500842,
"end_date": 1705912842,
"remaining_reward": 123456.789,
"lp_token_deposited": 456123.987235,
"nb_deposit": 132,
"stats": {
"reward_distributed": 1234.65657
}
}get_user_infos(user_genesis_address)Returns the informations of a user who has deposited lp token in the farm
{
"deposited_amount": 456123.789456,
"reward_amount": 12.456339
}deposit()This action allow user to deposit lp token in the farm. User must send tokens to the farm's genesis address. It's fund will be hold by the contract and could be reclaimed using withdraw action. The user will gain reward each second based on the reward amount and it's share of the farm. The reward can be claimed using the claim actions.
A user can deposit multiple time in the same farm, or in multiple farms.
claim()This action allow user to claim all the reward he earned since he deposited in the farm or since it's last claim.
withdraw(amount)This action allow user to withdraw all or a part of it's deposited lp token. In the same time is also claim it's earned rewards.
amountis the amount the user wants to withdraw
udpate_dates(new_start_date, new_end_date)This action can be triggered only by the Master address of the dex. The farm will update the start and end date.
update_code()This action can be triggered only by the Router contract of the dex. It allow the Router to request the farm to update it's code. The farm will request the new code using the function get_farm_code of the Factory (see above).
This farm allows users to lock their LP tokens for a given time in order to receive rewards.
get_farm_infos()Returns the informations of the farm
{
"lp_token_address": "0000ABCD...", // LP Token Address
"reward_token": "00001234...", // Reward token address or "UCO"
"start_date": 1705500842, // Unix timestamp
"end_date": 1705912842, // Unix timestamp
"remaining_reward": 123456.789, // Amount of rewards remaining
"rewards_distributed": 4523.97235, // Amount of rewards already distributed
"available_levels": { // an enumeration (string (level) ⇒ end date)
"1": 1750829615,
// ...
},
"stats": {
"1": {
"weight": 0.013, // Weight of this level
"deposits_count": 1344.454, // Current count of deposits on this level
"lp_tokens_deposited": 34553, // Current amount deposited on this level
"remaining_rewards": 3564332.333, // Remaining rewards for this level (based on current distribution)
},
// ...
}
}get_user_infos(user_genesis_address)Returns the deposits' details of a given user.
[
{
"id": "1725136117", // Deposit's identifier
"amount": 1213.456339, // Amount locked
"reward_amount": 33.45, // Current rewards accumulated
"start": 1750829615, // Timestamp lock begin
"end": 1782365634, // Timestamp lock end
"level": "3", // Current level
},
// ...
]deposit(level :: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "max")level: Determine the lock duration
This action allow users to deposit LP tokens in the farm. Users must send LP tokens to the farm's genesis address. Users may deposit multiple times. Deposits may be merged together for optimisation.
note: max can be used when there is less than 3 years remaining to ensure the lock ends with the farm's end.
claim(identifier :: string)identifier: Deposit's identifier
This action allow users to claim a single deposit's rewards. The LP tokens remains in the deposit. The deposit must be unlocked.
withdraw(amount :: float, identifier :: string)amount: Amount of LP tokens to withdrawidentifier: Deposit's identifier
This action allow users to withdraw partially or entirely a deposit. The deposit must be unlocked.
relock(level :: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "max", identifier :: string)level: Determine the lock durationidentifier: Deposit's identifier
This action allow users to update a deposit. It can only expand the lock duration. Accumulated rewards are transferred to the user.
note: max can be used when there is less than 3 years remaining to ensure the lock ends with the farm's end.
update_code()This action can be triggered only by the Router contract of the dex. It allow the Router to request the farm to update it's code. The farm will request the new code using the function get_farm_code of the Factory (see above).
Router is a helper contract for user to easily retrieve existing pools and create new pools.
get_pool_addresses(token1_address, token2_address)Returns the info of the pool for the 2 tokens address.
token1_addressis the address of the first tokentoken2_addressis the address of the second token
{
"address": "00001234...",
"lp_token_address": "00005678..."
}get_pool_list()Return the infos of all the pools. tokens field is the address of both token concatenated and separated by a slash.
[
{
"address": "00001234...",
"lp_token_address": "00005678...",
"tokens": "0000456.../000789..."
}
]get_farm_list()Return the infos of all the farms.
{
"lp_token_address": "00001234...",
"start_date": 1705500842,
"end_date": 1705912842,
"reward_token": "00005678...", // or "UCO"
"address": "0000ABCD..."
}add_pool(token1_address, token2_address, pool_creation_address)This action allows users to add a new pool in the router. The transaction triggering this action should also add the first liquidity to a previously created pool. The transaction that created the pool should be a token transaction with the token definition returned by the function get_lp_token_definition. It should also have the code returned by the function get_pool_code.
add_farm(lp_token, start_date, end_date, reward_token, farm_creation_address)This action allows the Master chain of the dex to add a new farm in the router. The transaction triggering this action should also add the first amount of reward token to the previously created farm. The transaction that created the farm should be a contract transaction with the code returned by the function get_farm_code of the Factory contract.
update_code(new_code)This action can be triggered only by the Master chain of the dex. It's allowing to update the code of the Router.
update_pools_code()This action can be triggered only by the Master chain of the dex. It's allowing to update all the pools code. The Router will call the action update_code() of all the known pool.
update_farms_code()This action can be triggered only by the Master chain of the dex. It's allowing to update all the farms code. The Router will call the action update_code() of all the known farm.
To get some statistics about the DEX, pool contracts are storing the volume and fee for both tokens since its creation. Farm contract also stores the reward already distibuted. You can refer to get_pool_infos function and get_farm_infos.
Those stats are accumulator since contract creation. For example, if you want to get the fee since the last 24h you have to retrieve the contract address of the pool 24h hour before (you can use node's getTransactionChain graphql api with from args) and call the function get_pool_infos on this transaction address. Do the same for the current address and you can calculate the difference between both values. The difference is the fee paid since the last 24h
In the directory contracts you can find a script dex.js. This script provide the main functionnality to deploy the dex and test it.
node dex --help
dex [command]
Commands:
dex init_keychain Initialize the dex keychain with the primary services
dex deploy_factory Deploy the factory
dex deploy_router Deploy the router
dex update_router Update the router
dex update_pools Update all pool code
dex update_farms Update all farm code
dex update_protocol_fee Update the protocol fee for a pool
dex update_farm_dates Update the start and end date of a farm
dex create_tokens Create tokens and send them to user address
dex deploy_pool Deploy a pool for the token specified
dex add_liquidity Add liquidity to a pool
dex remove_liquidity Remove liquidity from a pool
dex swap Swap exact token for token
dex deploy_farm Deploy a farm for a lp token and a reward token
dex deposit Deposit LP Token in a farm
dex claim Claim token from a farming pool
dex withdraw Withdraw LP token from a farming pool and claim rewardsFor each command you can get the help:
node dex swap --help
dex swap
Swap exact token for token
Options:
--token1 First token name (token to send) [string] [required]
--token2 Second token name (token to receive) [string] [required]
--token1_amount Amount of token to send [required]
--slippage Slippage in percentage (2 = 2%) to apply. Default 2To deploy the main dex contract you have to init the keychain and deploy the router:
node dex init_keychainnode dex deploy_factorynode dex deploy_routerNB: Don't forget to faucet the Master genesis address before executing node dex deploy_factory
To test the dex you first have to create some tokens, it will create tokens with 1 million supply
node dex create_tokens --number 6This will create multiple tokens with the name token0, token1, token2 ...
Then you can deploy a pool:
node dex deploy_pool --token1 token3 --token2 token4 --token1_amount 100 --token2_amount 200Then you can use script to add / remove liquidity or swap:
node dex add_liquidity --token1 token3 --token1_amount 750 --token2 token4
node dex swap --token1 token3 --token1_amount 50 --token2 token4
node dex remove_liquidity --token1 token3 --token2 token4 --lp_token_amount 72You can also deploy a farm (Master address should have the reward tokens):
node dex deploy_farm --lp_token 0000e866...f160 --reward_token token4 --reward_token_amount 2000 --farm_type 1Then you can use script to deposit, claim or withdraw:
node dex deposit --lp_token 0000e866...f160 --reward_token UCO --lp_token_amount 20
node dex claim --lp_token 0000e866...f160 --reward_token UCO
node dex withdraw --lp_token 0000e866...f160 --reward_token UCO --amount 20To update router code you can use this script:
node dex update_routerTo update pools code you can use this script:
node dex deploy_factory
node dex update_poolsTo update farms code you can use this script:
node dex deploy_factory
node dex update_farms- Security access with your Archethic Wallet
- Flutter 3.19+
- Dart 3.3+
*** This Application is currently in active development so it might fail to build. Please refer to issues or create new issues if you find any. Contributions are welcomed.