Skip to content

Commit

Permalink
fix: removed ckbtc exchange in liquidity pool (#19)
Browse files Browse the repository at this point in the history
* fix: removed ckbtc exchange in liquidity pool

* fix: removed xrc from liquidity pool
  • Loading branch information
veeso authored Aug 3, 2024
1 parent 344d9f8 commit a5f29ab
Show file tree
Hide file tree
Showing 23 changed files with 36 additions and 566 deletions.
9 changes: 4 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ serde_json = "1"
sha2 = "0.10"
sha3 = "0.10"
thiserror = "1.0"
time = { version = "0.3.28", features = ["macros", "parsing"] }
time = { version = "0.3.36", features = ["macros", "parsing"] }

[profile.dev]
debug = false
Expand Down
26 changes: 5 additions & 21 deletions docs/canisters/ekoke-liquidity-pool.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

- [EKOKE Liquidity Pool Canister](#ekoke-liquidity-pool-canister)
- [Introduction](#introduction)
- [Swap Account](#swap-account)
- [Refund to investors](#refund-to-investors)
- [API](#api)
- [HTTP API](#http-api)
- [Request protocol](#request-protocol)
Expand All @@ -13,27 +13,15 @@

## Introduction

In order to guarantee a real value to the $EKOKE token, the EKOKE DAO manages a Liquidity Pool which has two accounts, the first is ICP and the second is ckBTC.
In order to guarantee a real value to the $EKOKE token, the EKOKE DAO manages a Liquidity Pool which has currently a ICP account.

The liquidity pool can be funded by anyone by sending funds to the account returned by `liquidity_pool_accounts` call.

For each Deferred NFT sold on the marketplace to the contract buyer, the 10% of the amount paid is sent by to the liquidity pool. This guarantees that the value of a $EKOKE is at least 10% of a NFT value. (More or less, there are also other criteria which determines the value of the token).

There's no way for any person to withdraw funds in the **Liquidity Pool**, they are locked forever.
## Refund to investors

## Swap Account

In order to allow the exchange between the ICP sent after a sale on the marketplace into ckBTC, which will be considered as a value reserve, at the creation of the canister a Swap account is passed as argument.

The swap account is an ICRC account which must have a certain ckBTC amount of it and which will guarantee an allowance to the ekoke liquidity pool canister in order to spend their ckBTC. At this point once a day the canister will try to swap its ICP into ckBTC from the account.

The exchange ratio is calculated by using the XRC canister.

The amount sent will be the minimum between:

- the amount of ICP converted into ckBTC in the liquidity pool
- the amount of ckBTC on the swap account
- the allowance given to the ckBTC ledger for the swap account
In case a contract fails to be paid, the liquidity pool receives the initial deposit sent by the buyer. The liquidity pool funds are also used to refund the third party investors.

## API

Expand Down Expand Up @@ -68,8 +56,7 @@ Returns an object containing the balance for each account in the liquidity pool

```json
{
"icp": nat,
"ckbtc": nat
"icp": nat
}
```

Expand All @@ -81,8 +68,5 @@ Returns the account for the liquidity pool
{
"icp": {
"owner": "principal"
},
"ckbtc": {
"owner": "principal"
}
}
13 changes: 1 addition & 12 deletions integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,7 @@ impl TestEnv {
ekoke_ledger_id,
);
Self::install_ekoke_ledger(&pic, ekoke_ledger_id, ekoke_reward_pool_id);
Self::install_ekoke_liquidity_pool(
&pic,
ekoke_liquidity_pool_id,
icp_ledger_id,
ckbtc_id,
xrc_id,
);
Self::install_ekoke_liquidity_pool(&pic, ekoke_liquidity_pool_id, icp_ledger_id);
Self::install_ekoke_reward_pool(
&pic,
ekoke_reward_pool_id,
Expand Down Expand Up @@ -299,18 +293,13 @@ impl TestEnv {
pic: &PocketIc,
ekoke_liquidity_pool_id: Principal,
icp_ledger_canister: Principal,
ckbtc_canister: Principal,
xrc_canister: Principal,
) {
pic.add_cycles(ekoke_liquidity_pool_id, DEFAULT_CYCLES);
let wasm_bytes = Self::load_wasm(Canister::EkokeLiquidityPool);

let init_arg = EkokeLiquidityPoolInitData {
admins: vec![actor::admin()],
swap_account: actor::swap_account(),
icp_ledger_canister,
ckbtc_canister,
xrc_canister,
};
let init_arg = Encode!(&init_arg).unwrap();

Expand Down
5 changes: 0 additions & 5 deletions integration-tests/tests/http/ekoke_liquidity_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@ fn test_http_should_get_liquidity_pool_accounts_and_balance() {
let liquidity_pool_accounts: LiquidityPoolAccounts =
http_client.http_request("liquidityPoolAccounts", serde_json::json!({}));

assert_eq!(
liquidity_pool_accounts.ckbtc.owner,
env.ekoke_liquidity_pool_id
);
assert_eq!(
liquidity_pool_accounts.icp.owner,
env.ekoke_liquidity_pool_id
Expand All @@ -23,6 +19,5 @@ fn test_http_should_get_liquidity_pool_accounts_and_balance() {
let liquidity_pool_balance: LiquidityPoolBalance =
http_client.http_request("liquidityPoolBalance", serde_json::json!({}));

assert_eq!(liquidity_pool_balance.ckbtc, 0u64);
assert_eq!(liquidity_pool_balance.icp, 0u64);
}
4 changes: 0 additions & 4 deletions scripts/deploy_functions.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,12 @@ deploy_ekoke_liquidity_pool() {
NETWORK="$2"
EKOKE_LIQUIDITY_POOL_PRINCIPAL="$3"
ADMINS="$4"
SWAP_ACCOUNT="$5"

echo "deploying ekoke-liquidity-pool canister $EKOKE_LIQUIDITY_POOL_PRINCIPAL"

ekoke_liquidity_pool_init_args="(record {
swap_account = $SWAP_ACCOUNT;
admins = vec { $(for admin in $ADMINS; do echo "principal \"$admin\";"; done) };
ckbtc_canister = principal \"mxzaz-hqaaa-aaaar-qaada-cai\";
icp_ledger_canister = principal \"ryjl3-tyaaa-aaaaa-aaaba-cai\";
xrc_canister = principal \"uf6dk-hyaaa-aaaaq-qaaaq-cai\";
})"

dfx deploy --mode=$INSTALL_MODE --yes --network="$NETWORK" --argument="$ekoke_liquidity_pool_init_args" ekoke-liquidity-pool
Expand Down
3 changes: 1 addition & 2 deletions scripts/deploy_ic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ source ./deploy_functions.sh
source ./did.sh

ADMIN_PRINCIPAL="$(dfx identity get-principal)"
SWAP_ACCOUNT="$(account "$ADMIN_PRINCIPAL")"
ERC20_BRIDGE_ADDRESS="0xc08e14F47382BCc1dA6c3Ff366018cAb1c77091F"
ERC20_SWAP_FEE="231634000000000"
ERC20_NETWORK="Ethereum"
Expand Down Expand Up @@ -48,7 +47,7 @@ case "$CANISTER" in
;;

"ekoke-liquidity-pool")
deploy_ekoke_liquidity_pool "reinstall" "ic" "$EKOKE_LIQUIDITY_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL" "$SWAP_ACCOUNT"
deploy_ekoke_liquidity_pool "reinstall" "ic" "$EKOKE_LIQUIDITY_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL"
;;

"ekoke-reward-pool")
Expand Down
3 changes: 1 addition & 2 deletions scripts/deploy_local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ source ./deploy_functions.sh
source ./did.sh

ADMIN_PRINCIPAL="$(dfx identity get-principal)"
SWAP_ACCOUNT="$(account "$ADMIN_PRINCIPAL")"
ERC20_BRIDGE_ADDRESS="0xc08e14F47382BCc1dA6c3Ff366018cAb1c77091F"
ERC20_SWAP_FEE="231634000000000"
ERC20_NETWORK="Sepolia"
Expand All @@ -28,7 +27,7 @@ set -e

deploy_deferred "reinstall" "local" "$DEFERRED_PRINCIPAL" "$EKOKE_REWARD_POOL_PRINCIPAL" "$MARKETPLACE_PRINCIPAL" "$ADMIN_PRINCIPAL"
deploy_ekoke_erc20_swap "reinstall" "local" "$EKOKE_ERC20_SWAP_PRINCIPAL" "$ADMIN_PRINCIPAL" "$EKOKE_LEDGER_PRINCIPAL" "$ERC20_BRIDGE_ADDRESS" "$ERC20_SWAP_FEE" "$ERC20_NETWORK"
deploy_ekoke_liquidity_pool "reinstall" "local" "$EKOKE_LIQUIDITY_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL" "$SWAP_ACCOUNT"
deploy_ekoke_liquidity_pool "reinstall" "local" "$EKOKE_LIQUIDITY_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL"
deploy_ekoke_reward_pool "reinstall" "local" "$EKOKE_REWARD_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL" "$EKOKE_LEDGER_PRINCIPAL" "$DEFERRED_PRINCIPAL" "$MARKETPLACE_PRINCIPAL"
deploy_marketplace "reinstall" "local" "$MARKETPLACE_PRINCIPAL" "$DEFERRED_PRINCIPAL" "$EKOKE_REWARD_POOL_PRINCIPAL" "$ADMIN_PRINCIPAL" "$EKOKE_LIQUIDITY_POOL_PRINCIPAL"

Expand Down
10 changes: 2 additions & 8 deletions src/declarations/ekoke-liquidity-pool/ekoke-liquidity-pool.did
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ type EkokeError = variant {
};
type EkokeLiquidityPoolInitData = record {
icp_ledger_canister : principal;
ckbtc_canister : principal;
swap_account : Account;
xrc_canister : principal;
admins : vec principal;
};
type HttpRequest = record {
Expand All @@ -59,8 +56,8 @@ type HttpResponse = record {
upgrade : opt bool;
status_code : nat16;
};
type LiquidityPoolAccounts = record { icp : Account; ckbtc : Account };
type LiquidityPoolBalance = record { icp : nat; ckbtc : nat };
type LiquidityPoolAccounts = record { icp : Account };
type LiquidityPoolBalance = record { icp : nat };
type PoolError = variant { PoolNotFound : nat; NotEnoughTokens };
type RegisterError = variant { TransactionNotFound };
type RejectionCode = variant {
Expand Down Expand Up @@ -97,10 +94,7 @@ type TransferFromError = variant {
service : (EkokeLiquidityPoolInitData) -> {
admin_cycles : () -> (nat) query;
admin_set_admins : (vec principal) -> ();
admin_set_ckbtc_canister : (principal) -> ();
admin_set_icp_ledger_canister : (principal) -> ();
admin_set_swap_account : (Account) -> ();
admin_set_xrc_canister : (principal) -> ();
http_request : (HttpRequest) -> (HttpResponse) query;
liquidity_pool_accounts : () -> (LiquidityPoolAccounts) query;
liquidity_pool_balance : () -> (Result) query;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ export type EkokeError = { 'Configuration' : ConfigurationError } |
{ 'Ecdsa' : EcdsaError };
export interface EkokeLiquidityPoolInitData {
'icp_ledger_canister' : Principal,
'ckbtc_canister' : Principal,
'swap_account' : Account,
'xrc_canister' : Principal,
'admins' : Array<Principal>,
}
export interface HttpRequest {
Expand All @@ -62,8 +59,8 @@ export interface HttpResponse {
'upgrade' : [] | [boolean],
'status_code' : number,
}
export interface LiquidityPoolAccounts { 'icp' : Account, 'ckbtc' : Account }
export interface LiquidityPoolBalance { 'icp' : bigint, 'ckbtc' : bigint }
export interface LiquidityPoolAccounts { 'icp' : Account }
export interface LiquidityPoolBalance { 'icp' : bigint }
export type PoolError = { 'PoolNotFound' : bigint } |
{ 'NotEnoughTokens' : null };
export type RegisterError = { 'TransactionNotFound' : null };
Expand Down Expand Up @@ -100,10 +97,7 @@ export type TransferFromError = {
export interface _SERVICE {
'admin_cycles' : ActorMethod<[], bigint>,
'admin_set_admins' : ActorMethod<[Array<Principal>], undefined>,
'admin_set_ckbtc_canister' : ActorMethod<[Principal], undefined>,
'admin_set_icp_ledger_canister' : ActorMethod<[Principal], undefined>,
'admin_set_swap_account' : ActorMethod<[Account], undefined>,
'admin_set_xrc_canister' : ActorMethod<[Principal], undefined>,
'http_request' : ActorMethod<[HttpRequest], HttpResponse>,
'liquidity_pool_accounts' : ActorMethod<[], LiquidityPoolAccounts>,
'liquidity_pool_balance' : ActorMethod<[], Result>,
Expand Down
29 changes: 5 additions & 24 deletions src/declarations/ekoke-liquidity-pool/ekoke-liquidity-pool.did.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
export const idlFactory = ({ IDL }) => {
const Account = IDL.Record({
'owner' : IDL.Principal,
'subaccount' : IDL.Opt(IDL.Vec(IDL.Nat8)),
});
const EkokeLiquidityPoolInitData = IDL.Record({
'icp_ledger_canister' : IDL.Principal,
'ckbtc_canister' : IDL.Principal,
'swap_account' : Account,
'xrc_canister' : IDL.Principal,
'admins' : IDL.Vec(IDL.Principal),
});
const HttpRequest = IDL.Record({
Expand All @@ -22,14 +15,12 @@ export const idlFactory = ({ IDL }) => {
'upgrade' : IDL.Opt(IDL.Bool),
'status_code' : IDL.Nat16,
});
const LiquidityPoolAccounts = IDL.Record({
'icp' : Account,
'ckbtc' : Account,
});
const LiquidityPoolBalance = IDL.Record({
'icp' : IDL.Nat,
'ckbtc' : IDL.Nat,
const Account = IDL.Record({
'owner' : IDL.Principal,
'subaccount' : IDL.Opt(IDL.Vec(IDL.Nat8)),
});
const LiquidityPoolAccounts = IDL.Record({ 'icp' : Account });
const LiquidityPoolBalance = IDL.Record({ 'icp' : IDL.Nat });
const ConfigurationError = IDL.Variant({
'AdminsCantBeEmpty' : IDL.Null,
'AnonymousAdmin' : IDL.Null,
Expand Down Expand Up @@ -128,10 +119,7 @@ export const idlFactory = ({ IDL }) => {
return IDL.Service({
'admin_cycles' : IDL.Func([], [IDL.Nat], ['query']),
'admin_set_admins' : IDL.Func([IDL.Vec(IDL.Principal)], [], []),
'admin_set_ckbtc_canister' : IDL.Func([IDL.Principal], [], []),
'admin_set_icp_ledger_canister' : IDL.Func([IDL.Principal], [], []),
'admin_set_swap_account' : IDL.Func([Account], [], []),
'admin_set_xrc_canister' : IDL.Func([IDL.Principal], [], []),
'http_request' : IDL.Func([HttpRequest], [HttpResponse], ['query']),
'liquidity_pool_accounts' : IDL.Func(
[],
Expand All @@ -142,15 +130,8 @@ export const idlFactory = ({ IDL }) => {
});
};
export const init = ({ IDL }) => {
const Account = IDL.Record({
'owner' : IDL.Principal,
'subaccount' : IDL.Opt(IDL.Vec(IDL.Nat8)),
});
const EkokeLiquidityPoolInitData = IDL.Record({
'icp_ledger_canister' : IDL.Principal,
'ckbtc_canister' : IDL.Principal,
'swap_account' : Account,
'xrc_canister' : IDL.Principal,
'admins' : IDL.Vec(IDL.Principal),
});
return [EkokeLiquidityPoolInitData];
Expand Down
7 changes: 0 additions & 7 deletions src/did/src/ekoke_liquidity_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,13 @@
mod liquidity_pool;

use candid::{CandidType, Deserialize, Principal};
use icrc::icrc1::account::Account;

pub use self::liquidity_pool::{LiquidityPoolAccounts, LiquidityPoolBalance};

/// These are the arguments which are taken by the ekoke liquidity pool canister on init
#[derive(Debug, Clone, CandidType, Deserialize)]
pub struct EkokeLiquidityPoolInitData {
pub admins: Vec<Principal>,
/// The canister ID of the CKBTC canister
pub ckbtc_canister: Principal,
/// ICP ledger canister id
pub icp_ledger_canister: Principal,
/// Swap account
pub swap_account: Account,
/// XRC canister
pub xrc_canister: Principal,
}
4 changes: 0 additions & 4 deletions src/did/src/ekoke_liquidity_pool/liquidity_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,13 @@ use serde::Serialize;
/// The accounts that hold the liquidity pools for the CKBTC and ICP tokens.
#[derive(Clone, Debug, PartialEq, Eq, CandidType, Deserialize, Serialize)]
pub struct LiquidityPoolAccounts {
/// The account that holds the pool for the CKBTC token.
pub ckbtc: Account,
/// The account that holds the pool for the ICP tokens.
pub icp: Account,
}

/// The balance of the liquidity pool
#[derive(Clone, Debug, PartialEq, Eq, CandidType, Deserialize, Serialize)]
pub struct LiquidityPoolBalance {
/// CKBTC tokens hold in the liquidity pool
pub ckbtc: Nat,
/// ICP tokens hold in the liquidity pool
pub icp: Nat,
}
1 change: 0 additions & 1 deletion src/ekoke_liquidity_pool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ icrc = { path = "../icrc" }
serde = { workspace = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
xrc = { path = "../xrc" }

[dev-dependencies]
pretty_assertions = "1"
Expand Down
Loading

0 comments on commit a5f29ab

Please sign in to comment.