Skip to content

Commit

Permalink
Merge pull request #45 from madfish-solutions/token-to-token-improvem…
Browse files Browse the repository at this point in the history
…ents

Token to token improvements
  • Loading branch information
KStasi authored Jul 27, 2021
2 parents 25ce829 + 07b0b3a commit 46e059e
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 77 deletions.
11 changes: 10 additions & 1 deletion contracts/partials/ITTDex.ligo
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,19 @@ type token_to_token_route_params is
receiver : address; (* tokens receiver *)
]

type initialize_params is
[@layout:comb]
record [
pair : tokens_info; (* exchange pair info *)
token_a_in : nat; (* min amount of tokens A invested *)
token_b_in : nat; (* min amount of tokens B invested *)
]

type invest_liquidity_params is
[@layout:comb]
record [
pair : tokens_info; (* exchange pair info *)
shares : nat; (* the amount of shares to receive *)
token_a_in : nat; (* min amount of tokens A invested *)
token_b_in : nat; (* min amount of tokens B invested *)
]
Expand All @@ -108,7 +117,7 @@ type divest_liquidity_params is
]

type dex_action is
| AddPair of invest_liquidity_params (* sets initial liquidity *)
| AddPair of initialize_params (* sets initial liquidity *)
| Swap of token_to_token_route_params (* exchanges token to another token and sends them to receiver *)
| Invest of invest_liquidity_params (* mints min shares after investing tokens *)
| Divest of divest_liquidity_params (* burns shares and sends tokens to the owner *)
Expand Down
39 changes: 22 additions & 17 deletions contracts/partials/TTMethodDex.ligo
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,17 @@ function typed_transfer(
contract_address)
end;

(* Helper function to transfer the asset based on its standard *)
function check_token_id(
const token_id : nat;
const standard: token_type) : unit is
case standard of
Fa12 -> if token_id = 0n
then unit
else (failwith("Dex/non-zero-token-id") : unit)
| Fa2 -> unit
end;

#include "../partials/TTMethodFA2.ligo"

(* Initialize exchange after the previous liquidity was drained *)
Expand All @@ -207,6 +218,10 @@ function initialize_exchange(
if params.pair.token_a_address > params.pair.token_b_address
then failwith("Dex/wrong-pair") else skip;

(* check fa1.2 token ids *)
check_token_id(params.pair.token_a_id, params.pair.token_a_type);
check_token_id(params.pair.token_b_id, params.pair.token_b_type);

(* read pair info*)
const res : (pair_info * nat) = get_pair(params.pair, s);
const pair : pair_info = res.0;
Expand Down Expand Up @@ -468,29 +483,19 @@ function invest_liquidity(
if pair.token_a_pool * pair.token_b_pool = 0n
then failwith("Dex/not-launched") else skip;

(* calculate purchased tokens *)
const shares_a_purchased : nat =
params.token_a_in * pair.total_supply / pair.token_a_pool;
const shares_b_purchased : nat =
params.token_b_in * pair.total_supply / pair.token_b_pool;
const shares_purchased : nat =
if shares_a_purchased < shares_b_purchased
then shares_a_purchased
else shares_b_purchased;

(* ensure purchsed shares satisfy required minimum *)
if shares_purchased = 0n
if params.shares = 0n
then failwith("Dex/wrong-params") else skip;

(* calculate tokens to be withdrawn *)
const tokens_a_required : nat =
shares_purchased * pair.token_a_pool / pair.total_supply;
if shares_purchased * pair.token_a_pool >
params.shares * pair.token_a_pool / pair.total_supply;
if params.shares * pair.token_a_pool >
tokens_a_required * pair.total_supply
then tokens_a_required := tokens_a_required + 1n else skip;
const tokens_b_required : nat =
shares_purchased * pair.token_b_pool / pair.total_supply;
if shares_purchased * pair.token_b_pool >
params.shares * pair.token_b_pool / pair.total_supply;
if params.shares * pair.token_b_pool >
tokens_b_required * pair.total_supply
then tokens_b_required := tokens_b_required + 1n else skip;

Expand All @@ -508,15 +513,15 @@ function invest_liquidity(
const share : nat = account.balance;

(* update user's shares *)
account.balance := share + shares_purchased;
account.balance := share + params.shares;
s.ledger[(Tezos.sender, token_id)] := account;

(* update reserves *)
pair.token_a_pool := pair.token_a_pool + tokens_a_required;
pair.token_b_pool := pair.token_b_pool + tokens_b_required;

(* update total number of shares *)
pair.total_supply := pair.total_supply + shares_purchased;
pair.total_supply := pair.total_supply + params.shares;
s.pairs[token_id] := pair;

(* prepare operations to get initial liquidity *)
Expand Down
74 changes: 21 additions & 53 deletions migrations/2_deploy_token_to_token_dex.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,21 +104,6 @@ module.exports = async (deployer, network, accounts) => {
.approve(dexInstance.address.toString(), initialTokenAmount)
.send();
await operation.confirmation();

operation = await dex.methods
.use(
"addPair",
ordered
? token0Instance.address.toString()
: token1Instance.address.toString(),
ordered
? token1Instance.address.toString()
: token0Instance.address.toString(),
initialTokenAmount,
initialTokenAmount
)
.send();
await operation.confirmation();
} else {
let operation = await token0Instance.methods
.update_operators([
Expand Down Expand Up @@ -150,44 +135,27 @@ module.exports = async (deployer, network, accounts) => {
.send();
}
await operation.confirmation();

if (standard === "MIXED") {
operation = await dex.methods
.use(
"addPair",
ordered
? token0Instance.address.toString()
: token1Instance.address.toString(),
0,
"fa12",
ordered
? token1Instance.address.toString()
: token0Instance.address.toString(),
0,
"fa2".initialTokenAmount,
initialTokenAmount
)
.send();
} else {
operation = await dex.methods
.use(
"addPair",
ordered
? token0Instance.address.toString()
: token1Instance.address.toString(),
0,
standard.toLocaleLowerCase(),
ordered
? token1Instance.address.toString()
: token0Instance.address.toString(),
0,
standard.toLocaleLowerCase(),
initialTokenAmount,
initialTokenAmount
)
.send();
}
await operation.confirmation();
}
operation = await dex.methods
.use(
"addPair",
ordered
? token0Instance.address.toString()
: token1Instance.address.toString(),
0,
standard == "MIXED" ? "fa2" : standard.toLocaleLowerCase(),
null,
ordered
? token1Instance.address.toString()
: token0Instance.address.toString(),
0,
standard == "MIXED" ? "fa12" : standard.toLocaleLowerCase(),
null,
initialTokenAmount,
initialTokenAmount
)
.send();

await operation.confirmation();
}
};
19 changes: 15 additions & 4 deletions test/InvestTTLiquidity.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ contract("InvestTTLiquidity()", function () {

it("success in case of min shares of 1", async function () {
const pairAddress = context.dex.contract.address;
const maxTokenAAmount = 1000;
const maxTokenBAmount = 1000;
const tokenAAmount = 1;
const tokenBAmount = 100;
await context.tokens[0].updateStorage({
ledger: [aliceAddress, pairAddress],
});
Expand Down Expand Up @@ -170,7 +174,12 @@ contract("InvestTTLiquidity()", function () {
pairAddress
].balance;
const initDexPair = context.dex.storage.pairs[0];
await context.dex.investLiquidity("0", tokenAAmount, tokenBAmount, 1);
await context.dex.investLiquidity(
"0",
maxTokenAAmount,
maxTokenBAmount,
1
);
await context.tokens[0].updateStorage({
ledger: [aliceAddress, pairAddress],
});
Expand Down Expand Up @@ -321,8 +330,10 @@ contract("InvestTTLiquidity()", function () {
describe("Test purchased shares", () => {
before(async () => {});

it("success in case of more then 0 tokens purchesed", async function () {
it("success in case of more then 0 shares purchesed", async function () {
const pairAddress = context.dex.contract.address;
const tokenAAmount = 1000;
const tokenBAmount = 100000;
await context.tokens[0].updateStorage({
ledger: [aliceAddress, pairAddress],
});
Expand Down Expand Up @@ -351,7 +362,7 @@ contract("InvestTTLiquidity()", function () {
pairAddress
].balance;
const initDexPair = context.dex.storage.pairs[0];
await context.dex.investLiquidity("0", tokenAAmount, tokenBAmount, 1);
await context.dex.investLiquidity("0", tokenAAmount, tokenBAmount, 1000);
await context.tokens[0].updateStorage({
ledger: [aliceAddress, pairAddress],
});
Expand Down Expand Up @@ -416,7 +427,7 @@ contract("InvestTTLiquidity()", function () {
1,
bobAddress
);
await rejects(context.dex.investLiquidity("0", 1, 1, 1), (err) => {
await rejects(context.dex.investLiquidity("0", 1, 1, 0), (err) => {
ok(err.message == "Dex/wrong-params", "Error message mismatch");
return true;
});
Expand Down
4 changes: 2 additions & 2 deletions test/helpers/ttdexFA2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,9 @@ export class TTDex extends TokenFA2 {
pair.token_b_id,
standard.toLowerCase() == "mixed" ? "fa12" : standard.toLowerCase(),
null,
minShares,
tokenAAmount,
tokenBAmount,
minShares
tokenBAmount
)
.send();
await confirmOperation(tezos, operation.hash);
Expand Down

0 comments on commit 46e059e

Please sign in to comment.