From 866a64034debc00e555feb83d0b9851752c793f9 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 23 Jun 2022 13:39:42 +0300 Subject: [PATCH 01/67] Update view for iterating over pool rewards instead of user earnings --- contracts/partials/dex_core/views.ligo | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contracts/partials/dex_core/views.ligo b/contracts/partials/dex_core/views.ligo index fd74ab3..769674d 100644 --- a/contracts/partials/dex_core/views.ligo +++ b/contracts/partials/dex_core/views.ligo @@ -105,16 +105,17 @@ const info = unwrap_or(s.storage.stakers_balance[key], default_staker_info); function get_rewards( const key : token_pool_idx_t; - const value : account_reward_t) + const value : nat) : nat is block { + const earning = unwrap_or(info.earnings[key], record[reward_f=0n;former_f=0n]) const pool_accum_f = unwrap_or(pool_accumulator_f[key], 0n); - const new_former_f = info.balance * pool_accum_f; - const reward_amt = (value.reward_f + abs(new_former_f - value.former_f)) / Constants.accum_precision; + const new_former_f = info.balance * value; + const reward_amt = (earning.reward_f + abs(new_former_f - earning.former_f)) / Constants.accum_precision; } with reward_amt; const rew_info: staker_res = record [ balance = info.balance; - rewards = Map.map(get_rewards, info.earnings); + rewards = Map.map(get_rewards, pool_accumulator_f); ]; } with record [ request = params; From cb76f4c50d52d41d04d2ca9207f428290e70fb77 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 23 Jun 2022 13:44:53 +0300 Subject: [PATCH 02/67] remove unused var --- contracts/partials/dex_core/views.ligo | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/partials/dex_core/views.ligo b/contracts/partials/dex_core/views.ligo index 769674d..5c5d7e1 100644 --- a/contracts/partials/dex_core/views.ligo +++ b/contracts/partials/dex_core/views.ligo @@ -109,7 +109,6 @@ : nat is block { const earning = unwrap_or(info.earnings[key], record[reward_f=0n;former_f=0n]) - const pool_accum_f = unwrap_or(pool_accumulator_f[key], 0n); const new_former_f = info.balance * value; const reward_amt = (earning.reward_f + abs(new_former_f - earning.former_f)) / Constants.accum_precision; } with reward_amt; From 3c70ec91938734b50e681d426f9509a7abd7695e Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 23 Jun 2022 13:46:14 +0300 Subject: [PATCH 03/67] add semicolon --- contracts/partials/dex_core/views.ligo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/partials/dex_core/views.ligo b/contracts/partials/dex_core/views.ligo index 5c5d7e1..f02302c 100644 --- a/contracts/partials/dex_core/views.ligo +++ b/contracts/partials/dex_core/views.ligo @@ -108,7 +108,7 @@ const value : nat) : nat is block { - const earning = unwrap_or(info.earnings[key], record[reward_f=0n;former_f=0n]) + const earning = unwrap_or(info.earnings[key], record[reward_f=0n;former_f=0n]); const new_former_f = info.balance * value; const reward_amt = (earning.reward_f + abs(new_former_f - earning.former_f)) / Constants.accum_precision; } with reward_amt; From ca69703caf1b30c9a53fca91b4c310d7cfbd3a3a Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Tue, 25 Oct 2022 17:39:34 +0300 Subject: [PATCH 04/67] Initial draft of strategy implementation --- contracts/partials/dex_core/helpers.ligo | 4 + contracts/partials/dex_core/storage.ligo | 2 + contracts/partials/errors.ligo | 2 +- contracts/partials/strategy/helpers.ligo | 94 ++++++++++++++++++++++++ contracts/partials/strategy/methods.ligo | 50 +++++++++++++ contracts/partials/strategy/types.ligo | 25 +++++++ migrations/00_dex.ts | 1 - migrations/01_factory.ts | 2 - migrations/02_factory_pools.ts | 26 +++++-- 9 files changed, 197 insertions(+), 9 deletions(-) create mode 100644 contracts/partials/strategy/helpers.ligo create mode 100644 contracts/partials/strategy/methods.ligo create mode 100644 contracts/partials/strategy/types.ligo diff --git a/contracts/partials/dex_core/helpers.ligo b/contracts/partials/dex_core/helpers.ligo index 2965982..1b6915b 100644 --- a/contracts/partials/dex_core/helpers.ligo +++ b/contracts/partials/dex_core/helpers.ligo @@ -216,6 +216,10 @@ function get_pool_info( ref_f = 0n; stakers_f = 0n; ]; + strategy = record [ + strat_contract = (None: option(address)); + configuration = (map []: map(token_pool_idx_t, strategy_storage_t)); + ] staker_accumulator = record [ accumulator_f = (map []: map(token_pool_idx_t, nat)); total_fees = (map []: map(token_pool_idx_t, nat)); diff --git a/contracts/partials/dex_core/storage.ligo b/contracts/partials/dex_core/storage.ligo index ffa253e..167617b 100644 --- a/contracts/partials/dex_core/storage.ligo +++ b/contracts/partials/dex_core/storage.ligo @@ -49,6 +49,8 @@ type pool_t is [@layout:comb] record [ tokens_info : map(token_pool_idx_t, token_info_t); fee : fees_storage_t; + strategy : strategy_full_storage_t; + staker_accumulator : staker_accum_t; (* LP data *) diff --git a/contracts/partials/errors.ligo b/contracts/partials/errors.ligo index ac8faf1..ad3535e 100644 --- a/contracts/partials/errors.ligo +++ b/contracts/partials/errors.ligo @@ -18,7 +18,7 @@ module Dex is { const not_started : string = "not-started"; const pool_listed : string = "pool-exist"; const pool_not_listed : string = "not-launched"; - const reserves_drained : string = "zero-reserves-when-positive-shares"; + const reserves_drained : string = "zero-reserves-when-positive-shares"; const supply_drained : string = "positive-reserves-when-zero-shares"; const time_expired : string = "time-expired"; const timestamp_error : string = "timestamp-error"; diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo new file mode 100644 index 0000000..28973bd --- /dev/null +++ b/contracts/partials/strategy/helpers.ligo @@ -0,0 +1,94 @@ +function check_strategy_bounds( + const reserves : nat; + const desired_reserves: nat; + const desired_rate_f : nat; + const delta_rate_f : nat) + : unit is + block { + const rate_f = reserves * Constants.precision / desired_reserves; + const in_upper_bound = rate_f < (desired_rate_f + delta_rate_f); + const in_lower_bound = rate_f > nat_or_error(desired_rate_f - delta_rate_f, Errors.Math.nat_error); + } with require(in_upper_bound and in_lower_bound, Erorrs.Strategy.out_of_delta_bounds) + +function calculate_desired_reserves( + const reserves : nat; + const strat_token_conf: strategy_storage_t) + : nat is + block { + const desired_reserves : nat = reserves * strat_token_conf.des_reserves_rate_f / Constants.precision; + check_strategy_bounds( + reserves, + desired_reserves, + strat_token_conf.des_reserves_rate_f, + strat_token_conf.delta_rate_f + ); + } with if desired_reserves > strat_token_conf.min_invest + then desired_reserves + else 0n + +(* Helper function to get mint lending contract entrypoint *) +[@inline] function get_update_state_entrypoint( + const strategy_address: address) + : contract(upd_strat_state_t) is + Utils.unwrap( + (Tezos.get_entrypoint_opt("%update_token_state", strategy_address): option(contract(upd_strat_state_t))), + Errors.Strategy.no_update_state_entrypoint + ); + +function update_strategy_reserves( + const token : token_t; + const old_s_reserves : nat; + const new_s_reserves : nat; + const strat_contract : address) + : list(operation) is + block { + const upd_state_param : upd_strat_state_t = record[ + token = token; + new_balance = new_s_reserves + ]; + var before_ops := Constants.no_operations; + var after_ops := Constants.no_operations; + case is_nat(new_s_reserves - old_s_reserves) of [ + Some(value) -> { + if value > 0n + then { + // send additional reserves to Yupana through Strategy + before_ops := before_ops + # typed_transfer( + Tezos.self_address(), + strat_contract, + nat_or_error(new_s_reserves - old_s_reserves, Errors.Math.nat_error), + token + ) + } + } + | None -> { // means that old_s_reserves > new_s_reserves, waiting for refiling from Strategy + // TODO: make lock flag before receiving tokens from strategy + after_ops := Constants.no_operations; + } + ]; + const ops = concat_lists( + before_ops # Tezos.transaction( + upd_state_param, + 0mutez, + get_update_state_entrypoint(strat_contract) + ), + after_ops + ) + } with ops + +function operate_with_strategy( + const token : token_t; + const reserves : nat; + const strategy_address: address; + var strategy : option(strategy_storage_t)) + : list(operation) * option(strategy_storage_t) is + block { + var return := case strategy of [ + Some(s) -> { + const new_s_reserves = calculate_desired_reserves(reserves, strategy); + const ops = update_strategy_reserves(token, s.strategy_reserves, new_s_reserves, strategy_address); + } with ops * Some(s with record[strategy_reserves = new_s_reserves]) + | None -> Constants.no_operations * None + ] + } with return \ No newline at end of file diff --git a/contracts/partials/strategy/methods.ligo b/contracts/partials/strategy/methods.ligo new file mode 100644 index 0000000..7c7e137 --- /dev/null +++ b/contracts/partials/strategy/methods.ligo @@ -0,0 +1,50 @@ +function connect_strategy( + const conn_param : conn_strategy_param; + var s : storage_t) + : return_t is + block { + const dev_address = get_dev_address(s); + require(Tezos.sender = dev_address, Errors.Dex.not_developer); + var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); + function claim_reserves( + const token_id: pool_token_id_t; + const config : strategy_storage_t) + : unit is + block { + if config.strategy_reserves > 0n + then skip// TODO: claim tokens back + } with unit; + Map.iter(claim_reserves, pool.strategy.configuration); + pool.strategy.strat_contract := params.strategy_contract; + pool.strategy.configuration := (map[]: map(pool_token_id_t, strategy_storage_t)); + s.pools[params.pool_id] := pool; + } with (Constants.no_operations, s) + +function update_token_to_strategy_params( + const conn_t_param : conn_tok_strat_param; + var s : storage_t) + : return_t is + block { + const dev_address = get_dev_address(s); + require(Tezos.sender = dev_address, Errors.Dex.not_developer); + var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); + var strat_config = pool.strategy.configuration; + strat_config[params.pool_token_id] := case Map.find_opt(params.pool_token_id, strat_config) of [ + Some(data) -> { + // TODO: reinvest with new params? + } with data with record [ + des_reserves_rate_f = params.des_reserves_rate_f; + delta_rate_f = params.delta_rate_f; + min_invest = params.min_invest; + ] + | None -> { + // TODO: update lending_market_id on strategy call + } with record[ + des_reserves_rate_f = params.des_reserves_rate_f; + delta_rate_f = params.delta_rate_f; + min_invest = params.min_invest; + strategy_reserves = 0n; + ] + ] + s.pools[params.pool_id] := pool; + } with (Constants.no_operations, s) \ No newline at end of file diff --git a/contracts/partials/strategy/types.ligo b/contracts/partials/strategy/types.ligo new file mode 100644 index 0000000..14a210b --- /dev/null +++ b/contracts/partials/strategy/types.ligo @@ -0,0 +1,25 @@ +type strategy_storage_t = [@layout:comb] record[ + des_reserves_rate_f : nat; + delta_rate_f : nat; + min_invest : nat; + strategy_reserves : nat; +]; + +type strategy_full_storage_t = [@layout:comb] record [ + strat_contract : option(address); + configuration : map(pool_token_id_t, strategy_storage_t) +] + +type conn_strategy_param = [@layout:comb] record [ + pool_id : pool_id_t; + strategy_contract : option(address); +] + +type conn_tok_strat_param = [@layout:comb] record [ + pool_id : pool_id_t; + pool_token_id : pool_token_id_t; + lending_market_id : nat; + des_reserves_rate_f : nat; + delta_rate_f : nat; + min_invest : nat; +] \ No newline at end of file diff --git a/migrations/00_dex.ts b/migrations/00_dex.ts index 210c303..147a940 100644 --- a/migrations/00_dex.ts +++ b/migrations/00_dex.ts @@ -37,7 +37,6 @@ module.exports = async (tezos: TezosToolkit, network: NetworkLiteral) => { storage.storage.dev_store.dev_lambdas = await setupLambdasToStorage( dev_lambdas_comp ); - const contractAddress: TezosAddress = await migrate( tezos, config.outputDirectory, diff --git a/migrations/01_factory.ts b/migrations/01_factory.ts index 298300c..8f059f1 100644 --- a/migrations/01_factory.ts +++ b/migrations/01_factory.ts @@ -44,8 +44,6 @@ module.exports = async (tezos: TezosToolkit, network: NetworkLiteral) => { console.log( `Factory contract: ${chalk.bgYellow.bold.redBright(contractAddress)}` ); - const dex_f: DexFactory = await DexFactory.init(tezos, contractAddress); - await dex_f.setDevAddress(process.env.ADMIN_ADDRESS, tezos); console.log( `Factory is ${chalk.green( "online" diff --git a/migrations/02_factory_pools.ts b/migrations/02_factory_pools.ts index 6a3e709..fff35ee 100644 --- a/migrations/02_factory_pools.ts +++ b/migrations/02_factory_pools.ts @@ -1,4 +1,4 @@ -import { MichelsonMap, TezosToolkit } from "@taquito/taquito"; +import { MichelsonMap, OpKind, TezosToolkit } from "@taquito/taquito"; import config from "../config"; import { FA12TokenType, @@ -6,19 +6,16 @@ import { NetworkLiteral, TezosAddress, } from "../utils/helpers"; -import { DexFactoryAPI as DexFactory } from "../test/Factory/API"; import factoryInfo from "../build/factory.json"; import pools from "../storage/pairConfig.json"; import { Token, TokenFA2, TokenFA12 } from "../test/Token"; import BigNumber from "bignumber.js"; import { confirmOperation } from "../utils/confirmation"; -const tokensAmount = new BigNumber("100000"); - module.exports = async (tezos: TezosToolkit, network: NetworkLiteral) => { - await new Promise((r) => setTimeout(r, 10000)); const factoryAddress: TezosAddress = factoryInfo.networks[network].factory; const factory = await tezos.contract.at(factoryAddress); + const sender_addr = await tezos.signer.publicKeyHash(); let poolData; for (const pair of pools) { console.log("Pool", pair.name); @@ -102,6 +99,25 @@ module.exports = async (tezos: TezosToolkit, network: NetworkLiteral) => { " disapproved" ); } + const dex_address: TezosAddress = await factory.contractViews + .get_pool({ + tokens: pair.tokensInfo.map((token) => token.token), + deployer: sender_addr, + }) + .executeView({ viewCaller: sender_addr }); + const dex = await tezos.contract.at(dex_address); + op = await dex.methods.set_admin(process.env.ADMIN_ADDRESS).send(); + await confirmOperation(tezos, op.hash); + console.log("Admin set ", process.env.ADMIN_ADDRESS); console.log(`Dex of ${pair.name} started`); } + let operation = await factory.methods + .set_whitelist(false, sender_addr) + .send(); + await confirmOperation(tezos, operation.hash); + console.log("Removed from whitelist ", sender_addr); + operation = await factory.methods + .set_dev_address(process.env.ADMIN_ADDRESS) + .send(); + await confirmOperation(tezos, operation.hash); }; From bc6d3e53c46cc0e6ff59370bee18f9e6bf8b40f2 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Wed, 26 Oct 2022 16:47:08 +0300 Subject: [PATCH 05/67] Inject strategy methods and lambdas --- contracts/compiled/dex4factory.tz | 716 +++++++++++++++-------- contracts/main/dex.ligo | 18 +- contracts/main/factory.ligo | 14 +- contracts/partials/constants.ligo | 1 + contracts/partials/dex_core/helpers.ligo | 2 +- contracts/partials/dex_core/storage.ligo | 4 + contracts/partials/dex_core/types.ligo | 4 +- contracts/partials/errors.ligo | 7 + contracts/partials/factory/helpers.ligo | 9 +- contracts/partials/factory/lambdas.ligo | 4 +- contracts/partials/factory/storage.ligo | 6 +- contracts/partials/strategy/helpers.ligo | 44 +- contracts/partials/strategy/lambdas.ligo | 86 +++ contracts/partials/strategy/methods.ligo | 66 +-- contracts/partials/strategy/types.ligo | 31 +- contracts/partials/utils.ligo | 1 + package.json | 9 +- scripts/commands/compile/utils.ts | 4 +- test/lambdas/Strategy_lambdas.json | 14 + 19 files changed, 700 insertions(+), 340 deletions(-) create mode 100644 contracts/partials/strategy/lambdas.ligo create mode 100644 test/lambdas/Strategy_lambdas.json diff --git a/contracts/compiled/dex4factory.tz b/contracts/compiled/dex4factory.tz index 8c27f16..d550919 100644 --- a/contracts/compiled/dex4factory.tz +++ b/contracts/compiled/dex4factory.tz @@ -10,63 +10,76 @@ (or (or (address %set_default_referral) (pair %set_fees (nat %pool_id) (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)))) (nat %stop_ramp_A)))) - (or %user_action - (or %use_dex - (or (or (pair %claim_referral - (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - (nat %amount)) - (pair %divest + (or (or %use_strategy + (or (pair %connect_strategy (nat %pool_id) (option %strategy_contract address)) + (pair %set_token_strategy + (nat %pool_id) + (nat %pool_token_id) + (nat %lending_market_id) + (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest))) + (pair %set_token_strategy_update_flag + (nat %pool_id) + (nat %pool_token_id) + (bool %flag))) + (or %user_action + (or %use_dex + (or (or (pair %claim_referral + (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + (nat %amount)) + (pair %divest + (nat %pool_id) + (map %min_amounts_out nat nat) + (nat %shares) + (timestamp %deadline) + (option %receiver address))) + (or (pair %divest_imbalanced + (nat %pool_id) + (map %amounts_out nat nat) + (nat %max_shares) + (timestamp %deadline) + (option %receiver address) + (option %referral address)) + (pair %divest_one_coin + (nat %pool_id) + (nat %shares) + (nat %token_index) + (nat %min_amount_out) + (timestamp %deadline) + (option %receiver address) + (option %referral address)))) + (or (or (pair %invest + (nat %pool_id) + (nat %shares) + (map %in_amounts nat nat) + (timestamp %deadline) + (option %receiver address) + (option %referral address)) + (or %stake + (pair %add (nat %pool_id) (nat %amount)) + (pair %remove (nat %pool_id) (nat %amount)))) + (pair %swap (nat %pool_id) - (map %min_amounts_out nat nat) - (nat %shares) - (timestamp %deadline) - (option %receiver address))) - (or (pair %divest_imbalanced - (nat %pool_id) - (map %amounts_out nat nat) - (nat %max_shares) - (timestamp %deadline) - (option %receiver address) - (option %referral address)) - (pair %divest_one_coin - (nat %pool_id) - (nat %shares) - (nat %token_index) + (nat %idx_from) + (nat %idx_to) + (nat %amount) (nat %min_amount_out) (timestamp %deadline) (option %receiver address) (option %referral address)))) - (or (or (pair %invest - (nat %pool_id) - (nat %shares) - (map %in_amounts nat nat) - (timestamp %deadline) - (option %receiver address) - (option %referral address)) - (or %stake - (pair %add (nat %pool_id) (nat %amount)) - (pair %remove (nat %pool_id) (nat %amount)))) - (pair %swap - (nat %pool_id) - (nat %idx_from) - (nat %idx_to) - (nat %amount) - (nat %min_amount_out) - (timestamp %deadline) - (option %receiver address) - (option %referral address)))) - (or %use_token - (or (or (pair %balance_of - (list %requests (pair (address %owner) (nat %token_id))) - (contract %callback - (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))))) - (pair %total_supply (nat %token_id) (contract %receiver nat))) - (or (list %transfer - (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount))))) - (pair %update_metadata (nat %token_id) (map %token_info string bytes)))) - (list %update_operators - (or (pair %add_operator (address %owner) (address %operator) (nat %token_id)) - (pair %remove_operator (address %owner) (address %operator) (nat %token_id))))))) ; + (or %use_token + (or (or (pair %balance_of + (list %requests (pair (address %owner) (nat %token_id))) + (contract %callback + (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))))) + (pair %total_supply (nat %token_id) (contract %receiver nat))) + (or (list %transfer + (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount))))) + (pair %update_metadata (nat %token_id) (map %token_info string bytes)))) + (list %update_operators + (or (pair %add_operator (address %owner) (address %operator) (nat %token_id)) + (pair %remove_operator (address %owner) (address %operator) (nat %token_id)))))))) ; storage (pair (pair %storage (address %admin) @@ -87,6 +100,15 @@ nat (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_updatable)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -111,7 +133,8 @@ (big_map %metadata string bytes) (big_map %admin_lambdas nat bytes) (big_map %dex_lambdas nat bytes) - (big_map %token_lambdas nat bytes)) ; + (big_map %token_lambdas nat bytes) + (big_map %strat_lambdas nat bytes)) ; code { PUSH string "not-contract-admin" ; PUSH string "not-started" ; PUSH string "function-not-set" ; @@ -144,7 +167,7 @@ UPDATE 30 ; UPDATE 1 } } { DROP ; SWAP } } - { DROP ; SWAP } ; + { IF_LEFT { DROP ; SWAP } { DROP ; SWAP } } ; SWAP ; IF_LEFT { IF_LEFT @@ -261,6 +284,15 @@ nat (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_updatable)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -301,6 +333,15 @@ nat (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_updatable)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -337,70 +378,45 @@ DROP ; IF_LEFT { DIG 4 ; + DROP ; + PUSH string "no-address" ; DUP 3 ; CAR ; - GET 30 ; + GET 29 ; + UNIT ; + VIEW "dev_address" address ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH string "not-developer" ; + SWAP ; + SENDER ; + COMPARE ; + EQ ; IF { DROP } { FAILWITH } ; DIG 3 ; DUP 3 ; - GET 7 ; + GET 10 ; DUP 3 ; IF_LEFT - { IF_LEFT - { IF_LEFT { DROP ; PUSH nat 5 } { DROP ; PUSH nat 2 } } - { IF_LEFT { DROP ; PUSH nat 3 } { DROP ; PUSH nat 4 } } } - { IF_LEFT - { IF_LEFT { DROP ; PUSH nat 1 } { DROP ; PUSH nat 6 } } - { DROP ; PUSH nat 0 } } ; + { IF_LEFT { DROP ; PUSH nat 0 } { DROP ; PUSH nat 1 } } + { DROP ; PUSH nat 2 } ; GET ; IF_NONE { FAILWITH } { SWAP ; DROP } ; DIG 3 ; SWAP ; UNPACK (lambda - (pair (or (or (or (pair %claim_referral - (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - (nat %amount)) - (pair %divest - (nat %pool_id) - (map %min_amounts_out nat nat) - (nat %shares) - (timestamp %deadline) - (option %receiver address))) - (or (pair %divest_imbalanced - (nat %pool_id) - (map %amounts_out nat nat) - (nat %max_shares) - (timestamp %deadline) - (option %receiver address) - (option %referral address)) - (pair %divest_one_coin - (nat %pool_id) - (nat %shares) - (nat %token_index) - (nat %min_amount_out) - (timestamp %deadline) - (option %receiver address) - (option %referral address)))) - (or (or (pair %invest - (nat %pool_id) - (nat %shares) - (map %in_amounts nat nat) - (timestamp %deadline) - (option %receiver address) - (option %referral address)) - (or %stake - (pair %add (nat %pool_id) (nat %amount)) - (pair %remove (nat %pool_id) (nat %amount)))) - (pair %swap + (pair (or (or (pair %connect_strategy (nat %pool_id) (option %strategy_contract address)) + (pair %set_token_strategy (nat %pool_id) - (nat %idx_from) - (nat %idx_to) - (nat %amount) - (nat %min_amount_out) - (timestamp %deadline) - (option %receiver address) - (option %referral address)))) + (nat %pool_token_id) + (nat %lending_market_id) + (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest))) + (pair %set_token_strategy_update_flag + (nat %pool_id) + (nat %pool_token_id) + (bool %flag))) (pair (address %admin) (address %default_referral) (set %managers address) @@ -419,6 +435,15 @@ nat (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_updatable)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -459,6 +484,15 @@ nat (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_updatable)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -486,137 +520,331 @@ DIG 2 ; PAIR ; EXEC ; - DUP ; + UNPAIR ; DUG 2 ; - CDR ; UPDATE 1 ; SWAP ; - CAR ; PAIR } - { DIG 4 ; - DUP 3 ; - CAR ; - GET 30 ; - IF { DROP } { FAILWITH } ; - DIG 3 ; - DUP 3 ; - GET 8 ; - DUP 3 ; - IF_LEFT - { IF_LEFT - { IF_LEFT { DROP ; PUSH nat 1 } { DROP ; PUSH nat 4 } } - { IF_LEFT { DROP ; PUSH nat 0 } { DROP ; PUSH nat 3 } } } - { DROP ; PUSH nat 2 } ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DIG 3 ; - SWAP ; - UNPACK - (lambda - (pair (or (or (or (pair %balance_of - (list %requests (pair (address %owner) (nat %token_id))) - (contract %callback - (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))))) - (pair %total_supply (nat %token_id) (contract %receiver nat))) - (or (list %transfer - (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount))))) - (pair %update_metadata (nat %token_id) (map %token_info string bytes)))) - (list %update_operators - (or (pair %add_operator (address %owner) (address %operator) (nat %token_id)) - (pair %remove_operator (address %owner) (address %operator) (nat %token_id))))) - (pair (pair %storage - (address %admin) - (address %default_referral) - (set %managers address) - (nat %pools_count) - (big_map %tokens - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (big_map %pool_to_id bytes nat) - (big_map %pools - nat - (pair (nat %initial_A_f) - (timestamp %initial_A_time) - (nat %future_A_f) - (timestamp %future_A_time) - (map %tokens_info - nat - (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) - (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - (pair %staker_accumulator - (map %accumulator_f nat nat) - (map %total_fees nat nat) - (nat %total_staked)) - (nat %total_supply))) - (big_map %ledger (pair address nat) nat) - (big_map %allowances (pair address nat) (set address)) - (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) - (big_map %dev_rewards - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - nat) - (big_map %referral_rewards - (pair address - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - nat) - (big_map %stakers_balance - (pair address nat) - (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) - (pair %quipu_token (address %token_address) (nat %token_id)) - (address %factory_address) - (bool %started)) - (big_map %metadata string bytes) - (big_map %admin_lambdas nat bytes) - (big_map %dex_lambdas nat bytes) - (big_map %token_lambdas nat bytes))) - (pair (list operation) - (pair (pair %storage - (address %admin) - (address %default_referral) - (set %managers address) - (nat %pools_count) - (big_map %tokens - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (big_map %pool_to_id bytes nat) - (big_map %pools - nat - (pair (nat %initial_A_f) - (timestamp %initial_A_time) - (nat %future_A_f) - (timestamp %future_A_time) - (map %tokens_info - nat - (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) - (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - (pair %staker_accumulator - (map %accumulator_f nat nat) - (map %total_fees nat nat) - (nat %total_staked)) - (nat %total_supply))) - (big_map %ledger (pair address nat) nat) - (big_map %allowances (pair address nat) (set address)) - (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) - (big_map %dev_rewards - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - nat) - (big_map %referral_rewards - (pair address - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - nat) - (big_map %stakers_balance - (pair address nat) - (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) - (pair %quipu_token (address %token_address) (nat %token_id)) - (address %factory_address) - (bool %started)) - (big_map %metadata string bytes) - (big_map %admin_lambdas nat bytes) - (big_map %dex_lambdas nat bytes) - (big_map %token_lambdas nat bytes)))) ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUG 2 ; - PAIR ; - EXEC } } } ; + { IF_LEFT + { DIG 4 ; + DUP 3 ; + CAR ; + GET 30 ; + IF { DROP } { FAILWITH } ; + DIG 3 ; + DUP 3 ; + GET 7 ; + DUP 3 ; + IF_LEFT + { IF_LEFT + { IF_LEFT { DROP ; PUSH nat 5 } { DROP ; PUSH nat 2 } } + { IF_LEFT { DROP ; PUSH nat 3 } { DROP ; PUSH nat 4 } } } + { IF_LEFT + { IF_LEFT { DROP ; PUSH nat 1 } { DROP ; PUSH nat 6 } } + { DROP ; PUSH nat 0 } } ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DIG 3 ; + SWAP ; + UNPACK + (lambda + (pair (or (or (or (pair %claim_referral + (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + (nat %amount)) + (pair %divest + (nat %pool_id) + (map %min_amounts_out nat nat) + (nat %shares) + (timestamp %deadline) + (option %receiver address))) + (or (pair %divest_imbalanced + (nat %pool_id) + (map %amounts_out nat nat) + (nat %max_shares) + (timestamp %deadline) + (option %receiver address) + (option %referral address)) + (pair %divest_one_coin + (nat %pool_id) + (nat %shares) + (nat %token_index) + (nat %min_amount_out) + (timestamp %deadline) + (option %receiver address) + (option %referral address)))) + (or (or (pair %invest + (nat %pool_id) + (nat %shares) + (map %in_amounts nat nat) + (timestamp %deadline) + (option %receiver address) + (option %referral address)) + (or %stake + (pair %add (nat %pool_id) (nat %amount)) + (pair %remove (nat %pool_id) (nat %amount)))) + (pair %swap + (nat %pool_id) + (nat %idx_from) + (nat %idx_to) + (nat %amount) + (nat %min_amount_out) + (timestamp %deadline) + (option %receiver address) + (option %referral address)))) + (pair (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_updatable)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started))) + (pair (list operation) + (pair (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_updatable)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started)))) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 3 ; + CAR ; + DIG 2 ; + PAIR ; + EXEC ; + DUP ; + DUG 2 ; + CDR ; + UPDATE 1 ; + SWAP ; + CAR ; + PAIR } + { DIG 4 ; + DUP 3 ; + CAR ; + GET 30 ; + IF { DROP } { FAILWITH } ; + DIG 3 ; + DUP 3 ; + GET 9 ; + DUP 3 ; + IF_LEFT + { IF_LEFT + { IF_LEFT { DROP ; PUSH nat 1 } { DROP ; PUSH nat 4 } } + { IF_LEFT { DROP ; PUSH nat 0 } { DROP ; PUSH nat 3 } } } + { DROP ; PUSH nat 2 } ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DIG 3 ; + SWAP ; + UNPACK + (lambda + (pair (or (or (or (pair %balance_of + (list %requests (pair (address %owner) (nat %token_id))) + (contract %callback + (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))))) + (pair %total_supply (nat %token_id) (contract %receiver nat))) + (or (list %transfer + (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount))))) + (pair %update_metadata (nat %token_id) (map %token_info string bytes)))) + (list %update_operators + (or (pair %add_operator (address %owner) (address %operator) (nat %token_id)) + (pair %remove_operator (address %owner) (address %operator) (nat %token_id))))) + (pair (pair %storage + (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_updatable)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started)) + (big_map %metadata string bytes) + (big_map %admin_lambdas nat bytes) + (big_map %dex_lambdas nat bytes) + (big_map %token_lambdas nat bytes) + (big_map %strat_lambdas nat bytes))) + (pair (list operation) + (pair (pair %storage + (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_updatable)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started)) + (big_map %metadata string bytes) + (big_map %admin_lambdas nat bytes) + (big_map %dex_lambdas nat bytes) + (big_map %token_lambdas nat bytes) + (big_map %strat_lambdas nat bytes)))) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUG 2 ; + PAIR ; + EXEC } } } } ; view "calc_token_amount" (pair (nat %pool_id) (map %amounts nat nat) (bool %is_deposit)) nat @@ -856,7 +1084,7 @@ IF_NONE { FAILWITH } { SWAP ; DROP } } ; SWAP ; DIG 2 ; - GET 14 ; + GET 16 ; DIG 2 ; MUL ; EDIV ; @@ -918,16 +1146,19 @@ PAIR ; GET ; IF_NONE {} { SWAP ; DROP } ; - DUP ; - CDR ; + SWAP ; + GET 15 ; + CAR ; MAP { UNPAIR ; PUSH nat 0 ; - DUP 5 ; - GET 13 ; - CAR ; + PUSH nat 0 ; + PAIR ; + DUP 4 ; + CDR ; DIG 2 ; GET ; IF_NONE {} { SWAP ; DROP } ; + SWAP ; DUP 3 ; CAR ; MUL ; @@ -943,8 +1174,6 @@ EDIV ; IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; CAR } ; - DIG 2 ; - DROP ; SWAP ; CAR ; PAIR ; @@ -1549,6 +1778,7 @@ timestamp (map nat (pair nat nat nat)) (pair nat nat nat) + (pair (option address) (map nat (pair nat nat nat nat bool))) (pair (map nat nat) (map nat nat) nat) nat))) nat @@ -1951,7 +2181,7 @@ CAR ; DUP 9 ; DUP 8 ; - GET 14 ; + GET 16 ; DUP 3 ; DUP 9 ; MUL ; @@ -2121,7 +2351,7 @@ PUSH string "low-total-supply" ; DIG 3 ; DIG 4 ; - GET 14 ; + GET 16 ; SUB ; ISNAT ; IF_NONE { FAILWITH } { SWAP ; DROP } ; @@ -2151,7 +2381,7 @@ SWAP ; DUP ; DUG 2 ; - GET 14 ; + GET 16 ; PUSH nat 1000000000000000000 ; DIG 2 ; GET 4 ; @@ -2196,7 +2426,7 @@ DIG 2 ; GET ; IF_NONE { FAILWITH } { SWAP ; DROP } ; - GET 14 } ; + GET 16 } ; view "get_balance" (list (pair (address %owner) (nat %token_id))) (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))) diff --git a/contracts/main/dex.ligo b/contracts/main/dex.ligo index f8563ad..10ebeaa 100644 --- a/contracts/main/dex.ligo +++ b/contracts/main/dex.ligo @@ -9,6 +9,7 @@ #include "../partials/common_types.ligo" #include "../partials/fa12/types.ligo" #include "../partials/fa2/types.ligo" +#include "../partials/strategy/types.ligo" #if !FACTORY #include "../partials/dev/types.ligo" #else @@ -25,10 +26,12 @@ #endif #include "../partials/dex_core/helpers.ligo" #include "../partials/fa2/helpers.ligo" +#include "../partials/strategy/helpers.ligo" #include "../partials/dex_core/math.ligo" (* Lambda entrypoints *) #include "../partials/admin/lambdas.ligo" #include "../partials/fa2/lambdas.ligo" +#include "../partials/strategy/lambdas.ligo" #include "../partials/dex_core/lambdas.ligo" #if !FACTORY #include "../partials/dev/lambdas.ligo" @@ -39,6 +42,7 @@ #endif #include "../partials/admin/methods.ligo" #include "../partials/fa2/methods.ligo" +#include "../partials/strategy/methods.ligo" #include "../partials/dex_core/methods.ligo" (* View methods *) #include "../partials/fa2/views.ligo" @@ -51,18 +55,20 @@ function main( block { case p of [ #if !FACTORY - | Set_dex_function(params) -> s := set_function(FDex, params, s) - | Set_admin_function(params) -> s := set_function(FAdmin, params, s) - | Set_token_function(params) -> s := set_function(FToken, params, s) - | Set_dev_function(params) -> s := set_function(FDev, params, s) - | Use_dev(params) -> s.storage.dev_store := call_dev(params, s.storage.dev_store) + | Set_dex_function(params) -> s := set_function(FDex, params, s) + | Set_admin_function(params) -> s := set_function(FAdmin, params, s) + | Set_token_function(params) -> s := set_function(FToken, params, s) + | Set_dev_function(params) -> s := set_function(FDev, params, s) + | Set_strategy_function(params) -> s := set_function(FStrat, params, s) + | Use_dev(params) -> s.storage.dev_store := call_dev(params, s.storage.dev_store) #else - | Factory_action(params) -> s := factory_action(params, s) + | Factory_action(params) -> s := factory_action(params, s) #endif | _ -> skip ] } with case p of [ | User_action(params) -> call_user_action(params, s) | Use_admin(params) -> call_admin(params, s) + | Use_strategy(params) -> call_strategy(params, s) | _ -> (Constants.no_operations, s) ] \ No newline at end of file diff --git a/contracts/main/factory.ligo b/contracts/main/factory.ligo index 3e78897..7b03576 100644 --- a/contracts/main/factory.ligo +++ b/contracts/main/factory.ligo @@ -4,6 +4,7 @@ #define FACTORY #include "../partials/fa12/types.ligo" #include "../partials/fa2/types.ligo" +#include "../partials/strategy/types.ligo" #include "../partials/dex_core/storage.ligo" #include "../partials/admin/types.ligo" #include "../partials/dex_core/types.ligo" @@ -24,12 +25,13 @@ function main( : fact_return_t is block { case p of [ - | Set_init_function(params) -> s.init_func := set_init_function(params, s) - | Set_dev_function(params) -> s := set_function(FDev, params, s) - | Set_admin_function(params) -> s := set_function(FAdmin, params, s) - | Set_dex_function(params) -> s := set_function(FDex, params, s) - | Set_token_function(params) -> s := set_function(FToken, params, s) - | Use_dev(params) -> s.storage.dev_store := call_dev(params, s.storage.dev_store) + | Set_init_function(params) -> s.init_func := set_init_function(params, s) + | Set_dev_function(params) -> s := set_function(FDev, params, s) + | Set_admin_function(params) -> s := set_function(FAdmin, params, s) + | Set_dex_function(params) -> s := set_function(FDex, params, s) + | Set_token_function(params) -> s := set_function(FToken, params, s) + | Set_strategy_function(params) -> s := set_function(FStrat, params, s) + | Use_dev(params) -> s.storage.dev_store := call_dev(params, s.storage.dev_store) | _ -> skip ] } with case p of [ diff --git a/contracts/partials/constants.ligo b/contracts/partials/constants.ligo index a34971b..a95b4dc 100644 --- a/contracts/partials/constants.ligo +++ b/contracts/partials/constants.ligo @@ -4,6 +4,7 @@ const dex_func_count : nat = 7n; const dev_func_count : nat = 2n; const token_func_count : nat = 5n; +const strat_func_count : nat = 3n; #if !FACTORY const admin_func_count : nat = 8n; #else diff --git a/contracts/partials/dex_core/helpers.ligo b/contracts/partials/dex_core/helpers.ligo index 1b6915b..43435f5 100644 --- a/contracts/partials/dex_core/helpers.ligo +++ b/contracts/partials/dex_core/helpers.ligo @@ -219,7 +219,7 @@ function get_pool_info( strategy = record [ strat_contract = (None: option(address)); configuration = (map []: map(token_pool_idx_t, strategy_storage_t)); - ] + ]; staker_accumulator = record [ accumulator_f = (map []: map(token_pool_idx_t, nat)); total_fees = (map []: map(token_pool_idx_t, nat)); diff --git a/contracts/partials/dex_core/storage.ligo b/contracts/partials/dex_core/storage.ligo index 167617b..20c7deb 100644 --- a/contracts/partials/dex_core/storage.ligo +++ b/contracts/partials/dex_core/storage.ligo @@ -98,7 +98,11 @@ type full_storage_t is [@layout:comb] record [ admin_lambdas : big_map(nat, bytes); (* map with admin-related functions code *) dex_lambdas : big_map(nat, bytes); (* map with exchange-related functions code *) token_lambdas : big_map(nat, bytes); (* map with token-related functions code *) + strat_lambdas : big_map(nat, bytes); (* map with strategy-related functions code *) ] type return_t is list(operation) * storage_t + +type strat_func_t is (strategy_action_t * storage_t) -> return_t + type full_return_t is list(operation) * full_storage_t diff --git a/contracts/partials/dex_core/types.ligo b/contracts/partials/dex_core/types.ligo index fba497f..2de0564 100644 --- a/contracts/partials/dex_core/types.ligo +++ b/contracts/partials/dex_core/types.ligo @@ -1,4 +1,4 @@ -type func_entry_t is FAdmin | FDex | FToken | FDev +type func_entry_t is FAdmin | FDex | FToken | FDev | FStrat type staker_info_req_t is [@layout:comb] record [ user : address; @@ -149,6 +149,7 @@ type factory_action_t is type full_action_t is | Use_admin of admin_action_t +| Use_strategy of strategy_action_t | User_action of user_action_t #if !FACTORY | Use_dev of dev_action_t @@ -159,6 +160,7 @@ type full_action_t is | Set_token_function of set_lambda_func_t (* sets the FA function, is used before the whole system is launched *) | Set_dev_function of set_lambda_func_t +| Set_strategy_function of set_lambda_func_t #else | Factory_action of factory_action_t #endif diff --git a/contracts/partials/errors.ligo b/contracts/partials/errors.ligo index ad3535e..72c0189 100644 --- a/contracts/partials/errors.ligo +++ b/contracts/partials/errors.ligo @@ -46,6 +46,7 @@ module FA2 is { module Math is { const nat_error : string = "value-not-natural"; const ediv_error : string = "ediv-error"; + const percent_overflow : string = "percent-overflow"; } module Factory is { @@ -55,4 +56,10 @@ module Factory is { const not_deployer : string = "not-deployer-of-pool"; const not_dex : string = "not-dex"; const burn_rate_overflow : string = "burn-rate-overflow"; +} + +module Strategy is { + const out_of_delta_bounds : string = "out-of-delta-bounds"; + const no_update_state_entrypoint: string = "no-update-state-EP"; + const unknown_token : string = "no-token-strategy-set"; } \ No newline at end of file diff --git a/contracts/partials/factory/helpers.ligo b/contracts/partials/factory/helpers.ligo index fdb3b3f..1ddbc27 100644 --- a/contracts/partials/factory/helpers.ligo +++ b/contracts/partials/factory/helpers.ligo @@ -114,11 +114,13 @@ function form_pool_storage( const tokens_info : map(token_pool_idx_t, token_info_t); const a_constant : nat; const fees : fees_storage_t; + const strategy : option(address); const default_referral: address; const managers : set(address); const quipu_token : fa2_token_t; const a_lambdas : big_map(nat, bytes); - const t_lambdas : big_map(nat, bytes)) + const t_lambdas : big_map(nat, bytes); + const s_lambdas : big_map(nat, bytes)) : pool_f_storage_t is block { const default_token_id = 0n; @@ -129,6 +131,10 @@ function form_pool_storage( future_A_time = Tezos.now; tokens_info = tokens_info; fee = fees; + strategy = record[ + strat_contract = strategy; + configuration = (map[]: map(token_pool_idx_t, strategy_storage_t)); + ]; staker_accumulator = record [ accumulator_f = (map []: map(token_pool_idx_t, nat)); total_fees = (map []: map(token_pool_idx_t, nat)); @@ -169,4 +175,5 @@ function form_pool_storage( admin_lambdas = a_lambdas; dex_lambdas = (big_map[]: big_map(nat, bytes)); // too large for injection in one operation token_lambdas = t_lambdas; + strat_lambdas = s_lambdas; ] \ No newline at end of file diff --git a/contracts/partials/factory/lambdas.ligo b/contracts/partials/factory/lambdas.ligo index 86971e0..ad148b7 100644 --- a/contracts/partials/factory/lambdas.ligo +++ b/contracts/partials/factory/lambdas.ligo @@ -45,11 +45,13 @@ function add_pool( tokens_info, params.a_constant, params.fees, + params.strategy, params.default_referral, params.managers, s.storage.quipu_token, s.admin_lambdas, - s.token_lambdas + s.token_lambdas, + s.strat_lambdas ) ); const pool_address = deploy.1; diff --git a/contracts/partials/factory/storage.ligo b/contracts/partials/factory/storage.ligo index ab3708b..5bd984a 100644 --- a/contracts/partials/factory/storage.ligo +++ b/contracts/partials/factory/storage.ligo @@ -23,7 +23,8 @@ type pool_init_param_t is [@layout:comb] record [ tokens_info : map(token_pool_idx_t, token_prec_info_t); default_referral : address; managers : set(address); - fees : fees_storage_t + fees : fees_storage_t; + strategy : option(address); ] type inner_store_t is [@layout:comb] record[ @@ -43,6 +44,7 @@ type full_storage_t is [@layout:comb] record [ admin_lambdas : big_map(nat, bytes); (* map with admin-related functions code *) dex_lambdas : big_map(nat, bytes); (* map with exchange-related functions code *) token_lambdas : big_map(nat, bytes); (* map with token-related functions code *) + strat_lambdas : big_map(nat, bytes); (* map with strategy-related functions code *) init_func : option(bytes); metadata : big_map(string, bytes); (* TZIP-16 metadata *) ] @@ -60,6 +62,8 @@ type fact_action_t is | Set_dev_function of set_lambda_func_t | Set_admin_function of set_lambda_func_t (* sets the admin specific function, is used before the whole system is launched *) +| Set_strategy_function of set_lambda_func_t +(* sets the strategy connectors functions, is used before the whole system is launched *) | Set_dex_function of set_lambda_func_t (* sets the dex specific function, is used before the whole system is launched *) | Set_token_function of set_lambda_func_t diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index 28973bd..ffa919e 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -8,7 +8,7 @@ function check_strategy_bounds( const rate_f = reserves * Constants.precision / desired_reserves; const in_upper_bound = rate_f < (desired_rate_f + delta_rate_f); const in_lower_bound = rate_f > nat_or_error(desired_rate_f - delta_rate_f, Errors.Math.nat_error); - } with require(in_upper_bound and in_lower_bound, Erorrs.Strategy.out_of_delta_bounds) + } with require(in_upper_bound and in_lower_bound, Errors.Strategy.out_of_delta_bounds) function calculate_desired_reserves( const reserves : nat; @@ -30,12 +30,13 @@ function calculate_desired_reserves( [@inline] function get_update_state_entrypoint( const strategy_address: address) : contract(upd_strat_state_t) is - Utils.unwrap( + unwrap( (Tezos.get_entrypoint_opt("%update_token_state", strategy_address): option(contract(upd_strat_state_t))), Errors.Strategy.no_update_state_entrypoint ); function update_strategy_reserves( + const token_pool_id : token_pool_idx_t; const token : token_t; const old_s_reserves : nat; const new_s_reserves : nat; @@ -43,7 +44,7 @@ function update_strategy_reserves( : list(operation) is block { const upd_state_param : upd_strat_state_t = record[ - token = token; + pool_token_id = token_pool_id; new_balance = new_s_reserves ]; var before_ops := Constants.no_operations; @@ -53,13 +54,12 @@ function update_strategy_reserves( if value > 0n then { // send additional reserves to Yupana through Strategy - before_ops := before_ops - # typed_transfer( - Tezos.self_address(), + before_ops := typed_transfer( + Tezos.self_address(unit), strat_contract, nat_or_error(new_s_reserves - old_s_reserves, Errors.Math.nat_error), token - ) + ) # before_ops; } } | None -> { // means that old_s_reserves > new_s_reserves, waiting for refiling from Strategy @@ -68,27 +68,33 @@ function update_strategy_reserves( } ]; const ops = concat_lists( - before_ops # Tezos.transaction( + Tezos.transaction( upd_state_param, 0mutez, get_update_state_entrypoint(strat_contract) - ), + ) # before_ops, after_ops ) } with ops function operate_with_strategy( + const token_pool_id : token_pool_idx_t; const token : token_t; const reserves : nat; const strategy_address: address; - var strategy : option(strategy_storage_t)) - : list(operation) * option(strategy_storage_t) is + var strategy : strategy_storage_t) + : list(operation) * strategy_storage_t is block { - var return := case strategy of [ - Some(s) -> { - const new_s_reserves = calculate_desired_reserves(reserves, strategy); - const ops = update_strategy_reserves(token, s.strategy_reserves, new_s_reserves, strategy_address); - } with ops * Some(s with record[strategy_reserves = new_s_reserves]) - | None -> Constants.no_operations * None - ] - } with return \ No newline at end of file + var ops := Constants.no_operations; + if strategy.is_updatable then { + const new_s_reserves = calculate_desired_reserves(reserves, strategy); + ops := update_strategy_reserves( + token_pool_id, + token, + strategy.strategy_reserves, + new_s_reserves, + strategy_address + ); + strategy.strategy_reserves := new_s_reserves; + } + } with (ops, strategy) \ No newline at end of file diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo new file mode 100644 index 0000000..b33fd3d --- /dev/null +++ b/contracts/partials/strategy/lambdas.ligo @@ -0,0 +1,86 @@ +function connect_strategy( + const p : strategy_action_t; + var s : storage_t) + : return_t is + block { + var operations: list(operation) := Constants.no_operations; + case p of [ + | Connect_strategy(params) -> { + var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); + function claim_reserves( + const token_id: token_pool_idx_t; + const config : strategy_storage_t) + : unit is + block { + if config.strategy_reserves > 0n + then skip// TODO: claim tokens back + } with unit; + Map.iter(claim_reserves, pool.strategy.configuration); + pool.strategy.strat_contract := params.strategy_contract; + pool.strategy.configuration := (map[]: map(token_pool_idx_t, strategy_storage_t)); + s.pools[params.pool_id] := pool; + } + | _ -> unreachable(Unit) + ] + } with (operations, s) + +function update_token_to_strategy_params( + const p : strategy_action_t; + var s : storage_t) + : return_t is + block { + var operations: list(operation) := Constants.no_operations; + case p of [ + | Set_token_strategy(params) -> { + var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); + var strat_config := pool.strategy.configuration; + require(params.des_reserves_rate_f + params.delta_rate_f < Constants.precision, Errors.Math.percent_overflow); + strat_config[params.pool_token_id] := case Map.find_opt(params.pool_token_id, strat_config) of [ + Some(data) -> { + (* WARNING: lending_market_id is ignored in this case + because pool_token_id already added to Strategy *) + // TODO: call update stategy with new desired params? + const _ = 0n; + } with data with record [ + des_reserves_rate_f = params.des_reserves_rate_f; + delta_rate_f = params.delta_rate_f; + min_invest = params.min_invest; + ] + | None -> { + // TODO: update lending_market_id on strategy call + const _ = 0n; + } with record[ + des_reserves_rate_f = params.des_reserves_rate_f; + delta_rate_f = params.delta_rate_f; + min_invest = params.min_invest; + strategy_reserves = 0n; + is_updatable = True; + ] + ]; + pool.strategy.configuration := strat_config; + s.pools[params.pool_id] := pool; + } + | _ -> unreachable(Unit) + ] + } with (operations, s) + +function set_updatable( + const p : strategy_action_t; + var s : storage_t) + : return_t is + block { + var operations: list(operation) := Constants.no_operations; + case p of [ + | Set_token_strategy_update_flag(params) -> { + var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); + pool.strategy.configuration[params.pool_token_id] := unwrap( + pool.strategy.configuration[params.pool_token_id], + Errors.Strategy.unknown_token + ) with record [ + is_updatable = params.flag; + ]; + s.pools[params.pool_id] := pool; + } + | _ -> unreachable(Unit) + ] + } with (operations, s) \ No newline at end of file diff --git a/contracts/partials/strategy/methods.ligo b/contracts/partials/strategy/methods.ligo index 7c7e137..17fad92 100644 --- a/contracts/partials/strategy/methods.ligo +++ b/contracts/partials/strategy/methods.ligo @@ -1,50 +1,18 @@ -function connect_strategy( - const conn_param : conn_strategy_param; - var s : storage_t) - : return_t is - block { - const dev_address = get_dev_address(s); - require(Tezos.sender = dev_address, Errors.Dex.not_developer); - var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); - function claim_reserves( - const token_id: pool_token_id_t; - const config : strategy_storage_t) - : unit is - block { - if config.strategy_reserves > 0n - then skip// TODO: claim tokens back - } with unit; - Map.iter(claim_reserves, pool.strategy.configuration); - pool.strategy.strat_contract := params.strategy_contract; - pool.strategy.configuration := (map[]: map(pool_token_id_t, strategy_storage_t)); - s.pools[params.pool_id] := pool; - } with (Constants.no_operations, s) +(* This methods called only by dev and modifies only `storage` property of full storage *) +[@inline] function call_strategy( + const p : strategy_action_t; + var s : full_storage_t) + : full_return_t is + block { + const dev_address = get_dev_address(s.storage); + require(Tezos.sender = dev_address, Errors.Dex.not_developer); + const idx : nat = case p of [ + | Connect_strategy(_) -> 0n + | Set_token_strategy(_) -> 1n + | Set_token_strategy_update_flag(_) -> 2n + ]; -function update_token_to_strategy_params( - const conn_t_param : conn_tok_strat_param; - var s : storage_t) - : return_t is - block { - const dev_address = get_dev_address(s); - require(Tezos.sender = dev_address, Errors.Dex.not_developer); - var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); - var strat_config = pool.strategy.configuration; - strat_config[params.pool_token_id] := case Map.find_opt(params.pool_token_id, strat_config) of [ - Some(data) -> { - // TODO: reinvest with new params? - } with data with record [ - des_reserves_rate_f = params.des_reserves_rate_f; - delta_rate_f = params.delta_rate_f; - min_invest = params.min_invest; - ] - | None -> { - // TODO: update lending_market_id on strategy call - } with record[ - des_reserves_rate_f = params.des_reserves_rate_f; - delta_rate_f = params.delta_rate_f; - min_invest = params.min_invest; - strategy_reserves = 0n; - ] - ] - s.pools[params.pool_id] := pool; - } with (Constants.no_operations, s) \ No newline at end of file + const lambda_bytes : bytes = unwrap(s.strat_lambdas[idx], Errors.Dex.unknown_func); + const func: strat_func_t = unwrap((Bytes.unpack(lambda_bytes) : option(strat_func_t)), Errors.Dex.wrong_use_function); + const (operations, storage) = func(p, s.storage); + } with (operations, s with record[ storage = storage ]) \ No newline at end of file diff --git a/contracts/partials/strategy/types.ligo b/contracts/partials/strategy/types.ligo index 14a210b..5854f82 100644 --- a/contracts/partials/strategy/types.ligo +++ b/contracts/partials/strategy/types.ligo @@ -1,25 +1,42 @@ -type strategy_storage_t = [@layout:comb] record[ +type strategy_storage_t is [@layout:comb] record[ des_reserves_rate_f : nat; delta_rate_f : nat; min_invest : nat; strategy_reserves : nat; + is_updatable : bool; ]; -type strategy_full_storage_t = [@layout:comb] record [ +type strategy_full_storage_t is [@layout:comb] record [ strat_contract : option(address); - configuration : map(pool_token_id_t, strategy_storage_t) + configuration : map(token_pool_idx_t, strategy_storage_t) ] -type conn_strategy_param = [@layout:comb] record [ +type conn_strategy_param is [@layout:comb] record [ pool_id : pool_id_t; strategy_contract : option(address); ] -type conn_tok_strat_param = [@layout:comb] record [ +type conn_tok_strat_param is [@layout:comb] record [ pool_id : pool_id_t; - pool_token_id : pool_token_id_t; + pool_token_id : token_pool_idx_t; lending_market_id : nat; des_reserves_rate_f : nat; delta_rate_f : nat; min_invest : nat; -] \ No newline at end of file +] + +type tok_strat_upd_fl_param is [@layout:comb] record [ + pool_id : pool_id_t; + pool_token_id : token_pool_idx_t; + flag : bool; +] + +type upd_strat_state_t is [@layout:comb] record [ + pool_token_id : nat; + new_balance : nat; +] + +type strategy_action_t is +| Connect_strategy of conn_strategy_param +| Set_token_strategy of conn_tok_strat_param +| Set_token_strategy_update_flag of tok_strat_upd_fl_param \ No newline at end of file diff --git a/contracts/partials/utils.ligo b/contracts/partials/utils.ligo index 3797998..6a5f20c 100644 --- a/contracts/partials/utils.ligo +++ b/contracts/partials/utils.ligo @@ -230,6 +230,7 @@ function get_token_by_id( | FAdmin -> s.admin_lambdas := set_func_or_fail(params, Constants.admin_func_count, s.admin_lambdas) | FDex -> s.dex_lambdas := set_func_or_fail(params, Constants.dex_func_count, s.dex_lambdas) | FToken -> s.token_lambdas := set_func_or_fail(params, Constants.token_func_count, s.token_lambdas) + | FStrat -> s.strat_lambdas := set_func_or_fail(params, Constants.strat_func_count, s.strat_lambdas) #if !INSIDE_DEX | FDev -> s.storage.dev_store.dev_lambdas := set_func_or_fail(params, Constants.dev_func_count, s.storage.dev_store.dev_lambdas) #else diff --git a/package.json b/package.json index b5a7f69..b1cea81 100644 --- a/package.json +++ b/package.json @@ -33,25 +33,28 @@ "compile": "yarn compile-contract -c dex && yarn compile-lambda-all && yarn compile-factory", "compile-contract": "yarn cli compile -F json", "compile-lambda": "yarn cli compile-lambda", - "compile-lambda-all": "yarn compile-lambda-admin && yarn compile-lambda-dex && yarn compile-lambda-dev && yarn compile-lambda-token", + "compile-lambda-all": "yarn compile-lambda-admin && yarn compile-lambda-dex && yarn compile-lambda-dev && yarn compile-lambda-token && yarn compile-lambda-strategy", "compile-lambda-standalone": "yarn -s compile-lambda -C ./contracts/main/dex.ligo", "compile-lambda-dex": "yarn -s compile-lambda-standalone -T Dex -J ./test/lambdas/Dex_lambdas.json", "compile-lambda-dev": "yarn -s compile-lambda-standalone -T Dev -J ./test/lambdas/Dev_lambdas.json", "compile-lambda-token": " yarn -s compile-lambda-standalone -T Token -J ./test/lambdas/Token_lambdas.json", + "compile-lambda-strategy": " yarn -s compile-lambda-standalone -T Strategy -J ./test/lambdas/Strategy_lambdas.json", "compile-lambda-admin": "yarn -s compile-lambda-standalone -T Admin -J ./test/lambdas/Admin_lambdas.json", "compile-factory": "yarn setup-pre-compiled && yarn compile-lambda-all-factory && yarn compile-contract -c factory && yarn cli compile-factory-lambda -F add_pool", - "compile-lambda-all-factory": "yarn compile-lambda-admin-factory && yarn compile-lambda-dex-factory && yarn compile-lambda-token-factory", + "compile-lambda-all-factory": "yarn compile-lambda-admin-factory && yarn compile-lambda-dex-factory && yarn compile-lambda-token-factory && yarn compile-lambda-strategy-factory", "compile-dex-lambda-factory": "yarn -s compile-lambda -C ./contracts/main/dex4factory.ligo", "compile-lambda-dex-factory": "yarn -s compile-dex-lambda-factory -T Dex -J ./test/lambdas/Dex_lambdas.json", "compile-lambda-token-factory": "yarn -s compile-dex-lambda-factory -T Token -J ./test/lambdas/Token_lambdas.json", "compile-lambda-admin-factory": "yarn -s compile-dex-lambda-factory -T Admin -J ./test/lambdas/Admin_lambdas.json", + "compile-lambda-strategy-factory": " yarn -s compile-dex-lambda-factory -T Strategy -J ./test/lambdas/Strategy_lambdas.json", "compile-for-test": "yarn compile-contract -c dex_test && yarn compile-lambda-all-test && yarn compile-factory", "compile-lambda-test": "yarn -s compile-lambda -C ./contracts/main/dex_test.ligo", - "compile-lambda-all-test": "yarn compile-lambda-admin-test && yarn compile-lambda-dex-test && yarn compile-lambda-dev-test && yarn compile-lambda-token-test", + "compile-lambda-all-test": "yarn compile-lambda-admin-test && yarn compile-lambda-dex-test && yarn compile-lambda-dev-test && yarn compile-lambda-token-test && yarn compile-lambda-strategy-test", "compile-lambda-dex-test": "yarn -s compile-lambda-test -T Dex -J ./test/lambdas/Dex_lambdas.json", "compile-lambda-dev-test": "yarn -s compile-lambda-test -T Dev -J ./test/lambdas/Dev_lambdas.json", "compile-lambda-token-test": "yarn -s compile-lambda-test -T Token -J ./test/lambdas/Token_lambdas.json", "compile-lambda-admin-test": "yarn -s compile-lambda-test -T Admin -J ./test/lambdas/Admin_lambdas.json", + "compile-lambda-strategy-test": " yarn -s compile-lambda-test -T Strategy -J ./test/lambdas/Strategy_lambdas.json", "recompile": "yarn clear-build && yarn compile-contract && yarn compile-lambda-all && yarn compile-factory", "migrate": "yarn cli migrate", "test": "jest", diff --git a/scripts/commands/compile/utils.ts b/scripts/commands/compile/utils.ts index acc5b20..9112d0c 100644 --- a/scripts/commands/compile/utils.ts +++ b/scripts/commands/compile/utils.ts @@ -190,7 +190,7 @@ export const compileLambdas = async ( json: string, contract: string, isDockerizedLigo = config.dockerizedLigo, - type: "Dex" | "Token" | "Permit" | "Admin" | "Dev" + type: "Dex" | "Token" | "Permit" | "Admin" | "Dev" | "Strategy" ) => { console.log(`Compiling ${contract} contract lambdas of ${type} type...\n`); @@ -247,7 +247,7 @@ export const compileLambdas = async ( "." + " ".repeat(4 - (lambda.index + 1).toString().length) + lambda.name + - " ".repeat(21 - lambda.name.length) + + " ".repeat(40 - lambda.name.length) + " successfully compiled." ); } diff --git a/test/lambdas/Strategy_lambdas.json b/test/lambdas/Strategy_lambdas.json new file mode 100644 index 0000000..4db47d4 --- /dev/null +++ b/test/lambdas/Strategy_lambdas.json @@ -0,0 +1,14 @@ +[ + { + "index": 0, + "name": "connect_strategy" + }, + { + "index": 1, + "name": "update_token_to_strategy_params" + }, + { + "index": 2, + "name": "set_updatable" + } +] From 33adeeb773d88c7062738721bb4b197ce5be558d Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 27 Oct 2022 20:07:45 +0300 Subject: [PATCH 06/67] Try fix tests --- config.ts | 4 +-- contracts/partials/strategy/helpers.ligo | 2 +- contracts/partials/strategy/lambdas.ligo | 8 +++--- contracts/partials/strategy/methods.ligo | 2 +- contracts/partials/strategy/types.ligo | 4 +-- migrations/00_dex.ts | 8 ++++++ migrations/01_factory.ts | 2 ++ package.json | 36 ++++++++++++++++++------ scenario/generate_graphs.py | 3 +- scenario/initial_storage.py | 7 +++-- scenario/test_admin.py | 3 +- scenario/test_divests.py | 3 +- scenario/test_fees.py | 3 +- scenario/test_staking.py | 3 +- scenario/test_swap.py | 3 +- scenario/test_token_to_token_transfer.py | 3 +- scripts/commands/compile/utils.ts | 2 +- scripts/commands/sandbox/types.ts | 1 + scripts/commands/sandbox/utils.ts | 7 ++++- storage/dex.ts | 1 + storage/factory.ts | 1 + test/Dex/API/dexAPI.ts | 25 ++++++++++++++-- test/Dex/API/storage.ts | 1 + test/Dex/API/types.ts | 15 ++++++++++ test/Dex/cases/before.ts | 1 + test/Factory/API/factoryAPI.ts | 10 +++++++ test/Factory/API/storage.ts | 1 + test/Factory/API/types.ts | 1 + test/Factory/cases/before.ts | 1 + test/lambdas/Strategy_lambdas.json | 2 +- utils/helpers.ts | 4 +-- 31 files changed, 131 insertions(+), 36 deletions(-) diff --git a/config.ts b/config.ts index f9864e5..16e9535 100644 --- a/config.ts +++ b/config.ts @@ -11,7 +11,7 @@ export const config = { sandbox: { host: "http://localhost", port: 20000, - protocol: TezosProtocols.ITHACA, + protocol: TezosProtocols.KATHMANDU, genesisBlockHash: "random", defaultSignerSK: "edsk3QoqBuvdamxouPhin7swCvkQNgq4jP5KZPbwWNnwdZpSpJiEbq", accounts: { @@ -33,7 +33,7 @@ export const config = { }, }, testnet: { - host: "https://ithacanet.ecadinfra.com", + host: "https://ghostnet.testnets.xyz", port: 443, faucet: null, }, diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index ffa919e..ae3b1e0 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -86,7 +86,7 @@ function operate_with_strategy( : list(operation) * strategy_storage_t is block { var ops := Constants.no_operations; - if strategy.is_updatable then { + if strategy.is_rebalance then { const new_s_reserves = calculate_desired_reserves(reserves, strategy); ops := update_strategy_reserves( token_pool_id, diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo index b33fd3d..b044baa 100644 --- a/contracts/partials/strategy/lambdas.ligo +++ b/contracts/partials/strategy/lambdas.ligo @@ -54,7 +54,7 @@ function update_token_to_strategy_params( delta_rate_f = params.delta_rate_f; min_invest = params.min_invest; strategy_reserves = 0n; - is_updatable = True; + is_rebalance = True; ] ]; pool.strategy.configuration := strat_config; @@ -64,20 +64,20 @@ function update_token_to_strategy_params( ] } with (operations, s) -function set_updatable( +function set_rebalance( const p : strategy_action_t; var s : storage_t) : return_t is block { var operations: list(operation) := Constants.no_operations; case p of [ - | Set_token_strategy_update_flag(params) -> { + | Set_token_strategy_rebalance(params) -> { var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); pool.strategy.configuration[params.pool_token_id] := unwrap( pool.strategy.configuration[params.pool_token_id], Errors.Strategy.unknown_token ) with record [ - is_updatable = params.flag; + is_rebalance = params.flag; ]; s.pools[params.pool_id] := pool; } diff --git a/contracts/partials/strategy/methods.ligo b/contracts/partials/strategy/methods.ligo index 17fad92..319305d 100644 --- a/contracts/partials/strategy/methods.ligo +++ b/contracts/partials/strategy/methods.ligo @@ -9,7 +9,7 @@ const idx : nat = case p of [ | Connect_strategy(_) -> 0n | Set_token_strategy(_) -> 1n - | Set_token_strategy_update_flag(_) -> 2n + | Set_token_strategy_rebalance(_) -> 2n ]; const lambda_bytes : bytes = unwrap(s.strat_lambdas[idx], Errors.Dex.unknown_func); diff --git a/contracts/partials/strategy/types.ligo b/contracts/partials/strategy/types.ligo index 5854f82..98c7865 100644 --- a/contracts/partials/strategy/types.ligo +++ b/contracts/partials/strategy/types.ligo @@ -3,7 +3,7 @@ type strategy_storage_t is [@layout:comb] record[ delta_rate_f : nat; min_invest : nat; strategy_reserves : nat; - is_updatable : bool; + is_rebalance : bool; ]; type strategy_full_storage_t is [@layout:comb] record [ @@ -39,4 +39,4 @@ type upd_strat_state_t is [@layout:comb] record [ type strategy_action_t is | Connect_strategy of conn_strategy_param | Set_token_strategy of conn_tok_strat_param -| Set_token_strategy_update_flag of tok_strat_upd_fl_param \ No newline at end of file +| Set_token_strategy_rebalance of tok_strat_upd_fl_param \ No newline at end of file diff --git a/migrations/00_dex.ts b/migrations/00_dex.ts index 147a940..7534a38 100644 --- a/migrations/00_dex.ts +++ b/migrations/00_dex.ts @@ -15,6 +15,7 @@ import dex_lambdas_comp from "../build/lambdas/Dex_lambdas.json"; import dev_lambdas_comp from "../build/lambdas/Dev_lambdas.json"; import token_lambdas_comp from "../build/lambdas/Token_lambdas.json"; import admin_lambdas_comp from "../build/lambdas/Admin_lambdas.json"; +import strat_lambdas_comp from "../build/lambdas/Strategy_lambdas.json"; import { Dex } from "../test/Dex/API/dexAPI"; import { DevStorage } from "../test/Developer/API/storage"; import chalk from "chalk"; @@ -69,6 +70,13 @@ module.exports = async (tezos: TezosToolkit, network: NetworkLiteral) => { 8, dex_lambdas_comp ); + await setFunctionBatchCompilled( + tezos, + contractAddress, + "Strategy", + 8, + strat_lambdas_comp + ); console.log( `DEX (${chalk.bold.bgRed.underline("standalone")}) is ${chalk.green( "online" diff --git a/migrations/01_factory.ts b/migrations/01_factory.ts index 8f059f1..45aa214 100644 --- a/migrations/01_factory.ts +++ b/migrations/01_factory.ts @@ -9,6 +9,7 @@ import { } from "../utils/helpers"; import { validateAddress, validateContractAddress } from "@taquito/utils"; import dev_lambdas_comp from "../build/lambdas/Dev_lambdas.json"; +import strat_lambdas_comp from "../build/lambdas/Strategy_lambdas.json"; import { DexFactoryAPI as DexFactory } from "../test/Factory/API"; import chalk from "chalk"; import storage from "../storage/factory"; @@ -34,6 +35,7 @@ module.exports = async (tezos: TezosToolkit, network: NetworkLiteral) => { storage.storage.dev_store.dev_lambdas = await setupLambdasToStorage( dev_lambdas_comp ); + storage.strat_lambdas = await setupLambdasToStorage(strat_lambdas_comp); const contractAddress: TezosAddress = await migrate( tezos, config.outputDirectory, diff --git a/package.json b/package.json index b1cea81..c446ce7 100644 --- a/package.json +++ b/package.json @@ -26,39 +26,57 @@ }, "scripts": { "cli": "ts-node ./scripts/cli.ts", + "help": "yarn cli --help", "start-sandbox": "yarn cli sandbox --up", "stop-sandbox": "yarn cli sandbox --down", - "setup-pre-compiled": "yarn cli compile -F tz -c dex4factory", - "compile": "yarn compile-contract -c dex && yarn compile-lambda-all && yarn compile-factory", "compile-contract": "yarn cli compile -F json", "compile-lambda": "yarn cli compile-lambda", - "compile-lambda-all": "yarn compile-lambda-admin && yarn compile-lambda-dex && yarn compile-lambda-dev && yarn compile-lambda-token && yarn compile-lambda-strategy", + "compile-lambda-standalone": "yarn -s compile-lambda -C ./contracts/main/dex.ligo", + "compile-dex-lambda-factory": "yarn -s compile-lambda -C ./contracts/main/dex4factory.ligo", + "compile-lambda-test": "yarn -s compile-lambda -C ./contracts/main/dex_test.ligo", + + "compile-lambda-all": "yarn compile-lambda-admin && yarn compile-lambda-dex && yarn compile-lambda-dev && yarn compile-lambda-token && yarn compile-lambda-strategy", "compile-lambda-dex": "yarn -s compile-lambda-standalone -T Dex -J ./test/lambdas/Dex_lambdas.json", "compile-lambda-dev": "yarn -s compile-lambda-standalone -T Dev -J ./test/lambdas/Dev_lambdas.json", "compile-lambda-token": " yarn -s compile-lambda-standalone -T Token -J ./test/lambdas/Token_lambdas.json", - "compile-lambda-strategy": " yarn -s compile-lambda-standalone -T Strategy -J ./test/lambdas/Strategy_lambdas.json", "compile-lambda-admin": "yarn -s compile-lambda-standalone -T Admin -J ./test/lambdas/Admin_lambdas.json", - "compile-factory": "yarn setup-pre-compiled && yarn compile-lambda-all-factory && yarn compile-contract -c factory && yarn cli compile-factory-lambda -F add_pool", + "compile-lambda-strategy": " yarn -s compile-lambda-standalone -T Strategy -J ./test/lambdas/Strategy_lambdas.json", + "compile-lambda-all-factory": "yarn compile-lambda-admin-factory && yarn compile-lambda-dex-factory && yarn compile-lambda-token-factory && yarn compile-lambda-strategy-factory", - "compile-dex-lambda-factory": "yarn -s compile-lambda -C ./contracts/main/dex4factory.ligo", "compile-lambda-dex-factory": "yarn -s compile-dex-lambda-factory -T Dex -J ./test/lambdas/Dex_lambdas.json", "compile-lambda-token-factory": "yarn -s compile-dex-lambda-factory -T Token -J ./test/lambdas/Token_lambdas.json", "compile-lambda-admin-factory": "yarn -s compile-dex-lambda-factory -T Admin -J ./test/lambdas/Admin_lambdas.json", "compile-lambda-strategy-factory": " yarn -s compile-dex-lambda-factory -T Strategy -J ./test/lambdas/Strategy_lambdas.json", - "compile-for-test": "yarn compile-contract -c dex_test && yarn compile-lambda-all-test && yarn compile-factory", - "compile-lambda-test": "yarn -s compile-lambda -C ./contracts/main/dex_test.ligo", + "compile-lambda-all-test": "yarn compile-lambda-admin-test && yarn compile-lambda-dex-test && yarn compile-lambda-dev-test && yarn compile-lambda-token-test && yarn compile-lambda-strategy-test", "compile-lambda-dex-test": "yarn -s compile-lambda-test -T Dex -J ./test/lambdas/Dex_lambdas.json", "compile-lambda-dev-test": "yarn -s compile-lambda-test -T Dev -J ./test/lambdas/Dev_lambdas.json", "compile-lambda-token-test": "yarn -s compile-lambda-test -T Token -J ./test/lambdas/Token_lambdas.json", "compile-lambda-admin-test": "yarn -s compile-lambda-test -T Admin -J ./test/lambdas/Admin_lambdas.json", "compile-lambda-strategy-test": " yarn -s compile-lambda-test -T Strategy -J ./test/lambdas/Strategy_lambdas.json", + + "precompile-dex": "yarn compile-lambda-all", + "compile-dex": "yarn compile-contract -c dex", + + "compile": "yarn compile-dex && yarn compile-factory", "recompile": "yarn clear-build && yarn compile-contract && yarn compile-lambda-all && yarn compile-factory", + + "precompile-factory": "yarn cli compile -F tz -c dex4factory && yarn compile-lambda-all-factory && yarn cli compile-factory-lambda -F add_pool", + "compile-factory": "yarn compile-contract -c factory", + + "precompile-for-test": "yarn compile-lambda-all-test", + "compile-for-test": "yarn compile-contract -c dex_test && yarn compile-factory", + "migrate": "yarn cli migrate", + "test": "jest", - "compile-n-test": "yarn compile-for-test && yarn start-sandbox && sleep 10 && yarn test && yarn stop-sandbox", + + "precompile-n-test": "yarn compile-for-test && yarn start-sandbox && sleep 10", + "compile-n-test": "yarn test", + "postcompile-n-test": "yarn stop-sandbox", + "clear-build": "rm -rf ./build", "lint": "eslint --ext .ts .", "fix": "eslint --ext .ts --fix ." diff --git a/scenario/generate_graphs.py b/scenario/generate_graphs.py index 42a5cf2..128bd45 100644 --- a/scenario/generate_graphs.py +++ b/scenario/generate_graphs.py @@ -6,7 +6,7 @@ from helpers import * from pytezos import ContractInterface, pytezos, MichelsonRuntimeError -from initial_storage import admin_lambdas, dex_lambdas, token_lambdas +from initial_storage import admin_lambdas, dex_lambdas, token_lambdas, start_lambdas import matplotlib.pyplot as plt import matplotlib.ticker @@ -40,6 +40,7 @@ def __init__(cls): storage = cls.dex.storage.dummy() storage["token_lambdas"] = token_lambdas storage["dex_lambdas"] = dex_lambdas + storage["strat_lambdas"] = strat_lambdas storage["admin_lambdas"] = admin_lambdas storage["storage"]["admin"] = admin cls.init_storage = storage diff --git a/scenario/initial_storage.py b/scenario/initial_storage.py index abc39f8..0a425eb 100644 --- a/scenario/initial_storage.py +++ b/scenario/initial_storage.py @@ -1,5 +1,5 @@ import json - +import os def parse_lambdas(path): lambdas = {} entries = json.load(open(path)) @@ -9,11 +9,12 @@ def parse_lambdas(path): lbytes = args[0]["bytes"] lambdas[i] = lbytes - assert int(args[1]["int"]) == i + assert int(args[1]["int"]) == i return lambdas admin_lambdas = parse_lambdas("./build/lambdas/Admin_lambdas.json") dex_lambdas = parse_lambdas("./build/lambdas/Dex_lambdas.json") token_lambdas = parse_lambdas("./build/lambdas/Token_lambdas.json") -dev_lambdas = parse_lambdas("./build/lambdas/Dev_lambdas.json") \ No newline at end of file +dev_lambdas = parse_lambdas("./build/lambdas/Dev_lambdas.json") +strat_lambdas = parse_lambdas("./build/lambdas/Strategy_lambdas.json") \ No newline at end of file diff --git a/scenario/test_admin.py b/scenario/test_admin.py index 11b0043..a30ac02 100644 --- a/scenario/test_admin.py +++ b/scenario/test_admin.py @@ -7,7 +7,7 @@ from helpers import * from pytezos import ContractInterface, MichelsonRuntimeError -from initial_storage import admin_lambdas, dex_lambdas, token_lambdas +from initial_storage import admin_lambdas, dex_lambdas, token_lambdas, strat_lambdas class StableSwapTest(TestCase): @@ -23,6 +23,7 @@ def setUpClass(cls): storage = cls.dex.storage.dummy() storage["token_lambdas"] = token_lambdas storage["dex_lambdas"] = dex_lambdas + storage["strat_lambdas"] = strat_lambdas storage["admin_lambdas"] = admin_lambdas storage["storage"]["admin"] = admin diff --git a/scenario/test_divests.py b/scenario/test_divests.py index bff08ce..43361a8 100644 --- a/scenario/test_divests.py +++ b/scenario/test_divests.py @@ -8,7 +8,7 @@ from helpers import * from pytezos import ContractInterface, MichelsonRuntimeError -from initial_storage import admin_lambdas, dex_lambdas, token_lambdas +from initial_storage import admin_lambdas, dex_lambdas, token_lambdas, strat_lambdas class DivestsTest(TestCase): @@ -24,6 +24,7 @@ def setUpClass(cls): storage = cls.dex.storage.dummy() storage["token_lambdas"] = token_lambdas storage["dex_lambdas"] = dex_lambdas + storage["strat_lambdas"] = strat_lambdas storage["admin_lambdas"] = admin_lambdas storage["storage"]["admin"] = admin diff --git a/scenario/test_fees.py b/scenario/test_fees.py index 0abbe65..dc0bfc4 100644 --- a/scenario/test_fees.py +++ b/scenario/test_fees.py @@ -7,7 +7,7 @@ from helpers import * from pytezos import ContractInterface, MichelsonRuntimeError -from initial_storage import admin_lambdas, dex_lambdas, token_lambdas, dev_lambdas +from initial_storage import admin_lambdas, dex_lambdas, token_lambdas, dev_lambdas, strat_lambdas class StableSwapTest(TestCase): @@ -23,6 +23,7 @@ def setUpClass(cls): storage = cls.dex.storage.dummy() storage["token_lambdas"] = token_lambdas storage["dex_lambdas"] = dex_lambdas + storage["strat_lambdas"] = strat_lambdas storage["admin_lambdas"] = admin_lambdas storage["storage"]["admin"] = admin storage["storage"]["dev_store"]["dev_address"] = dev diff --git a/scenario/test_staking.py b/scenario/test_staking.py index 2469fc6..5b90ff5 100644 --- a/scenario/test_staking.py +++ b/scenario/test_staking.py @@ -8,7 +8,7 @@ from helpers import * from pytezos import ContractInterface, MichelsonRuntimeError -from initial_storage import admin_lambdas, dex_lambdas, token_lambdas +from initial_storage import admin_lambdas, dex_lambdas, token_lambdas, strat_lambdas class StableStakingTest(TestCase): @@ -24,6 +24,7 @@ def setUpClass(cls): storage = cls.dex.storage.dummy() storage["token_lambdas"] = token_lambdas storage["dex_lambdas"] = dex_lambdas + storage["strat_lambdas"] = strat_lambdas storage["admin_lambdas"] = admin_lambdas storage["storage"]["admin"] = admin storage["storage"]["quipu_token"] = { diff --git a/scenario/test_swap.py b/scenario/test_swap.py index 73fd49c..dc1963b 100644 --- a/scenario/test_swap.py +++ b/scenario/test_swap.py @@ -7,7 +7,7 @@ from helpers import * from pytezos import ContractInterface, MichelsonRuntimeError -from initial_storage import admin_lambdas, dex_lambdas, token_lambdas +from initial_storage import admin_lambdas, dex_lambdas, token_lambdas, strat_lambdas class StableSwapTest(TestCase): @@ -23,6 +23,7 @@ def setUpClass(cls): storage = cls.dex.storage.dummy() storage["token_lambdas"] = token_lambdas storage["dex_lambdas"] = dex_lambdas + storage["strat_lambdas"] = strat_lambdas storage["admin_lambdas"] = admin_lambdas storage["storage"]["admin"] = admin diff --git a/scenario/test_token_to_token_transfer.py b/scenario/test_token_to_token_transfer.py index c398b2c..67bf744 100644 --- a/scenario/test_token_to_token_transfer.py +++ b/scenario/test_token_to_token_transfer.py @@ -8,7 +8,7 @@ from pytezos import ContractInterface, pytezos, MichelsonRuntimeError from pytezos.context.mixin import ExecutionContext -from initial_storage import admin_lambdas, dex_lambdas, token_lambdas +from initial_storage import admin_lambdas, dex_lambdas, token_lambdas, strat_lambdas pair = { "token_a_type" : { @@ -39,6 +39,7 @@ def setUpClass(cls): storage = cls.dex.storage.dummy() storage["token_lambdas"] = token_lambdas storage["dex_lambdas"] = dex_lambdas + storage["strat_lambdas"] = strat_lambdas storage["admin_lambdas"] = admin_lambdas storage["storage"]["admin"] = admin cls.init_storage = storage diff --git a/scripts/commands/compile/utils.ts b/scripts/commands/compile/utils.ts index 9112d0c..2365c6e 100644 --- a/scripts/commands/compile/utils.ts +++ b/scripts/commands/compile/utils.ts @@ -238,7 +238,7 @@ export const compileLambdas = async ( { int: lambda.index.toString() }, ], } - : JSON.parse(michelson).args[0].args[0].args[0]; + : JSON.parse(michelson).args[0].args[0].args[0].args[0]; res.push(bytes); console.log( diff --git a/scripts/commands/sandbox/types.ts b/scripts/commands/sandbox/types.ts index 3acb369..bb420df 100644 --- a/scripts/commands/sandbox/types.ts +++ b/scripts/commands/sandbox/types.ts @@ -28,6 +28,7 @@ export enum TezosProtocols { HANGZHOU = "hangzhou", ITHACA = "ithaca", JACARTA = "jacarta", + KATHMANDU = "kathmandu", } export declare type FlextesaTezosProtocols = { diff --git a/scripts/commands/sandbox/utils.ts b/scripts/commands/sandbox/utils.ts index 995eed9..c206ecc 100644 --- a/scripts/commands/sandbox/utils.ts +++ b/scripts/commands/sandbox/utils.ts @@ -49,6 +49,11 @@ export const flextesaProtocols: FlextesaTezosProtocols = { prefix: "013-PtJakart", kind: "Jacarta", }, + [TezosProtocols.KATHMANDU]: { + hash: "PtKathmankSpLLDALzWw7CGD2j2MtyveTwboEYokqUCP4a1LxMg", + prefix: "014-PtKathma", + kind: "Kathmandu", + }, }; export async function useSandbox(options: { up?: boolean; down?: boolean }) { @@ -125,7 +130,7 @@ const FLEXTESA_IMAGE = "oxheadalpha/flextesa:latest"; // Name for the running Docker image export const POD_NAME = "flextesa-sandbox"; -const defaultProtocol = TezosProtocols.ITHACA; +const defaultProtocol = TezosProtocols.KATHMANDU; const defaultOptions: FlextesaOptions = config.networks.sandbox; export const startFlextesa = async ( diff --git a/storage/dex.ts b/storage/dex.ts index ce42d70..aee2850 100644 --- a/storage/dex.ts +++ b/storage/dex.ts @@ -58,6 +58,7 @@ const storage: DexStorage = { admin_lambdas: new MichelsonMap(), dex_lambdas: new MichelsonMap(), token_lambdas: new MichelsonMap(), + strat_lambdas: new MichelsonMap(), }; export default storage; diff --git a/storage/factory.ts b/storage/factory.ts index c216526..38960c1 100644 --- a/storage/factory.ts +++ b/storage/factory.ts @@ -51,6 +51,7 @@ const factoryDefaultStorage: FactoryStorage = { admin_lambdas: new MichelsonMap(), dex_lambdas: new MichelsonMap(), token_lambdas: new MichelsonMap(), + strat_lambdas: new MichelsonMap(), metadata: metadata, }; diff --git a/test/Dex/API/dexAPI.ts b/test/Dex/API/dexAPI.ts index e563fa0..a51b71a 100644 --- a/test/Dex/API/dexAPI.ts +++ b/test/Dex/API/dexAPI.ts @@ -20,6 +20,7 @@ import { dexLambdas, tokenLambdas } from "../../storage/Functions"; import admin_lambdas_comp from "../../../build/lambdas/test/Admin_lambdas.json"; import dex_lambdas_comp from "../../../build/lambdas/test/Dex_lambdas.json"; import dev_lambdas_comp from "../../../build/lambdas/test/Dev_lambdas.json"; +import strat_lambdas_comp from "../../../build/lambdas/test/Strategy_lambdas.json"; import token_lambdas_comp from "../../../build/lambdas/test/Token_lambdas.json"; import { defaultTokenId, TokenFA12, TokenFA2 } from "../../Token"; import { DevEnabledContract } from "../../Developer/API/devAPI"; @@ -65,6 +66,13 @@ export class Dex extends TokenFA2 implements DevEnabledContract { 8, dex_lambdas_comp ); + await setFunctionBatchCompilled( + tezos, + dexAddress, + "Strategy", + 5, + strat_lambdas_comp + ); } return dex; } @@ -81,7 +89,13 @@ export class Dex extends TokenFA2 implements DevEnabledContract { ): Promise { this.storage = (await this.contract.storage()) as DexStorage; for (const key in maps) { - if (["dex_lambdas", "token_lambdas", "admin_lambdas"].includes(key)) + if ([ + "dex_lambdas", + "token_lambdas", + "admin_lambdas", + "strat_lambdas", + ].includes(key) + ) continue; this.storage.storage[key] = await maps[key].reduce( async (prev, current) => { @@ -102,7 +116,14 @@ export class Dex extends TokenFA2 implements DevEnabledContract { ); } for (const key in maps) { - if (!["dex_lambdas", "token_lambdas", "admin_lambdas"].includes(key)) + if ( + ![ + "dex_lambdas", + "token_lambdas", + "admin_lambdas", + "strat_lambdas", + ].includes(key) + ) continue; this.storage[key] = await maps[key].reduce(async (prev, current) => { try { diff --git a/test/Dex/API/storage.ts b/test/Dex/API/storage.ts index 8e2195b..6948652 100644 --- a/test/Dex/API/storage.ts +++ b/test/Dex/API/storage.ts @@ -31,5 +31,6 @@ const dex_storage: DexStorage = { admin_lambdas: new MichelsonMap(), dex_lambdas: new MichelsonMap(), token_lambdas: new MichelsonMap(), + strat_lambdas: new MichelsonMap(), }; export default dex_storage; diff --git a/test/Dex/API/types.ts b/test/Dex/API/types.ts index 68f1907..6c6b756 100644 --- a/test/Dex/API/types.ts +++ b/test/Dex/API/types.ts @@ -24,6 +24,19 @@ export declare type TokenInfo = { reserves: BigNumber; }; +export declare type TokenStrategyConfiguration = { + des_reserves_rate_f: BigNumber; + delta_rate_f: BigNumber; + min_invest: BigNumber; + strategy_reserves: BigNumber; + is_rebalance: boolean; +}; + +export declare type StrategyStoreType = { + strat_contract?: TezosAddress; + configuration: MichelsonMap; +}; + export declare type PairInfo = { initial_A_f: BigNumber; initial_A_time: Date; @@ -32,6 +45,7 @@ export declare type PairInfo = { tokens_info: MichelsonMap; fee: FeeType; + strategy: StrategyStoreType; staker_accumulator: { accumulator_f: MichelsonMap; total_staked: BigNumber; @@ -79,6 +93,7 @@ export declare type DexStorage = { admin_lambdas: MichelsonMap; dex_lambdas: MichelsonMap; token_lambdas: MichelsonMap; + strat_lambdas: MichelsonMap; }; export declare type RewardsType = { diff --git a/test/Dex/cases/before.ts b/test/Dex/cases/before.ts index 811779f..f152c1b 100644 --- a/test/Dex/cases/before.ts +++ b/test/Dex/cases/before.ts @@ -10,6 +10,7 @@ import dev_lambdas_comp from "../../../build/lambdas/test/Dev_lambdas.json"; import dex_lambdas_comp from "../../../build/lambdas/test/Dex_lambdas.json"; import token_lambdas_comp from "../../../build/lambdas/test/Token_lambdas.json"; import admin_lambdas_comp from "../../../build/lambdas/test/Admin_lambdas.json"; +import strat_lambdas_comp from "../../../build/lambdas/test/Strategy_lambdas.json"; import { accounts } from "../../../utils/constants"; import { DexAPI as Dex, defaultDexStorage as storage } from "../API"; diff --git a/test/Factory/API/factoryAPI.ts b/test/Factory/API/factoryAPI.ts index 0d76f84..f2ed8db 100644 --- a/test/Factory/API/factoryAPI.ts +++ b/test/Factory/API/factoryAPI.ts @@ -16,6 +16,7 @@ import { FactoryStorage } from "./types"; import admin_lambdas_comp from "../../../build/lambdas/factory/Admin_lambdas.json"; import dex_lambdas_comp from "../../../build/lambdas/factory/Dex_lambdas.json"; import token_lambdas_comp from "../../../build/lambdas/factory/Token_lambdas.json"; +import strat_lambdas_comp from "../../../build/lambdas/test/Strategy_lambdas.json"; import { confirmOperation } from "../../../utils/confirmation"; import BigNumber from "bignumber.js"; import { defaultTokenId, TokenFA12, TokenFA2 } from "../../Token"; @@ -70,6 +71,13 @@ export class DexFactory implements DevEnabledContract { 8, dex_lambdas_comp ); + await setFunctionBatchCompilled( + tezos, + factoryAddress, + "Strategy", + 5, + strat_lambdas_comp + ); await factory.updateStorage(); return factory; } @@ -87,6 +95,7 @@ export class DexFactory implements DevEnabledContract { // "dev_lambdas", "token_lambdas", "admin_lambdas", + "strat_lambdas" ].includes(key) ) continue; @@ -114,6 +123,7 @@ export class DexFactory implements DevEnabledContract { // "dev_lambdas", "token_lambdas", "admin_lambdas", + "strat_lambdas" ].includes(key) ) continue; diff --git a/test/Factory/API/storage.ts b/test/Factory/API/storage.ts index 2d9dd2e..b4cd80d 100644 --- a/test/Factory/API/storage.ts +++ b/test/Factory/API/storage.ts @@ -24,6 +24,7 @@ export const factory_storage: FactoryStorage = { admin_lambdas: new MichelsonMap(), dex_lambdas: new MichelsonMap(), token_lambdas: new MichelsonMap(), + strat_lambdas: new MichelsonMap(), metadata: new MichelsonMap(), }; diff --git a/test/Factory/API/types.ts b/test/Factory/API/types.ts index ac2533c..492a77d 100644 --- a/test/Factory/API/types.ts +++ b/test/Factory/API/types.ts @@ -21,6 +21,7 @@ export declare type FactoryStorage = { admin_lambdas: MichelsonMap; dex_lambdas: MichelsonMap; token_lambdas: MichelsonMap; + strat_lambdas: MichelsonMap; init_func?: BytesString; metadata: MichelsonMap; }; diff --git a/test/Factory/cases/before.ts b/test/Factory/cases/before.ts index e31c54b..ad32260 100644 --- a/test/Factory/cases/before.ts +++ b/test/Factory/cases/before.ts @@ -10,6 +10,7 @@ import dev_lambdas_comp from "../../../build/lambdas/test/Dev_lambdas.json"; import dex_lambdas_comp from "../../../build/lambdas/test/Dex_lambdas.json"; import token_lambdas_comp from "../../../build/lambdas/test/Token_lambdas.json"; import admin_lambdas_comp from "../../../build/lambdas/test/Admin_lambdas.json"; +import strat_lambdas_comp from "../../../build/lambdas/test/Strategy_lambdas.json"; import { defaultTokenId, TokenFA2 } from "../../Token"; import { setupQuipuGovToken } from "../../utils/tokensSetups"; import { accounts, dev_fee } from "../../../utils/constants"; diff --git a/test/lambdas/Strategy_lambdas.json b/test/lambdas/Strategy_lambdas.json index 4db47d4..24f5951 100644 --- a/test/lambdas/Strategy_lambdas.json +++ b/test/lambdas/Strategy_lambdas.json @@ -9,6 +9,6 @@ }, { "index": 2, - "name": "set_updatable" + "name": "set_rebalance" } ] diff --git a/utils/helpers.ts b/utils/helpers.ts index 7137993..c4f006b 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -163,7 +163,7 @@ export async function setupLambdasToStorage( export async function setFunctionBatchCompilled( tezos: TezosToolkit, contract: TezosAddress, - type: "Dex" | "Token" | "Admin" | "Dev", + type: "Dex" | "Token" | "Admin" | "Dev" | "Strategy", batchBy: number, comp_funcs_map ) { @@ -197,7 +197,7 @@ export async function setFunctionBatchCompilled( export async function setFunctionCompilled( tezos: TezosToolkit, contract: TezosAddress, - type: "Dex" | "Token" | "Admin" | "Dev", + type: "Dex" | "Token" | "Admin" | "Dev" | "Strategy", comp_funcs_map ) { let idx = 0; From a26170a13788619bc55b8ac63c819763705b9187 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 27 Oct 2022 20:36:14 +0300 Subject: [PATCH 07/67] update workflow --- .github/workflows/main.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d736ba4..56ca657 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -15,17 +15,15 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup dependencies - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: - node-version: "14" + node-version: "18" cache: 'yarn' cache-dependency-path: './yarn.lock' - - name: Install Git - run: sudo apt install git -y - name: Install modules - run: yarn install + run: yarn install --immutable --immutable-cache --check-cache - name: Compile contracts for tests run: yarn compile-for-test - name: Start sandbox and wait for initialization @@ -39,21 +37,23 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup Node - uses: actions/setup-node@v2 + uses: actions/setup-node@v3 with: - node-version: "14" + node-version: "18" cache: 'yarn' cache-dependency-path: './yarn.lock' - name: Set up Python - run: sudo apt install python pip + uses: actions/setup-python@v4 + with: + python-version: '3.9' - name: Install crypto libs run: sudo apt install libsodium-dev libsecp256k1-dev libgmp-dev - name: Install pytezos and pytest run: pip install pytezos pytest - name: Install node modules - run: yarn install + run: yarn install --immutable --immutable-cache --check-cache - name: Compile contracts run: yarn compile - name: Run scenario tests From 7c2181601a93711ee4bb5d6a64ce0e8e63ae782a Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 27 Oct 2022 21:04:54 +0300 Subject: [PATCH 08/67] upd workflow strange issues with flextesa --- .github/workflows/main.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 56ca657..9cd2b0f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,14 +24,8 @@ jobs: cache-dependency-path: './yarn.lock' - name: Install modules run: yarn install --immutable --immutable-cache --check-cache - - name: Compile contracts for tests - run: yarn compile-for-test - - name: Start sandbox and wait for initialization - run: yarn start-sandbox && sleep 10s - - name: Test the contracts - run: yarn test - - name: Stop sandbox - run: yarn stop-sandbox + - name: Compile contracts and test + run: yarn compile-n-test pytest: name: Pytest tests runs-on: ubuntu-latest From 78f9da121abdb9e52d18002ee6e5cf952d73636f Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 27 Oct 2022 21:11:19 +0300 Subject: [PATCH 09/67] longer wait --- .github/workflows/main.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9cd2b0f..8fbe890 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,7 +25,13 @@ jobs: - name: Install modules run: yarn install --immutable --immutable-cache --check-cache - name: Compile contracts and test - run: yarn compile-n-test + run: yarn compile-for-test + - name: Start sandbox and wait for initialization + run: yarn start-sandbox && sleep 20s + - name: Test the contracts + run: yarn test + - name: Stop sandbox + run: yarn stop-sandbox pytest: name: Pytest tests runs-on: ubuntu-latest From 3a3c06ca711502ab03070aa930affde71f2c7be9 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 10:49:44 +0300 Subject: [PATCH 10/67] wait for sandbox up with action --- .github/workflows/main.yml | 6 +++++- config.ts | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8fbe890..0aab060 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,7 +27,11 @@ jobs: - name: Compile contracts and test run: yarn compile-for-test - name: Start sandbox and wait for initialization - run: yarn start-sandbox && sleep 20s + run: yarn start-sandbox + - name: Wait For Endpoint + uses: emilioschepis/wait-for-endpoint@v1.0.3 + with: + url: http://localhost:2000/chains/main/blocks/head - name: Test the contracts run: yarn test - name: Stop sandbox diff --git a/config.ts b/config.ts index 16e9535..b7c7190 100644 --- a/config.ts +++ b/config.ts @@ -33,7 +33,7 @@ export const config = { }, }, testnet: { - host: "https://ghostnet.testnets.xyz", + host: "https://rpc.ghostnet.testnets.xyz", port: 443, faucet: null, }, From bc4b1b82a3f83afcb9a2287fbf4cefe274b76726 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 11:07:29 +0300 Subject: [PATCH 11/67] Update flextesa versions --- .github/workflows/main.yml | 4 ++-- scripts/commands/sandbox/utils.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 0aab060..3a688fd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,9 +26,9 @@ jobs: run: yarn install --immutable --immutable-cache --check-cache - name: Compile contracts and test run: yarn compile-for-test - - name: Start sandbox and wait for initialization + - name: Start sandbox run: yarn start-sandbox - - name: Wait For Endpoint + - name: Wait for Sandbox endpoint uses: emilioschepis/wait-for-endpoint@v1.0.3 with: url: http://localhost:2000/chains/main/blocks/head diff --git a/scripts/commands/sandbox/utils.ts b/scripts/commands/sandbox/utils.ts index c206ecc..7912ab3 100644 --- a/scripts/commands/sandbox/utils.ts +++ b/scripts/commands/sandbox/utils.ts @@ -125,7 +125,7 @@ export const createProtocolParams = ( }; // Flextesa image -const FLEXTESA_IMAGE = "oxheadalpha/flextesa:latest"; +const FLEXTESA_IMAGE = "oxheadalpha/flextesa:20221026"; // Name for the running Docker image export const POD_NAME = "flextesa-sandbox"; From 7b896c40f9205e06e6d8b70c8b24e41fdc8037cf Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 11:13:59 +0300 Subject: [PATCH 12/67] Upd host --- .github/workflows/main.yml | 2 +- config.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3a688fd..302bf7c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -31,7 +31,7 @@ jobs: - name: Wait for Sandbox endpoint uses: emilioschepis/wait-for-endpoint@v1.0.3 with: - url: http://localhost:2000/chains/main/blocks/head + url: http://0.0.0.0:2000/chains/main/blocks/head - name: Test the contracts run: yarn test - name: Stop sandbox diff --git a/config.ts b/config.ts index b7c7190..62b9539 100644 --- a/config.ts +++ b/config.ts @@ -9,7 +9,7 @@ export const config = { preferredLigoFlavor: "pascaligo", networks: { sandbox: { - host: "http://localhost", + host: "http://0.0.0.0", port: 20000, protocol: TezosProtocols.KATHMANDU, genesisBlockHash: "random", From e5bd5530f260c3b0ab68604edfe5fb76efd84897 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 11:23:33 +0300 Subject: [PATCH 13/67] hosts --- config.ts | 2 +- scripts/commands/sandbox/utils.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/config.ts b/config.ts index 62b9539..6d6b1a2 100644 --- a/config.ts +++ b/config.ts @@ -9,7 +9,7 @@ export const config = { preferredLigoFlavor: "pascaligo", networks: { sandbox: { - host: "http://0.0.0.0", + host: "http://127.0.0.1", port: 20000, protocol: TezosProtocols.KATHMANDU, genesisBlockHash: "random", diff --git a/scripts/commands/sandbox/utils.ts b/scripts/commands/sandbox/utils.ts index 7912ab3..c7ed368 100644 --- a/scripts/commands/sandbox/utils.ts +++ b/scripts/commands/sandbox/utils.ts @@ -143,7 +143,10 @@ export const startFlextesa = async ( const options = Object.assign({}, defaultOptions, _options); // Localhost is not a valid host for Docker - const host = options.host.includes("localhost") ? "0.0.0.0" : options.host; + const host = + options.host.includes("localhost") || options.host == "127.0.0.1" + ? "0.0.0.0" + : options.host; const port = options.port; // Protocol "validity" checks From 2e443e9f28819a67c2b8c1349cadd067d46cc355 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 11:32:44 +0300 Subject: [PATCH 14/67] add cache for contracts changes to build --- .github/workflows/main.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 302bf7c..b0163ab 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -24,14 +24,22 @@ jobs: cache-dependency-path: './yarn.lock' - name: Install modules run: yarn install --immutable --immutable-cache --check-cache + - uses: actions/cache@v3 + id: contracts-build-jest-cache + with: + path: | + build + contracts/compiled + key: ${{ runner.os }}-${{ hashFiles('contracts/**/*.ligo') }} - name: Compile contracts and test + if: steps.contracts-build-jest-cache.outputs.cache-hit != 'true' run: yarn compile-for-test - name: Start sandbox run: yarn start-sandbox - name: Wait for Sandbox endpoint uses: emilioschepis/wait-for-endpoint@v1.0.3 with: - url: http://0.0.0.0:2000/chains/main/blocks/head + url: http://localhost:2000/chains/main/blocks/head - name: Test the contracts run: yarn test - name: Stop sandbox @@ -58,7 +66,15 @@ jobs: run: pip install pytezos pytest - name: Install node modules run: yarn install --immutable --immutable-cache --check-cache + - uses: actions/cache@v3 + id: contracts-build-cache + with: + path: | + build + contracts/compiled + key: ${{ runner.os }}-${{ hashFiles('contracts/**/*.ligo') }} - name: Compile contracts + if: steps.contracts-build-cache.outputs.cache-hit != 'true' run: yarn compile - name: Run scenario tests run: pytest -s -v From 966d5f6dd8036a736ebb4871274ceaeaf4ae95ae Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 11:42:09 +0300 Subject: [PATCH 15/67] Update utils --- scripts/commands/sandbox/utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/commands/sandbox/utils.ts b/scripts/commands/sandbox/utils.ts index c7ed368..e2f301e 100644 --- a/scripts/commands/sandbox/utils.ts +++ b/scripts/commands/sandbox/utils.ts @@ -144,10 +144,10 @@ export const startFlextesa = async ( // Localhost is not a valid host for Docker const host = - options.host.includes("localhost") || options.host == "127.0.0.1" + options.host.includes("localhost") || options.host.includes("127.0.0.1") ? "0.0.0.0" : options.host; - const port = options.port; + const port = options.port || "20000"; // Protocol "validity" checks const protocol = @@ -165,7 +165,7 @@ export const startFlextesa = async ( "--name", POD_NAME, "-p", - host + ":" + port + ":20000", + host + ":" + port, "--env", "flextesa_node_cors_origin=*", FLEXTESA_IMAGE, From 43cc2430fc306380bb15942dbae1c3fce5306885 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 11:45:22 +0300 Subject: [PATCH 16/67] Port utils --- scripts/commands/sandbox/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/commands/sandbox/utils.ts b/scripts/commands/sandbox/utils.ts index e2f301e..a6466b0 100644 --- a/scripts/commands/sandbox/utils.ts +++ b/scripts/commands/sandbox/utils.ts @@ -165,7 +165,7 @@ export const startFlextesa = async ( "--name", POD_NAME, "-p", - host + ":" + port, + port + ":20000", "--env", "flextesa_node_cors_origin=*", FLEXTESA_IMAGE, From e745066e62e881a7ba4974bce2bc09c24bb1e73d Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 11:47:21 +0300 Subject: [PATCH 17/67] Workflow --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b0163ab..9cd5198 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,7 +39,7 @@ jobs: - name: Wait for Sandbox endpoint uses: emilioschepis/wait-for-endpoint@v1.0.3 with: - url: http://localhost:2000/chains/main/blocks/head + url: http://localhost:20000/chains/main/blocks/head - name: Test the contracts run: yarn test - name: Stop sandbox From e4dadc2e78609c5c05806e2aed7bcd2907bd4d94 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 11:55:09 +0300 Subject: [PATCH 18/67] Update workflow --- .github/workflows/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9cd5198..7e3612f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -30,7 +30,7 @@ jobs: path: | build contracts/compiled - key: ${{ runner.os }}-${{ hashFiles('contracts/**/*.ligo') }} + key: ${{ runner.os }}-jest-${{ hashFiles('contracts/**/*.ligo') }} - name: Compile contracts and test if: steps.contracts-build-jest-cache.outputs.cache-hit != 'true' run: yarn compile-for-test @@ -67,14 +67,14 @@ jobs: - name: Install node modules run: yarn install --immutable --immutable-cache --check-cache - uses: actions/cache@v3 - id: contracts-build-cache + id: contracts-build-pytest-cache with: path: | build contracts/compiled - key: ${{ runner.os }}-${{ hashFiles('contracts/**/*.ligo') }} + key: ${{ runner.os }}-py-${{ hashFiles('contracts/**/*.ligo') }} - name: Compile contracts - if: steps.contracts-build-cache.outputs.cache-hit != 'true' + if: steps.contracts-build-pytest-cache.outputs.cache-hit != 'true' run: yarn compile - name: Run scenario tests run: pytest -s -v From 6c64c29c2a548e3607d0e497ac04eaea8dffe0a4 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 11:58:33 +0300 Subject: [PATCH 19/67] update caching contracts --- .github/workflows/main.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7e3612f..b6bfaf2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,14 +25,14 @@ jobs: - name: Install modules run: yarn install --immutable --immutable-cache --check-cache - uses: actions/cache@v3 - id: contracts-build-jest-cache + id: contracts-build with: path: | build contracts/compiled - key: ${{ runner.os }}-jest-${{ hashFiles('contracts/**/*.ligo') }} + key: compiled-test-contracts-${{ runner.os }}-jest-${{ hashFiles('contracts/**/*.ligo') }} - name: Compile contracts and test - if: steps.contracts-build-jest-cache.outputs.cache-hit != 'true' + if: steps.contracts-build.outputs.cache-hit != 'true' run: yarn compile-for-test - name: Start sandbox run: yarn start-sandbox @@ -67,14 +67,14 @@ jobs: - name: Install node modules run: yarn install --immutable --immutable-cache --check-cache - uses: actions/cache@v3 - id: contracts-build-pytest-cache + id: contracts-build with: path: | build contracts/compiled - key: ${{ runner.os }}-py-${{ hashFiles('contracts/**/*.ligo') }} + key: compiled-contracts-${{ runner.os }}-${{ hashFiles('contracts/**/*.ligo') }} - name: Compile contracts - if: steps.contracts-build-pytest-cache.outputs.cache-hit != 'true' + if: steps.contracts-build.outputs.cache-hit != 'true' run: yarn compile - name: Run scenario tests run: pytest -s -v From 7be236c9a6e3dc95534109802aebaaa6cde5a040 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 14:53:20 +0300 Subject: [PATCH 20/67] Update python tests --- contracts/partials/constants.ligo | 2 +- contracts/partials/strategy/lambdas.ligo | 86 ++++++++----- contracts/partials/strategy/methods.ligo | 6 +- contracts/partials/strategy/types.ligo | 25 +++- scenario/constants.py | 1 + scenario/test_strategy.py | 149 +++++++++++++++++++++++ test/lambdas/Strategy_lambdas.json | 10 +- 7 files changed, 241 insertions(+), 38 deletions(-) create mode 100644 scenario/test_strategy.py diff --git a/contracts/partials/constants.ligo b/contracts/partials/constants.ligo index a95b4dc..80cde6d 100644 --- a/contracts/partials/constants.ligo +++ b/contracts/partials/constants.ligo @@ -4,7 +4,7 @@ const dex_func_count : nat = 7n; const dev_func_count : nat = 2n; const token_func_count : nat = 5n; -const strat_func_count : nat = 3n; +const strat_func_count : nat = 5n; #if !FACTORY const admin_func_count : nat = 8n; #else diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo index b044baa..7bf78c6 100644 --- a/contracts/partials/strategy/lambdas.ligo +++ b/contracts/partials/strategy/lambdas.ligo @@ -1,3 +1,11 @@ +const default_strategy_configuration = record [ + des_reserves_rate_f = 0n; + delta_rate_f = 0n; + min_invest = 0n; + strategy_reserves = 0n; + is_rebalance = True; +] + function connect_strategy( const p : strategy_action_t; var s : storage_t) @@ -10,66 +18,70 @@ function connect_strategy( function claim_reserves( const token_id: token_pool_idx_t; const config : strategy_storage_t) - : unit is + : strategy_storage_t is block { if config.strategy_reserves > 0n then skip// TODO: claim tokens back - } with unit; - Map.iter(claim_reserves, pool.strategy.configuration); + } with config with record[strategy_reserves=0n]; + pool.strategy.configuration := Map.map(claim_reserves, pool.strategy.configuration); pool.strategy.strat_contract := params.strategy_contract; - pool.strategy.configuration := (map[]: map(token_pool_idx_t, strategy_storage_t)); s.pools[params.pool_id] := pool; } | _ -> unreachable(Unit) ] } with (operations, s) -function update_token_to_strategy_params( +function connect_token_to_strategy( const p : strategy_action_t; - var s : storage_t) + const s : storage_t) : return_t is block { var operations: list(operation) := Constants.no_operations; + case p of [ + | Connect_token_strategy(params) -> { + const token = get_token_by_id( + params.pool_token_id, + s.tokens[params.pool_id] + ); + const connect_token_params: strat_upd_info_t = record[ + token = token; + pool_token_id = params.pool_id; + lending_market_id = params.lending_market_id + ]; + // TODO: send connection to strategy + } + | _ -> unreachable(Unit) + ] + } with (operations, s) + +function update_token_strategy_params( + const p : strategy_action_t; + var s : storage_t) + : return_t is + block { case p of [ | Set_token_strategy(params) -> { var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); - var strat_config := pool.strategy.configuration; require(params.des_reserves_rate_f + params.delta_rate_f < Constants.precision, Errors.Math.percent_overflow); - strat_config[params.pool_token_id] := case Map.find_opt(params.pool_token_id, strat_config) of [ - Some(data) -> { - (* WARNING: lending_market_id is ignored in this case - because pool_token_id already added to Strategy *) - // TODO: call update stategy with new desired params? - const _ = 0n; - } with data with record [ - des_reserves_rate_f = params.des_reserves_rate_f; - delta_rate_f = params.delta_rate_f; - min_invest = params.min_invest; - ] - | None -> { - // TODO: update lending_market_id on strategy call - const _ = 0n; - } with record[ - des_reserves_rate_f = params.des_reserves_rate_f; - delta_rate_f = params.delta_rate_f; - min_invest = params.min_invest; - strategy_reserves = 0n; - is_rebalance = True; - ] + pool.strategy.configuration[params.pool_token_id] := unwrap_or( + pool.strategy.configuration[params.pool_token_id], + default_strategy_configuration + ) with record [ + des_reserves_rate_f = params.des_reserves_rate_f; + delta_rate_f = params.delta_rate_f; + min_invest = params.min_invest; ]; - pool.strategy.configuration := strat_config; s.pools[params.pool_id] := pool; } | _ -> unreachable(Unit) ] - } with (operations, s) + } with (Constants.no_operations, s) function set_rebalance( const p : strategy_action_t; var s : storage_t) : return_t is block { - var operations: list(operation) := Constants.no_operations; case p of [ | Set_token_strategy_rebalance(params) -> { var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); @@ -83,4 +95,16 @@ function set_rebalance( } | _ -> unreachable(Unit) ] + } with (Constants.no_operations, s) + + function strategy_rebalance( + const p : strategy_action_t; + var s : storage_t) + : return_t is + block { + var operations: list(operation) := Constants.no_operations; + case p of [ + | Rebalance(params) -> skip + | _ -> unreachable(Unit) + ] } with (operations, s) \ No newline at end of file diff --git a/contracts/partials/strategy/methods.ligo b/contracts/partials/strategy/methods.ligo index 319305d..2622f7a 100644 --- a/contracts/partials/strategy/methods.ligo +++ b/contracts/partials/strategy/methods.ligo @@ -8,8 +8,10 @@ require(Tezos.sender = dev_address, Errors.Dex.not_developer); const idx : nat = case p of [ | Connect_strategy(_) -> 0n - | Set_token_strategy(_) -> 1n - | Set_token_strategy_rebalance(_) -> 2n + | Connect_token_strategy(_) -> 1n + | Set_token_strategy(_) -> 2n + | Set_token_strategy_rebalance(_) -> 3n + | Rebalance(_) -> 4n ]; const lambda_bytes : bytes = unwrap(s.strat_lambdas[idx], Errors.Dex.unknown_func); diff --git a/contracts/partials/strategy/types.ligo b/contracts/partials/strategy/types.ligo index 98c7865..8fee960 100644 --- a/contracts/partials/strategy/types.ligo +++ b/contracts/partials/strategy/types.ligo @@ -17,9 +17,14 @@ type conn_strategy_param is [@layout:comb] record [ ] type conn_tok_strat_param is [@layout:comb] record [ + pool_id : pool_id_t; + pool_token_id : token_pool_idx_t; + lending_market_id : nat; +]; + +type set_tok_strat_param is [@layout:comb] record [ pool_id : pool_id_t; pool_token_id : token_pool_idx_t; - lending_market_id : nat; des_reserves_rate_f : nat; delta_rate_f : nat; min_invest : nat; @@ -36,7 +41,21 @@ type upd_strat_state_t is [@layout:comb] record [ new_balance : nat; ] +type rebalance_param is [@layout:comb] record [ + pool_id : pool_id_t; + pool_token_id : nat; +] + +type strat_upd_info_t is [@layout:comb] record [ + token : token_t; + pool_token_id : token_pool_idx_t; + lending_market_id : nat; +] + + type strategy_action_t is | Connect_strategy of conn_strategy_param -| Set_token_strategy of conn_tok_strat_param -| Set_token_strategy_rebalance of tok_strat_upd_fl_param \ No newline at end of file +| Connect_token_strategy of conn_tok_strat_param +| Set_token_strategy of set_tok_strat_param +| Set_token_strategy_rebalance of tok_strat_upd_fl_param +| Rebalance of rebalance_param \ No newline at end of file diff --git a/scenario/constants.py b/scenario/constants.py index d2b7df7..3d677b5 100644 --- a/scenario/constants.py +++ b/scenario/constants.py @@ -24,6 +24,7 @@ factory = "KT1LzyPS8rN375tC31WPAVHaQ4HyBvTSLwBu" quipu_token = "KT1LzyPS8rN375tC31WPAVHaQ4HyBvTSLwBu" price_feed = "KT1Qf46j2x37sAN4t2MKRQRVt9gc4FZ5duMs" +strategy_address = "KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5" fee_collector = "tz1MDhGTfMQjtMYFXeasKzRWzkQKPtXEkSEw" dummy_sig = "sigY3oZknG7z2N9bj5aWVtdZBakTviKnwbSYTecbbT2gwQDrnLRNhP5KDcLroggq71AjXWkx27nSLfS8rodS4DYn14FyueS5" diff --git a/scenario/test_strategy.py b/scenario/test_strategy.py new file mode 100644 index 0000000..1da8f55 --- /dev/null +++ b/scenario/test_strategy.py @@ -0,0 +1,149 @@ + +from unittest import TestCase +import pytest +import json +from pprint import pprint +from constants import * +from decimal import Decimal + +from helpers import * + +from pytezos import ContractInterface, MichelsonRuntimeError +from initial_storage import admin_lambdas, dex_lambdas, token_lambdas, strat_lambdas, dev_lambdas + +class DexStrategyTest(TestCase): + + @classmethod + def setUpClass(cls): + cls.maxDiff = None + + text = open("./build/dex.json").read() + code = json.loads(text) + + cls.dex = ContractInterface.from_micheline(code["michelson"]) + + storage = cls.dex.storage.dummy() + storage["token_lambdas"] = token_lambdas + storage["dex_lambdas"] = dex_lambdas + storage["strat_lambdas"] = strat_lambdas + storage["admin_lambdas"] = admin_lambdas + storage["storage"]["admin"] = admin + storage["storage"]["dev_store"]["dev_address"] = dev + storage["storage"]["dev_store"]["dev_lambdas"] = dev_lambdas + storage["storage"]["quipu_token"] = { + "token_address" : quipu_token, + "token_id": 0, + } + + cls.init_storage = storage + + def test_connect_strategy(self): + chain = LocalChain(storage=self.init_storage) + + add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) + chain.execute(add_pool, sender=admin) + + # connect new strategy address + connect = self.dex.connect_strategy(0, strategy_address) + res = chain.execute(connect, sender=dev) + + conneced_strategy = res.storage['storage']['pools'][0]['strategy']['strat_contract'] + self.assertEqual(conneced_strategy, strategy_address) + + # disconect strategy + connect = self.dex.connect_strategy(0, None) + res = chain.execute(connect, sender=dev) + conneced_strategy = res.storage['storage']['pools'][0]['strategy']['strat_contract'] + self.assertIsNone(conneced_strategy) + + def test_set_token_params(self): + chain = LocalChain(storage=self.init_storage) + + add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) + chain.execute(add_pool, sender=admin) + + pool_id = 0 + rates = { + 0: { + "des_reserves_rate_f": Decimal("0.3") * Decimal("1e18"), + "delta_rate_f": Decimal("0.05") * Decimal("1e18"), + "min_invest": 30000 + }, + 1: { + "des_reserves_rate_f": Decimal("0.2") * Decimal("1e18"), + "delta_rate_f": Decimal("0.02") * Decimal("1e18"), + "min_invest": 10000 + } + } + + for token_pool_id, config in rates.items(): + set_strat = self.dex.set_token_strategy( + pool_id, + token_pool_id, + int(config['des_reserves_rate_f']), + int(config['delta_rate_f']), + config['min_invest']) + res = chain.execute(set_strat, sender=dev) + conneced_config = res.storage['storage']['pools'][pool_id]['strategy']['configuration'][token_pool_id] + self.assertEqual(conneced_config, + { + "is_rebalance": True, + "strategy_reserves": 0, + **config + }) + + def test_connect_token_to_strategy(self): + pytest.skip("Not implemented yet") + chain = LocalChain(storage=self.init_storage) + + add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) + chain.execute(add_pool, sender=admin) + + def test_set_token_rebalance_flag(self): + chain = LocalChain(storage=self.init_storage) + + add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) + chain.execute(add_pool, sender=admin) + pool_id = 0 + token_pool_id = 0 + config = { + "des_reserves_rate_f": Decimal("0.3") * Decimal("1e18"), + "delta_rate_f": Decimal("0.05") * Decimal("1e18"), + "min_invest": 30000 + } + set_strat = self.dex.set_token_strategy( + pool_id, + token_pool_id, + int(config['des_reserves_rate_f']), + int(config['delta_rate_f']), + config['min_invest']) + res = chain.execute(set_strat, sender=dev) + conneced_config = res.storage['storage']['pools'][pool_id]['strategy']['configuration'][token_pool_id] + self.assertEqual(conneced_config, + { + "is_rebalance": True, + "strategy_reserves": 0, + **config + }) + set_reb = self.dex.set_token_strategy_rebalance( + pool_id, + token_pool_id, + False) + res = chain.execute(set_reb, sender=dev) + conneced_config = res.storage['storage']['pools'][pool_id]['strategy']['configuration'][token_pool_id] + self.assertEqual(conneced_config, + { + "is_rebalance": False, + "strategy_reserves": 0, + **config + }) + + def test_manual_rebalance(self): + pytest.skip("Not implemented yet") + chain = LocalChain(storage=self.init_storage) + + add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) + chain.execute(add_pool, sender=admin) + + connect = self.dex.rebalance(0, 0) + res = chain.execute(connect, sender=dev) \ No newline at end of file diff --git a/test/lambdas/Strategy_lambdas.json b/test/lambdas/Strategy_lambdas.json index 24f5951..1514335 100644 --- a/test/lambdas/Strategy_lambdas.json +++ b/test/lambdas/Strategy_lambdas.json @@ -5,10 +5,18 @@ }, { "index": 1, - "name": "update_token_to_strategy_params" + "name": "connect_token_to_strategy" }, { "index": 2, + "name": "update_token_strategy_params" + }, + { + "index": 3, "name": "set_rebalance" + }, + { + "index": 4, + "name": "strategy_rebalance" } ] From a7fc2d05aa7dd7d9f952e278c86bf1b82efeb69c Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 28 Oct 2022 15:31:54 +0300 Subject: [PATCH 21/67] update compiled dex4factory --- contracts/compiled/dex4factory.tz | 68 ++++++++++++++++++------------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/contracts/compiled/dex4factory.tz b/contracts/compiled/dex4factory.tz index d550919..2526b7c 100644 --- a/contracts/compiled/dex4factory.tz +++ b/contracts/compiled/dex4factory.tz @@ -11,15 +11,19 @@ (pair %set_fees (nat %pool_id) (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)))) (nat %stop_ramp_A)))) (or (or %use_strategy - (or (pair %connect_strategy (nat %pool_id) (option %strategy_contract address)) - (pair %set_token_strategy - (nat %pool_id) - (nat %pool_token_id) - (nat %lending_market_id) - (nat %des_reserves_rate_f) - (nat %delta_rate_f) - (nat %min_invest))) - (pair %set_token_strategy_update_flag + (or (or (pair %connect_strategy (nat %pool_id) (option %strategy_contract address)) + (pair %connect_token_strategy + (nat %pool_id) + (nat %pool_token_id) + (nat %lending_market_id))) + (or (pair %rebalance (nat %pool_id) (nat %pool_token_id)) + (pair %set_token_strategy + (nat %pool_id) + (nat %pool_token_id) + (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest)))) + (pair %set_token_strategy_rebalance (nat %pool_id) (nat %pool_token_id) (bool %flag))) @@ -108,7 +112,7 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_updatable)))) + (bool %is_rebalance)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -292,7 +296,7 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_updatable)))) + (bool %is_rebalance)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -341,7 +345,7 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_updatable)))) + (bool %is_rebalance)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -397,23 +401,29 @@ GET 10 ; DUP 3 ; IF_LEFT - { IF_LEFT { DROP ; PUSH nat 0 } { DROP ; PUSH nat 1 } } - { DROP ; PUSH nat 2 } ; + { IF_LEFT + { IF_LEFT { DROP ; PUSH nat 0 } { DROP ; PUSH nat 1 } } + { IF_LEFT { DROP ; PUSH nat 4 } { DROP ; PUSH nat 2 } } } + { DROP ; PUSH nat 3 } ; GET ; IF_NONE { FAILWITH } { SWAP ; DROP } ; DIG 3 ; SWAP ; UNPACK (lambda - (pair (or (or (pair %connect_strategy (nat %pool_id) (option %strategy_contract address)) - (pair %set_token_strategy - (nat %pool_id) - (nat %pool_token_id) - (nat %lending_market_id) - (nat %des_reserves_rate_f) - (nat %delta_rate_f) - (nat %min_invest))) - (pair %set_token_strategy_update_flag + (pair (or (or (or (pair %connect_strategy (nat %pool_id) (option %strategy_contract address)) + (pair %connect_token_strategy + (nat %pool_id) + (nat %pool_token_id) + (nat %lending_market_id))) + (or (pair %rebalance (nat %pool_id) (nat %pool_token_id)) + (pair %set_token_strategy + (nat %pool_id) + (nat %pool_token_id) + (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest)))) + (pair %set_token_strategy_rebalance (nat %pool_id) (nat %pool_token_id) (bool %flag))) @@ -443,7 +453,7 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_updatable)))) + (bool %is_rebalance)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -492,7 +502,7 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_updatable)))) + (bool %is_rebalance)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -617,7 +627,7 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_updatable)))) + (bool %is_rebalance)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -666,7 +676,7 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_updatable)))) + (bool %is_rebalance)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -759,7 +769,7 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_updatable)))) + (bool %is_rebalance)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -814,7 +824,7 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_updatable)))) + (bool %is_rebalance)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) From 78ac50e397ed5c751babda3fc81b78eb61d315b8 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 31 Oct 2022 20:49:07 +0200 Subject: [PATCH 22/67] Update JS/TS tests --- migrations/02_factory_pools.ts | 10 +- package.json | 4 +- scripts/commands/migrate/utils.ts | 2 +- test/00_Dex.test.ts | 179 +++++++-- test/01_Factory.test.ts | 28 +- test/Dex/API/dexAPI.ts | 343 +++++++++++------- test/Dex/API/types.ts | 2 +- test/Dex/cases/admin.ts | 6 +- test/Dex/cases/admin/fees.ts | 2 +- test/Dex/cases/admin/rampA.ts | 8 +- test/Dex/cases/before.ts | 11 +- test/Dex/cases/index.ts | 2 + test/Dex/cases/pool_part/add.ts | 2 +- test/Dex/cases/pool_part/divest.ts | 15 +- test/Dex/cases/pool_part/invest.ts | 3 +- test/Dex/cases/pool_part/stake.ts | 4 +- test/Dex/cases/pool_part/swap.ts | 14 +- test/Dex/cases/rewards/developer.ts | 52 +-- test/Dex/cases/rewards/referral.ts | 50 +-- test/Dex/cases/rewards/staker.ts | 10 +- .../cofigure-token/configure_strategy.ts | 67 ++++ .../strategy/cofigure-token/connect_token.ts | 0 .../cases/strategy/cofigure-token/index.ts | 4 + .../strategy/cofigure-token/is_rebalance.ts | 29 ++ .../strategy/cofigure-token/rebalance.ts | 0 test/Dex/cases/strategy/connect.ts | 46 +++ test/Dex/cases/strategy/index.ts | 9 + test/Dex/cases/views/pool.ts | 34 +- test/Factory/API/factoryAPI.ts | 18 +- test/Factory/cases/before.ts | 2 +- test/Factory/cases/init_pool.ts | 7 +- test/Factory/cases/rewards.ts | 19 +- test/Token/tokenFA12.ts | 10 +- test/Token/tokenFA2.ts | 8 +- test/utils/tokensSetups.ts | 8 +- utils/helpers.ts | 6 +- yarn.lock | 280 ++++++++------ 37 files changed, 843 insertions(+), 451 deletions(-) create mode 100644 test/Dex/cases/strategy/cofigure-token/configure_strategy.ts create mode 100644 test/Dex/cases/strategy/cofigure-token/connect_token.ts create mode 100644 test/Dex/cases/strategy/cofigure-token/index.ts create mode 100644 test/Dex/cases/strategy/cofigure-token/is_rebalance.ts create mode 100644 test/Dex/cases/strategy/cofigure-token/rebalance.ts create mode 100644 test/Dex/cases/strategy/connect.ts create mode 100644 test/Dex/cases/strategy/index.ts diff --git a/migrations/02_factory_pools.ts b/migrations/02_factory_pools.ts index fff35ee..b04e816 100644 --- a/migrations/02_factory_pools.ts +++ b/migrations/02_factory_pools.ts @@ -75,10 +75,10 @@ module.exports = async (tezos: TezosToolkit, network: NetworkLiteral) => { fees: pair.fees, }) .send(); - await confirmOperation(tezos, op.hash); + await op.confirmation(2); console.log("Add_pool ", op.hash); op = await factory.methods.start_dex(inputs).send(); - await confirmOperation(tezos, op.hash); + await op.confirmation(2); console.log("Start_dex ", op.hash); for (const index in poolData) { const value = pair.tokensInfo[index]; @@ -107,17 +107,17 @@ module.exports = async (tezos: TezosToolkit, network: NetworkLiteral) => { .executeView({ viewCaller: sender_addr }); const dex = await tezos.contract.at(dex_address); op = await dex.methods.set_admin(process.env.ADMIN_ADDRESS).send(); - await confirmOperation(tezos, op.hash); + await op.confirmation(2); console.log("Admin set ", process.env.ADMIN_ADDRESS); console.log(`Dex of ${pair.name} started`); } let operation = await factory.methods .set_whitelist(false, sender_addr) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); console.log("Removed from whitelist ", sender_addr); operation = await factory.methods .set_dev_address(process.env.ADMIN_ADDRESS) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); }; diff --git a/package.json b/package.json index c446ce7..1521d09 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,8 @@ "author": "Illia Likhoshva (https://www.madfish.solutions/)", "private": true, "dependencies": { - "@taquito/signer": "^11.1.0", - "@taquito/taquito": "^11.1.0", + "@taquito/signer": "^14.0.0", + "@taquito/taquito": "^14.0.0", "@types/jest": "^27.0.2", "chalk": "<5.0.0", "commander": "^8.3.0", diff --git a/scripts/commands/migrate/utils.ts b/scripts/commands/migrate/utils.ts index 2d7e5fd..50d5c15 100644 --- a/scripts/commands/migrate/utils.ts +++ b/scripts/commands/migrate/utils.ts @@ -66,7 +66,7 @@ export async function migrate( .catch((e) => { throw e; }); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); artifacts.networks[network] = { [contract]: operation.contractAddress, }; diff --git a/test/00_Dex.test.ts b/test/00_Dex.test.ts index c06ce92..31d56b8 100644 --- a/test/00_Dex.test.ts +++ b/test/00_Dex.test.ts @@ -34,7 +34,6 @@ describe("00. Standalone Dex", () => { let dex: API.DexAPI; let quipuToken: TokenFA2; - let lambdaContractAddress: TezosAddress; const { before: TInit, @@ -42,6 +41,7 @@ describe("00. Standalone Dex", () => { pools: TPool, rewards: TReward, views: TView, + strategy: TStrategy, } = DexTests; // Contract will be deployed before every single test, to make sure we @@ -49,8 +49,7 @@ describe("00. Standalone Dex", () => { beforeAll( async () => - ({ dex, tokens, quipuToken, lambdaContractAddress } = - await TInit.setupDexEnvironment(Tezos)) + ({ dex, tokens, quipuToken } = await TInit.setupDexEnvironment(Tezos)) ); describe("1. Testing Admin endpoints", () => { @@ -60,7 +59,7 @@ describe("00. Standalone Dex", () => { async () => await failCase( "bob", - async () => await dex.setAdmin(new_admin, Tezos), + async () => await dex.setAdmin(new_admin), "not-contract-admin" ), 10000 @@ -80,7 +79,7 @@ describe("00. Standalone Dex", () => { async () => await failCase( "bob", - async () => dex.setDevAddress(new_dev, Tezos), + async () => dex.setDevAddress(new_dev), "not-developer" ), 10000 @@ -91,7 +90,7 @@ describe("00. Standalone Dex", () => { async () => await failCase( "bob", - async () => await dex.setDevFee(dev_fee, Tezos), + async () => await dex.setDevFee(dev_fee), "not-developer" ), 20000 @@ -117,7 +116,7 @@ describe("00. Standalone Dex", () => { async () => await failCase( "bob", - async () => dex.addRemManager(true, manager, Tezos), + async () => dex.addRemManager(true, manager), "not-contract-admin" ), 10000 @@ -156,7 +155,7 @@ describe("00. Standalone Dex", () => { async () => await failCase( "bob", - async () => dex.setDefaultReferral(aliceAddress, Tezos), + async () => dex.setDefaultReferral(aliceAddress), "not-contract-admin" ), 10000 @@ -186,7 +185,7 @@ describe("00. Standalone Dex", () => { async () => await failCase( "alice", - async () => await dex.addPool(a_const, inputs, false, Tezos), + async () => await dex.addPool(a_const, inputs, false), "not-contract-admin" ), 10000 @@ -204,7 +203,7 @@ describe("00. Standalone Dex", () => { false, Tezos ), - 20000 + 30000 ); }); @@ -223,11 +222,11 @@ describe("00. Standalone Dex", () => { await failCase( "bob", async () => - await dex.contract.methods + dex.contract.methods .ramp_A( pool_id, - TPool.PoolAdmin.Ramp_A.future_a_const, - TPool.PoolAdmin.Ramp_A.future_a_time + TPool.PoolAdmin.Ramp_A.future_a_const.toString(), + TPool.PoolAdmin.Ramp_A.future_a_time.toString() ) .send(), "not-contract-admin" @@ -275,8 +274,7 @@ describe("00. Standalone Dex", () => { async () => await failCase( "bob", - async () => - await dex.setFees(pool_id, TPool.PoolAdmin.Fee.fees, Tezos), + async () => await dex.setFees(pool_id, TPool.PoolAdmin.Fee.fees), "not-contract-admin" ), 10000 @@ -362,14 +360,13 @@ describe("00. Standalone Dex", () => { await failCase( sender, async () => - await dex.investLiquidity( + dex.investLiquidity( pool_id, zero_amounts, min_shares, new Date(Date.now() + 1000 * 60 * 60 * 24), null, - referral, - Tezos + referral ), "zero-amount-in" ), @@ -379,17 +376,16 @@ describe("00. Standalone Dex", () => { it( "should fail if expired", async () => - await failCase( + failCase( sender, async () => - await dex.investLiquidity( + dex.investLiquidity( pool_id, amounts, min_shares, new Date(0), null, - referral, - Tezos + referral ), "time-expired" ), @@ -399,17 +395,16 @@ describe("00. Standalone Dex", () => { it( "should fail if wrong indexes", async () => - await failCase( + failCase( sender, async () => - await dex.investLiquidity( + dex.investLiquidity( pool_id, wrong_idx_amounts, min_shares, new Date(Date.now() + 1000 * 60 * 60 * 24), null, - referral, - Tezos + referral ), "zero-amount-in" ), @@ -432,6 +427,7 @@ describe("00. Standalone Dex", () => { 50000 ); + // eslint-disable-next-line jest/prefer-expect-assertions it("should invest liq imbalanced", async () => { await dex.updateStorage({ tokens: [pool_id.toString()], @@ -504,8 +500,7 @@ describe("00. Standalone Dex", () => { new BigNumber(0), new Date(0), bobAddress, - referral, - Tezos + referral ), "time-expired" ), @@ -526,8 +521,7 @@ describe("00. Standalone Dex", () => { new BigNumber(1), new Date(Date.now() + 1000 * 60 * 60 * 24), bobAddress, - referral, - Tezos + referral ), "zero-amount-in" ), @@ -549,7 +543,6 @@ describe("00. Standalone Dex", () => { idx_map, normalized, amounts, - lambdaContractAddress, Tezos ), 40000 @@ -602,8 +595,7 @@ describe("00. Standalone Dex", () => { min_amounts, new BigNumber("0"), new Date(Date.now() + 1000 * 60 * 60 * 24), - null, - Tezos + null ), "zero-amount-in" ), @@ -621,8 +613,7 @@ describe("00. Standalone Dex", () => { min_amounts, amount_in, new Date(0), - null, - Tezos + null ), "time-expired" ), @@ -864,7 +855,7 @@ describe("00. Standalone Dex", () => { token_id: pool_id, }, ]) - .read(lambdaContractAddress) + .read() .then((balances) => { expect(balances[0].balance.toNumber()).toBeGreaterThanOrEqual(0); expect(balances[1].balance.toNumber()).toBeGreaterThanOrEqual(0); @@ -874,7 +865,7 @@ describe("00. Standalone Dex", () => { it("should return total supply", async () => await dex.contract.views .total_supply(pool_id) - .read(lambdaContractAddress) + .read() .then((total_supply) => { expect(total_supply.toNumber()).toStrictEqual( dex.storage.storage.pools[ @@ -946,7 +937,6 @@ describe("00. Standalone Dex", () => { pool_id, batchTimes, referral, - lambdaContractAddress, Tezos ), 30000 @@ -978,9 +968,120 @@ describe("00. Standalone Dex", () => { pool_id, batchTimes, dev_address, - lambdaContractAddress, Tezos )); }); }); + + describe("7. Testing strategy", () => { + let pool_id: BigNumber; + let strategy: TezosAddress; + let pool_token_id: BigNumber; + + beforeAll(async () => { + await dex.updateStorage({}); + pool_id = dex.storage.storage.pools_count.minus(new BigNumber(1)); + strategy = aliceAddress; + pool_token_id = new BigNumber(0); + }); + + describe("as a developer", () => { + beforeAll(async () => { + const config = await prepareProviderOptions("bob"); + Tezos.setProvider(config); + }); + + it("should connect new strategy", async () => + await TStrategy.connect.setStrategyAddrSuccessCase( + dex, + pool_id, + strategy + )); + + it("should fail when set rebalance flag to non cofigured token", async () => + await failCase( + "bob", + async () => + await dex.setTokenStrategyRebalance(pool_id, pool_token_id, false), + "no-token-strategy-set" + )); + + it("should configure new strategy for token", async () => + await TStrategy.token.configureTokenStrategy.setStrategyParamsSuccessCase( + dex, + pool_id, + pool_token_id, + new BigNumber("0.3").multipliedBy("1e18"), + new BigNumber("0.05").multipliedBy("1e18"), + new BigNumber("300").multipliedBy("1e6") + )); + + it("should set is rebalance flag for token", async () => + await TStrategy.token.setStrategyRebalance.setIsRebalanceSuccessCase( + dex, + pool_id, + pool_token_id, + false + )); + + it("should configure strategy for token to zero", async () => + await TStrategy.token.configureTokenStrategy.setStrategyParamsToZeroSuccessCase( + dex, + pool_id, + pool_token_id + )); + + it("should disconnect new strategy", async () => + await TStrategy.connect.removeStrategyAddrSuccessCase(dex, pool_id)); + }); + + describe("as a non-developer", () => { + beforeAll(async () => { + const config = await prepareProviderOptions("eve"); + Tezos.setProvider(config); + }); + + // eslint-disable-next-line jest/prefer-expect-assertions + it("should fail when non-developer call the stategy EP", async () => { + await failCase( + "eve", + async () => + await dex.setTokenStrategyRebalance(pool_id, pool_token_id, false), + "not-developer" + ); + await failCase( + "eve", + async () => await dex.connectStrategy(pool_id, strategy), + "not-developer" + ); + await failCase( + "eve", + async () => + await dex.connectTokenStrategy( + pool_id, + pool_token_id, + new BigNumber(0) + ), + "not-developer" + ); + await failCase( + "eve", + async () => + await dex.setTokenStrategy( + pool_id, + pool_token_id, + new BigNumber("0.3").multipliedBy("1e18"), + new BigNumber("0.05").multipliedBy("1e18"), + new BigNumber("300").multipliedBy("1e6") + ), + "not-developer" + ); + await failCase( + "eve", + async () => await dex.rebalance(pool_id, pool_token_id), + "not-developer" + ); + }); + }); + }); }); diff --git a/test/01_Factory.test.ts b/test/01_Factory.test.ts index 3acf7ea..b9a828b 100644 --- a/test/01_Factory.test.ts +++ b/test/01_Factory.test.ts @@ -39,16 +39,14 @@ describe("01. Dex Factory", () => { ref_f: new BigNumber("0"), }; let factory: DexFactory; - let lambda: TezosAddress; let quipuToken: TokenFA2; beforeAll( async () => - ({ - factory, - quipuToken, - lambdaContractAddress: lambda, - } = await cases.before.setupFactoryEnvironment(tezos, developer_name)) + ({ factory, quipuToken } = await cases.before.setupFactoryEnvironment( + tezos, + developer_name + )) ); describe("1. Fee", () => { @@ -109,8 +107,7 @@ describe("01. Dex Factory", () => { dex_case.pools.PoolAdmin.Fee.fees, true, quipuToken, - tezos, - lambda + tezos ))); // eslint-disable-next-line jest/prefer-expect-assertions @@ -207,7 +204,6 @@ describe("01. Dex Factory", () => { idx_map, new BigNumber(10).pow(2), amounts, - lambda, Tezos ), 40000 @@ -263,7 +259,6 @@ describe("01. Dex Factory", () => { tokens, pool_id, developer_name, - lambda, Tezos )); }); @@ -324,7 +319,7 @@ describe("01. Dex Factory", () => { it("should deploy without QUIPU token fees", async () => { const init_balance: BigNumber = await quipuToken.contract.views .balance_of([{ owner: accounts.eve.pkh, token_id: "0" }]) - .read(lambda); + .read(); await cases.initPool.initializeExchangeSuccessCase( factory, @@ -337,13 +332,12 @@ describe("01. Dex Factory", () => { zero_fees, true, quipuToken, - tezos, - lambda + tezos ); const upd_balance: BigNumber = await quipuToken.contract.views .balance_of([{ owner: accounts.eve.pkh, token_id: "0" }]) - .read(lambda); + .read(); expect(init_balance[0].balance.toNumber()).toStrictEqual( upd_balance[0].balance.toNumber() ); @@ -401,8 +395,7 @@ describe("01. Dex Factory", () => { zero_fees, true, quipuToken, - tezos, - lambda + tezos )); }); @@ -450,8 +443,7 @@ describe("01. Dex Factory", () => { zero_fees, true, quipuToken, - tezos, - lambda + tezos )); }); diff --git a/test/Dex/API/dexAPI.ts b/test/Dex/API/dexAPI.ts index a51b71a..2b243a2 100644 --- a/test/Dex/API/dexAPI.ts +++ b/test/Dex/API/dexAPI.ts @@ -89,7 +89,8 @@ export class Dex extends TokenFA2 implements DevEnabledContract { ): Promise { this.storage = (await this.contract.storage()) as DexStorage; for (const key in maps) { - if ([ + if ( + [ "dex_lambdas", "token_lambdas", "admin_lambdas", @@ -102,8 +103,9 @@ export class Dex extends TokenFA2 implements DevEnabledContract { try { return { ...(await prev), - [key == "ledger" ? current[0] : current]: - await this.storage.storage[key].get(current), + [key == "ledger" || key == "configuration" + ? current[0] + : current]: await this.storage.storage[key].get(current), }; } catch (ex) { console.error(ex); @@ -141,20 +143,26 @@ export class Dex extends TokenFA2 implements DevEnabledContract { } async addPool( - a_const: BigNumber = new BigNumber("100000"), - token_info: { + aConst: BigNumber = new BigNumber("100000"), + tokenInfo: { asset: TokenFA12 | TokenFA2; in_amount: BigNumber; rate_f: BigNumber; precision_multiplier_f: BigNumber; }[], - approve = true, - tezos: TezosToolkit + approve = true ): Promise { - const tokens_info = new MichelsonMap(); + const tokens_info = new MichelsonMap< + number, + { + rate_f: string; + precision_multiplier_f: string; + reserves: string; + } + >(); const input_tokens: Array = []; - for (let i = 0; i < token_info.length; i++) { - const info = token_info[i]; + for (let i = 0; i < tokenInfo.length; i++) { + const info = tokenInfo[i]; if (approve) { await info.asset.approve(this.contract.address, info.in_amount); } @@ -165,9 +173,9 @@ export class Dex extends TokenFA2 implements DevEnabledContract { precision_multiplier_f: BigNumber; }) => { let result: { - rate_f: BigNumber; - precision_multiplier_f: BigNumber; - reserves: BigNumber; + rate_f: string; + precision_multiplier_f: string; + reserves: string; }; if (input.asset instanceof TokenFA2) { input_tokens.push({ @@ -177,18 +185,18 @@ export class Dex extends TokenFA2 implements DevEnabledContract { }, }); result = { - rate_f: input.rate_f, - precision_multiplier_f: input.precision_multiplier_f, - reserves: input.in_amount, + rate_f: input.rate_f.toString(), + precision_multiplier_f: input.precision_multiplier_f.toString(), + reserves: input.in_amount.toString(), }; } else { input_tokens.push({ fa12: input.asset.contract.address, }); result = { - rate_f: input.rate_f, - precision_multiplier_f: input.precision_multiplier_f, - reserves: input.in_amount, + rate_f: input.rate_f.toString(), + precision_multiplier_f: input.precision_multiplier_f.toString(), + reserves: input.in_amount.toString(), }; } return result; @@ -197,7 +205,7 @@ export class Dex extends TokenFA2 implements DevEnabledContract { } const operation = await this.contract.methodsObject .add_pool({ - a_constant: a_const, + a_constant: aConst.toString(), input_tokens: input_tokens, tokens_info, fees: { @@ -207,7 +215,7 @@ export class Dex extends TokenFA2 implements DevEnabledContract { }, }) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -219,22 +227,23 @@ export class Dex extends TokenFA2 implements DevEnabledContract { minAmountOut: BigNumber, expiration: Date, receiver: string = null, - referral: string = null, - tezos: TezosToolkit + referral: string = null ): Promise { - const operation = await this.contract.methods - .swap( - poolId, - inIdx, - toIdx, - amountIn, - minAmountOut, - new BigNumber(expiration.getTime()).dividedToIntegerBy(1000), - receiver, - referral - ) + const operation = await this.contract.methodsObject + .swap({ + pool_id: poolId.toString(), + idx_from: inIdx.toString(), + idx_to: toIdx.toString(), + amount: amountIn.toString(), + min_amount_out: minAmountOut.toString(), + deadline: new BigNumber(expiration.getTime()) + .dividedToIntegerBy(1000) + .toString(), + receiver: receiver, + referral: referral, + }) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -244,24 +253,25 @@ export class Dex extends TokenFA2 implements DevEnabledContract { minShares: BigNumber, expiration: Date, receiver: TezosAddress = null, - referral: TezosAddress = null, - tezos: TezosToolkit + referral: TezosAddress = null ): Promise { const in_amounts = new MichelsonMap(); tokenAmounts.forEach((value, key) => { - in_amounts.set(key, value.toNumber()); + in_amounts.set(key, value); }); - const operation = await this.contract.methods - .invest( - poolId, - minShares, - in_amounts, - new BigNumber(expiration.getTime()).dividedToIntegerBy(1000), - receiver, - referral - ) + const operation = await this.contract.methodsObject + .invest({ + pool_id: poolId.toString(), + shares: minShares.toString(), + in_amounts: in_amounts, + deadline: new BigNumber(expiration.getTime()) + .dividedToIntegerBy(1000) + .toString(), + receiver: receiver, + referral: referral, + }) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -270,23 +280,24 @@ export class Dex extends TokenFA2 implements DevEnabledContract { mintokenAmounts: Map, sharesBurned: BigNumber, expiration: Date, - receiver: TezosAddress = null, - tezos: TezosToolkit + receiver: TezosAddress = null ): Promise { - const amts = new MichelsonMap(); + const amts = new MichelsonMap(); mintokenAmounts.forEach((value, key) => { - amts.set(key, value); + amts.set(key, value.toString()); }); - const operation = await this.contract.methods - .divest( - poolId, - amts, - sharesBurned, - new BigNumber(expiration.getTime()).dividedToIntegerBy(1000), - receiver - ) + const operation = await this.contract.methodsObject + .divest({ + pool_id: poolId.toString(), + min_amounts_out: amts, + shares: sharesBurned.toString(), + deadline: new BigNumber(expiration.getTime()) + .dividedToIntegerBy(1000) + .toString(), + receiver: receiver, + }) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -296,25 +307,26 @@ export class Dex extends TokenFA2 implements DevEnabledContract { maxSharesBurned: BigNumber, expiration: Date, receiver: TezosAddress = null, - referral: TezosAddress = null, - tezos: TezosToolkit + referral: TezosAddress = null ): Promise { const amts = new MichelsonMap(); tokenAmounts.forEach((value, key) => { amts.set(key, value); }); - const operation = await this.contract.methods - .divest_imbalanced( - poolId, - amts, - maxSharesBurned, - new BigNumber(expiration.getTime()).dividedToIntegerBy(1000), - receiver, - referral - ) + const operation = await this.contract.methodsObject + .divest_imbalanced({ + pool_id: poolId.toString(), + amounts_out: amts, + max_shares: maxSharesBurned.toString(), + deadline: new BigNumber(expiration.getTime()) + .dividedToIntegerBy(1000) + .toString(), + receiver: receiver, + referral: referral, + }) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -325,84 +337,173 @@ export class Dex extends TokenFA2 implements DevEnabledContract { mintokenAmount: BigNumber, expiration: Date, receiver: TezosAddress = null, - referral: TezosAddress = null, - tezos: TezosToolkit + referral: TezosAddress = null ): Promise { - const operation = await this.contract.methods - .divest_one_coin( - poolId, - sharesBurned, - tokenIdx, - mintokenAmount, - new BigNumber(expiration.getTime()).dividedToIntegerBy(1000), - receiver, - referral - ) + const operation = await this.contract.methodsObject + .divest_one_coin({ + pool_id: poolId.toString(), + shares: sharesBurned.toString(), + token_index: tokenIdx.toString(), + min_amount_out: mintokenAmount.toString(), + deadline: new BigNumber(expiration.getTime()) + .dividedToIntegerBy(1000) + .toString(), + receiver: receiver, + referral: referral, + }) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } - async setAdmin( - new_admin: string, - tezos: TezosToolkit - ): Promise { + async setAdmin(newAdmin: string): Promise { await this.updateStorage({}); - const operation = await this.contract.methods.set_admin(new_admin).send(); + const operation = await this.contract.methods.set_admin(newAdmin).send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } async addRemManager( add: boolean, - manager: string, - tezos: TezosToolkit + manager: string ): Promise { await this.updateStorage({}); const operation = await this.contract.methods .add_rem_managers(add, manager) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } - async setDevAddress( - dev: string, - tezos: TezosToolkit - ): Promise { + async setDevAddress(dev: string): Promise { await this.updateStorage({}); const operation = await this.contract.methods.set_dev_address(dev).send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); + return operation; + } + + async connectStrategy( + poolId: BigNumber, + strategy: string | null = null + ): Promise { + await this.updateStorage({}); + const operation = await this.contract.methods + .connect_strategy(poolId, strategy) + .send(); + + await operation.confirmation(2); + // await confirmOperation(tezos, operation.hash); + return operation; + } + + async setTokenStrategy( + poolId: BigNumber, + poolTokenId: BigNumber, + desiredReservesRate_f: BigNumber, + deltaRate_f: BigNumber, + minInvestment: BigNumber + ): Promise { + await this.updateStorage({}); + const operation = await this.contract.methodsObject + .set_token_strategy({ + pool_id: poolId.toString(), + pool_token_id: poolTokenId.toString(), + des_reserves_rate_f: desiredReservesRate_f.toString(), + delta_rate_f: deltaRate_f.toString(), + min_invest: minInvestment.toString(), + }) + .send(); + + await operation.confirmation(2); + // await confirmOperation(tezos, operation.hash); return operation; } + + async setTokenStrategyRebalance( + poolId: BigNumber, + poolTokenId: BigNumber, + flag: boolean + ): Promise { + await this.updateStorage({}); + const operation = await this.contract.methods + .set_token_strategy_rebalance( + poolId.toString(), + poolTokenId.toString(), + flag + ) + .send(); + + await operation.confirmation(2); + // await confirmOperation(tezos, operation.hash); + return operation; + } + + setIsRebalanceStrategy = ( + poolId: BigNumber, + poolTokenId: BigNumber, + flag: boolean + ): Promise => + this.setTokenStrategyRebalance(poolId, poolTokenId, flag); + + async rebalance( + poolId: BigNumber, + poolTokenId: BigNumber + ): Promise { + await this.updateStorage({}); + const operation = await this.contract.methods + .rebalance(poolId.toString(), poolTokenId.toString()) + .send(); + + await operation.confirmation(2); + // await confirmOperation(tezos, operation.hash); + return operation; + } + + manualRebalanceStrategy = ( + poolId: BigNumber, + poolTokenId: BigNumber + ): Promise => this.rebalance(poolId, poolTokenId); + + async connectTokenStrategy( + poolId: BigNumber, + poolTokenId: BigNumber, + lendingMarketId: BigNumber + ): Promise { + await this.updateStorage({}); + const operation = await this.contract.methods + .connect_token_strategy( + poolId.toString(), + poolTokenId.toString(), + lendingMarketId.toString() + ) + .send(); + + await operation.confirmation(2); + // await confirmOperation(tezos, operation.hash); + return operation; + } + async setFees( pool_id: BigNumber, - fees: FeeType, - tezos: TezosToolkit + fees: FeeType ): Promise { const operation = await this.contract.methods .set_fees(pool_id, fees.lp_f, fees.stakers_f, fees.ref_f) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } - async setDevFee( - fee: BigNumber, - tezos: TezosToolkit - ): Promise { + async setDevFee(fee: BigNumber): Promise { const operation = await this.contract.methods.set_dev_fee(fee).send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } - async setDefaultReferral( - ref: string, - tezos: TezosToolkit - ): Promise { + async setDefaultReferral(ref: string): Promise { const operation = await this.contract.methods .set_default_referral(ref) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -410,36 +511,34 @@ export class Dex extends TokenFA2 implements DevEnabledContract { tokenAddress: string, tokenId: BigNumber, tokenAmount: number, - address: string, - tezos: TezosToolkit + address: string ): Promise { await this.updateStorage(); - const token = await tezos.contract.at(tokenAddress); + const token = await this.Tezos.contract.at(tokenAddress); const operation = await token.methods .update_operators([ { [tokenAmount ? "add_operator" : "remove_operator"]: { - owner: await tezos.signer.publicKeyHash(), + owner: await this.Tezos.signer.publicKeyHash(), operator: address, token_id: tokenId, }, }, ]) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } async approveFA12Token( tokenAddress: string, tokenAmount: number, - address: string, - tezos: TezosToolkit + address: string ): Promise { await this.updateStorage(); - const token = await tezos.contract.at(tokenAddress); + const token = await this.Tezos.contract.at(tokenAddress); const operation = await token.methods.approve(address, tokenAmount).send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } } diff --git a/test/Dex/API/types.ts b/test/Dex/API/types.ts index 6c6b756..37dd634 100644 --- a/test/Dex/API/types.ts +++ b/test/Dex/API/types.ts @@ -34,7 +34,7 @@ export declare type TokenStrategyConfiguration = { export declare type StrategyStoreType = { strat_contract?: TezosAddress; - configuration: MichelsonMap; + configuration: MichelsonMap; }; export declare type PairInfo = { diff --git a/test/Dex/cases/admin.ts b/test/Dex/cases/admin.ts index 07113fd..27c15df 100644 --- a/test/Dex/cases/admin.ts +++ b/test/Dex/cases/admin.ts @@ -24,7 +24,7 @@ export async function setAdminSuccessCase( expect(admin).not.toStrictEqual(initAdmin); expect(sender_address).toStrictEqual(initAdmin); - await dex.setAdmin(admin, Tezos); + await dex.setAdmin(admin); await dex.updateStorage({}); const updatedAdmin = dex.storage.storage.admin; @@ -46,7 +46,7 @@ export async function updateManagersSuccessCase( // initManagers includes manager if want to remove and not includes if add expect(initManagers.includes(manager)).not.toBe(add); - await dex.addRemManager(add, manager, Tezos); + await dex.addRemManager(add, manager); await dex.updateStorage({}); const updatedManagers = dex.storage.storage.managers; @@ -66,7 +66,7 @@ export async function setDefaultRefSuccessCase( const initRef = dex.storage.storage.default_referral; expect(ref).not.toStrictEqual(initRef); - await dex.setDefaultReferral(ref, Tezos); + await dex.setDefaultReferral(ref); await dex.updateStorage({}); const updatedDev = dex.storage.storage.default_referral; diff --git a/test/Dex/cases/admin/fees.ts b/test/Dex/cases/admin/fees.ts index 8d934f9..63aae9b 100644 --- a/test/Dex/cases/admin/fees.ts +++ b/test/Dex/cases/admin/fees.ts @@ -30,7 +30,7 @@ export async function setFeesSuccessCase( expect(initFee[key].toNumber()).not.toStrictEqual(fees[key].toNumber()); } - await dex.setFees(pool_id, fees, Tezos); + await dex.setFees(pool_id, fees); await dex.updateStorage({ pools: [pool_id.toString()] }); const updStorage: DexStorage = await dex.contract.storage(); diff --git a/test/Dex/cases/admin/rampA.ts b/test/Dex/cases/admin/rampA.ts index 210d1c8..1c33baf 100644 --- a/test/Dex/cases/admin/rampA.ts +++ b/test/Dex/cases/admin/rampA.ts @@ -25,8 +25,10 @@ export async function rampASuccessCase( ft_time = new BigNumber(Date.now()) .plus(ft_time.multipliedBy(1000)) .dividedToIntegerBy(1000); - const op = await dex.contract.methods.ramp_A(pool_id, ft_a, ft_time).send(); - await confirmOperation(Tezos, op.hash); + const op = await dex.contract.methods + .ramp_A(pool_id, ft_a.toString(), ft_time.toString()) + .send(); + await op.confirmation(2); await dex.updateStorage({ pools: [pool_id.toString()] }); const upd: PairInfo = dex.storage.storage.pools[pool_id.toString()]; const { @@ -52,7 +54,7 @@ export async function stopRampASuccessCase(dex: Dex, pool_id: BigNumber) { initial_A_time: init_in_A_t, } = init; const op = await dex.contract.methods.stop_ramp_A(pool_id).send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); await dex.updateStorage({ pools: [pool_id.toString()] }); const upd: PairInfo = dex.storage.storage.pools[pool_id.toString()]; const { diff --git a/test/Dex/cases/before.ts b/test/Dex/cases/before.ts index f152c1b..5cbe05d 100644 --- a/test/Dex/cases/before.ts +++ b/test/Dex/cases/before.ts @@ -23,17 +23,10 @@ export async function setupDexEnvironment(Tezos: TezosToolkit): Promise<{ dex: Dex; tokens: TokensMap; quipuToken: TokenFA2; - lambdaContractAddress: string; }> { const config = await prepareProviderOptions("alice"); Tezos.setProvider(config); - const op = await Tezos.contract.originate({ - code: VIEW_LAMBDA.code, - storage: VIEW_LAMBDA.storage, - }); - await confirmOperation(Tezos, op.hash); const quipuToken = await setupQuipuGovToken(Tezos); - const lambdaContractAddress = op.contractAddress; storage.storage.admin = accounts.alice.pkh; storage.storage.default_referral = accounts.bob.pkh; storage.storage.quipu_token = { @@ -51,7 +44,7 @@ export async function setupDexEnvironment(Tezos: TezosToolkit): Promise<{ code: dex_contract.michelson, storage: storage, }); - await confirmOperation(Tezos, dex_op.hash); + await dex_op.confirmation(2); console.debug( `[${chalk.green("ORIGINATION")}] DEX`, chalk.bold.underline(dex_op.contractAddress) @@ -59,5 +52,5 @@ export async function setupDexEnvironment(Tezos: TezosToolkit): Promise<{ const dex = await Dex.init(Tezos, dex_op.contractAddress); await new Promise((r) => setTimeout(r, 2000)); const tokens = await setupTrioTokens(dex, Tezos, true); - return { dex, tokens, quipuToken, lambdaContractAddress }; + return { dex, tokens, quipuToken }; } diff --git a/test/Dex/cases/index.ts b/test/Dex/cases/index.ts index c9e6c5e..4c9bf47 100644 --- a/test/Dex/cases/index.ts +++ b/test/Dex/cases/index.ts @@ -3,11 +3,13 @@ import * as admin from "./admin"; import * as pools from "./pool_part"; import * as rewards from "./rewards"; import * as views from "./views"; +import strategy from "./strategy"; export const cases = { before, admin, pools, rewards, views, + strategy, }; export default cases; diff --git a/test/Dex/cases/pool_part/add.ts b/test/Dex/cases/pool_part/add.ts index 69e7863..d2280ec 100644 --- a/test/Dex/cases/pool_part/add.ts +++ b/test/Dex/cases/pool_part/add.ts @@ -78,7 +78,7 @@ export async function addNewPair( const initPairCount = new BigNumber(dex.storage.storage.pools_count); expect(sender_addr).toStrictEqual(dex.storage.storage.admin); - await dex.addPool(a_const, inputs, approve, Tezos); + await dex.addPool(a_const, inputs, approve); await dex.updateStorage({}); await dex.updateStorage({ diff --git a/test/Dex/cases/pool_part/divest.ts b/test/Dex/cases/pool_part/divest.ts index ae2464d..e2413b0 100644 --- a/test/Dex/cases/pool_part/divest.ts +++ b/test/Dex/cases/pool_part/divest.ts @@ -54,14 +54,7 @@ export async function divestLiquiditySuccessCase( (value, key) => (raw_res[key] = value.reserves.toFormat(0).toString()) ); const init_ledger = dex.storage.storage.ledger[accounts[sender].pkh]; - await dex.divestLiquidity( - pool_id, - min_amounts, - shares, - expiration, - null, - Tezos - ); + await dex.divestLiquidity(pool_id, min_amounts, shares, expiration, null); await dex.updateStorage({ pools: [pool_id.toString()], ledger: [[accounts[sender].pkh, pool_id.toNumber()]], @@ -107,8 +100,7 @@ export async function divestLiquidityImbalanceSuccessCase( max_shares, expiration, null, - null, - Tezos + null ); await dex.updateStorage({ pools: [pool_id.toString()], @@ -159,8 +151,7 @@ export async function divestLiquidityOneSuccessCase( min_amount, expiration, null, - null, - Tezos + null ); await dex.updateStorage({ pools: [pool_id.toString()], diff --git a/test/Dex/cases/pool_part/invest.ts b/test/Dex/cases/pool_part/invest.ts index 6d42df0..40da66e 100644 --- a/test/Dex/cases/pool_part/invest.ts +++ b/test/Dex/cases/pool_part/invest.ts @@ -33,8 +33,7 @@ export async function investLiquiditySuccessCase( min_shares, expiration, null, - referral, - Tezos + referral ); await dex.updateStorage({ diff --git a/test/Dex/cases/pool_part/stake.ts b/test/Dex/cases/pool_part/stake.ts index f07ad3d..175eef5 100644 --- a/test/Dex/cases/pool_part/stake.ts +++ b/test/Dex/cases/pool_part/stake.ts @@ -23,7 +23,7 @@ export async function stakeToPoolSuccessCase( .then((balance) => balance.get([staker, pool_id.toString()])) .then((value) => (value ? value.balance : new BigNumber(0))); const op = await dex.contract.methods.stake("add", pool_id, input).send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); await dex.updateStorage({ pools: [pool_id.toString()] }); const upd_total_stake = dex.storage.storage.pools[pool_id.toNumber()].staker_accumulator @@ -59,7 +59,7 @@ export async function unstakeFromPoolSuccessCase( .then((balance) => balance.get([staker, pool_id.toString()])) .then((value) => (value ? value.balance : new BigNumber(0))); const op = await dex.contract.methods.stake("remove", pool_id, output).send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); await dex.updateStorage({ pools: [pool_id.toString()] }); const upd_total_stake = dex.storage.storage.pools[pool_id.toNumber()].staker_accumulator diff --git a/test/Dex/cases/pool_part/swap.ts b/test/Dex/cases/pool_part/swap.ts index cc89274..2030caa 100644 --- a/test/Dex/cases/pool_part/swap.ts +++ b/test/Dex/cases/pool_part/swap.ts @@ -52,7 +52,6 @@ export async function swapSuccessCase( idx_map: IndexMap, normalized_input: BigNumber, amounts: Map, - lambdaContractAddress: string, Tezos: TezosToolkit ) { const config = await prepareProviderOptions(sender); @@ -76,12 +75,12 @@ export async function swapSuccessCase( let init_in: BigNumber = await (tok_in instanceof TokenFA12 ? t_in_ep(accounts[sender].pkh) : t_in_ep([{ owner: accounts[sender].pkh, token_id: "0" }]) - ).read(lambdaContractAddress); + ).read(); let init_out: BigNumber = await (tok_out instanceof TokenFA12 ? t_out_ep(accounts[sender].pkh) : t_out_ep([{ owner: accounts[sender].pkh, token_id: "0" }]) - ).read(lambdaContractAddress); + ).read(); const in_amount = amounts.get(i); let min_out = amounts.get(j); @@ -104,8 +103,7 @@ export async function swapSuccessCase( min_out, exp, accounts[sender].pkh, - referral, - Tezos + referral ); await dex.updateStorage({ pools: [pool_id.toString()] }); const upd_reserves = @@ -147,11 +145,11 @@ export async function swapSuccessCase( let upd_in = await (tok_in instanceof TokenFA12 ? t_in_ep(accounts[sender].pkh) : t_in_ep([{ owner: accounts[sender].pkh, token_id: "0" }]) - ).read(lambdaContractAddress); + ).read(); let upd_out = await (tok_out instanceof TokenFA12 ? t_out_ep(accounts[sender].pkh) : t_out_ep([{ owner: accounts[sender].pkh, token_id: "0" }]) - ).read(lambdaContractAddress); + ).read(); expect(output.toNumber()).toBeGreaterThanOrEqual(min_out.toNumber()); @@ -295,7 +293,7 @@ export async function batchSwap( ); } const op = await batch.send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); console.debug( `[${chalk.bold.bgWhite.bgBlueBright( "BATCH" diff --git a/test/Dex/cases/rewards/developer.ts b/test/Dex/cases/rewards/developer.ts index 978cf7e..8c6cd20 100644 --- a/test/Dex/cases/rewards/developer.ts +++ b/test/Dex/cases/rewards/developer.ts @@ -15,7 +15,6 @@ export async function getDeveloperRewardsSuccessCase( pool_id: BigNumber, batchTimes: number, developer: string, - lambdaContractAddress: string, Tezos: TezosToolkit ) { const config = await prepareProviderOptions("bob"); @@ -32,13 +31,13 @@ export async function getDeveloperRewardsSuccessCase( }); const initUSDtz = await tokens.USDtz.contract.views .getBalance(developer) - .read(lambdaContractAddress); + .read(); const initkUSD = await tokens.kUSD.contract.views .getBalance(developer) - .read(lambdaContractAddress); + .read(); const inituUSD = await tokens.uUSD.contract.views .balance_of([{ owner: developer, token_id: "0" }]) - .read(lambdaContractAddress); + .read(); const USDtzRewards = await dev_stor.get({ fa12: tokens.USDtz.contract.address, @@ -73,10 +72,13 @@ export async function getDeveloperRewardsSuccessCase( kUSD: kUSDRewards, uUSD: uUSDRewards, }; - let op = await dex.contract.methods - .claim_developer("fa12", tokens.USDtz.contract.address, USDtzRewards) + let op = await dex.contract.methodsObject + .claim_developer({ + token: { fa12: tokens.USDtz.contract.address }, + amount: USDtzRewards.toString(), + }) .send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); console.debug(`[${chalk.bgGreenBright.red("CLAIM")}:DEVELOPER] USDtz`); await dex.updateStorage({ pools: [pool_id.toString()] }); let upd_dev_stor = await dex.contract @@ -88,10 +90,13 @@ export async function getDeveloperRewardsSuccessCase( fa12: tokens.USDtz.contract.address, }); expect(updUSDtzRewards.toNumber()).toBe(0); - op = await dex.contract.methods - .claim_developer("fa12", tokens.kUSD.contract.address, kUSDRewards) + op = await dex.contract.methodsObject + .claim_developer({ + token: { fa12: tokens.kUSD.contract.address }, + amount: kUSDRewards.toString(), + }) .send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); console.debug(`[${chalk.bgGreenBright.red("CLAIM")}:DEVELOPER] kUSD`); await dex.updateStorage({ pools: [pool_id.toString()] }); upd_dev_stor = await dex.contract.storage().then((storage: DexStorage) => { @@ -101,15 +106,18 @@ export async function getDeveloperRewardsSuccessCase( fa12: tokens.kUSD.contract.address, }); expect(updkUSDRewards.toNumber()).toBe(0); - op = await dex.contract.methods - .claim_developer( - "fa2", - tokens.uUSD.contract.address, - new BigNumber(defaultTokenId), - uUSDRewards - ) + op = await dex.contract.methodsObject + .claim_developer({ + token: { + fa2: { + token_address: tokens.uUSD.contract.address, + token_id: new BigNumber(defaultTokenId).toString(), + }, + }, + amount: uUSDRewards.toString(), + }) .send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); console.debug(`[${chalk.bgGreenBright.red("CLAIM")}:DEVELOPER] uUSD`); upd_dev_stor = await dex.contract.storage().then((storage: DexStorage) => { return storage.storage.dev_rewards; @@ -123,13 +131,11 @@ export async function getDeveloperRewardsSuccessCase( expect(upduUSDRewards.toNumber()).toBe(0); const updUSDtz = await tokens.USDtz.contract.views .getBalance(developer) - .read(lambdaContractAddress); - const updkUSD = await tokens.kUSD.contract.views - .getBalance(developer) - .read(lambdaContractAddress); + .read(); + const updkUSD = await tokens.kUSD.contract.views.getBalance(developer).read(); const upduUSD = await tokens.uUSD.contract.views .balance_of([{ owner: developer, token_id: "0" }]) - .read(lambdaContractAddress); + .read(); expect(updUSDtz.minus(initUSDtz).toNumber()).toStrictEqual( init_rewards.USDtz.toNumber() ); diff --git a/test/Dex/cases/rewards/referral.ts b/test/Dex/cases/rewards/referral.ts index 53d5683..d87d1b8 100644 --- a/test/Dex/cases/rewards/referral.ts +++ b/test/Dex/cases/rewards/referral.ts @@ -18,7 +18,6 @@ export async function getReferralRewardsSuccessCase( pool_id: BigNumber, batchSwapTimes: number, referral: AccountsLiteral, - lambdaContractAddress: string, Tezos: TezosToolkit ) { { @@ -40,13 +39,13 @@ export async function getReferralRewardsSuccessCase( }); const initUSDtz = await tokens.USDtz.contract.views .getBalance(ref_address) - .read(lambdaContractAddress); + .read(); const initkUSD = await tokens.kUSD.contract.views .getBalance(ref_address) - .read(lambdaContractAddress); + .read(); const inituUSD = await tokens.uUSD.contract.views .balance_of([{ owner: ref_address, token_id: "0" }]) - .read(lambdaContractAddress); + .read(); const USDtzRewards = await ref_stor.get({ 0: ref_address, @@ -82,10 +81,13 @@ export async function getReferralRewardsSuccessCase( kUSD: kUSDRewards, uUSD: uUSDRewards, }; - let op = await dex.contract.methods - .claim_referral("fa12", tokens.USDtz.contract.address, USDtzRewards) + let op = await dex.contract.methodsObject + .claim_referral({ + token: { fa12: tokens.USDtz.contract.address }, + amount: USDtzRewards.toString(), + }) .send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); console.debug(`[${chalk.bgGreenBright.red("CLAIM")}:REFERRAL] USDtz`); await dex.updateStorage({ pools: [pool_id.toString()] }); let upd_ref_stor = await dex.contract @@ -98,10 +100,13 @@ export async function getReferralRewardsSuccessCase( 1: { fa12: tokens.USDtz.contract.address }, }); expect(updUSDtzRewards.toNumber()).toBe(0); - op = await dex.contract.methods - .claim_referral("fa12", tokens.kUSD.contract.address, kUSDRewards) + op = await dex.contract.methodsObject + .claim_referral({ + token: { fa12: tokens.kUSD.contract.address }, + amount: kUSDRewards.toString(), + }) .send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); console.debug(`[${chalk.bgGreenBright.red("CLAIM")}:REFERRAL] kUSD`); await dex.updateStorage({ pools: [pool_id.toString()] }); upd_ref_stor = await dex.contract.storage().then((storage: DexStorage) => { @@ -112,15 +117,18 @@ export async function getReferralRewardsSuccessCase( 1: { fa12: tokens.kUSD.contract.address }, }); expect(updkUSDRewards.toNumber()).toBe(0); - op = await dex.contract.methods - .claim_referral( - "fa2", - tokens.uUSD.contract.address, - new BigNumber(defaultTokenId), - uUSDRewards - ) + op = await dex.contract.methodsObject + .claim_referral({ + token: { + fa2: { + token_address: tokens.uUSD.contract.address, + token_id: new BigNumber(defaultTokenId).toString(), + }, + }, + amount: uUSDRewards.toString(), + }) .send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); console.debug(`[${chalk.bgGreenBright.red("CLAIM")}:REFERRAL] uUSD`); upd_ref_stor = await dex.contract.storage().then((storage: DexStorage) => { return storage.storage.referral_rewards; @@ -137,13 +145,13 @@ export async function getReferralRewardsSuccessCase( expect(upduUSDRewards.toNumber()).toBe(0); const updUSDtz = await tokens.USDtz.contract.views .getBalance(ref_address) - .read(lambdaContractAddress); + .read(); const updkUSD = await tokens.kUSD.contract.views .getBalance(ref_address) - .read(lambdaContractAddress); + .read(); const upduUSD = await tokens.uUSD.contract.views .balance_of([{ owner: ref_address, token_id: "0" }]) - .read(lambdaContractAddress); + .read(); expect(updUSDtz.minus(initUSDtz).toNumber()).toStrictEqual( init_rewards.USDtz.toNumber() ); diff --git a/test/Dex/cases/rewards/staker.ts b/test/Dex/cases/rewards/staker.ts index 4465c68..b9ed27c 100644 --- a/test/Dex/cases/rewards/staker.ts +++ b/test/Dex/cases/rewards/staker.ts @@ -32,10 +32,14 @@ export async function harvestFromPoolSuccessCase( new BigNumber(0).toNumber() ); }); - const op = await dex.contract.methods - .stake("remove", pool_id, new BigNumber(0)) + const op = await dex.contract.methodsObject + .stake({ + remove: { + pool_id: pool_id, + amount: new BigNumber(0).toString(), + }}) .send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); await dex.updateStorage({ pools: [pool_id.toString()] }); const upd_total_stake = dex.storage.storage.pools[pool_id.toNumber()].staker_accumulator diff --git a/test/Dex/cases/strategy/cofigure-token/configure_strategy.ts b/test/Dex/cases/strategy/cofigure-token/configure_strategy.ts new file mode 100644 index 0000000..5e9da81 --- /dev/null +++ b/test/Dex/cases/strategy/cofigure-token/configure_strategy.ts @@ -0,0 +1,67 @@ +import BigNumber from "bignumber.js"; +import { TezosToolkit } from "@taquito/taquito"; +import Dex from "../../../API"; +import { PairInfo } from "../../../API/types"; + +export async function setStrategyParamsSuccessCase( + dex: Dex, + pool_id: BigNumber, + pool_token_id: BigNumber, + des_reserves_rate_f: BigNumber, + delta_rate_f: BigNumber, + min_invest: BigNumber +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + let pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + + await dex.setTokenStrategy( + pool_id, + pool_token_id, + des_reserves_rate_f, + delta_rate_f, + min_invest + ); + + await dex.updateStorage({ pools: [pool_id.toString()] }); + pool = dex.storage.storage.pools[pool_id.toString()]; + const updatedConfiguration = pool.strategy.configuration.get( + pool_token_id.toString() + ); + expect(updatedConfiguration).toMatchObject({ + des_reserves_rate_f: des_reserves_rate_f, + delta_rate_f: delta_rate_f, + min_invest: min_invest, + }); +} + +export async function setStrategyParamsToZeroSuccessCase( + dex: Dex, + pool_id: BigNumber, + pool_token_id: BigNumber +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + let pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + + await dex.setTokenStrategy( + pool_id, + pool_token_id, + new BigNumber(0), + new BigNumber(0), + new BigNumber(0) + ); + + await dex.updateStorage({ pools: [pool_id.toString()] }); + pool = dex.storage.storage.pools[pool_id.toString()]; + const updatedConfiguration = pool.strategy.configuration.get( + pool_token_id.toString() + ); + expect(updatedConfiguration).toMatchObject({ + des_reserves_rate_f: new BigNumber(0), + delta_rate_f: new BigNumber(0), + min_invest: new BigNumber(0), + }); + + // TODO: Remove liquidity from old Strategy checks +} diff --git a/test/Dex/cases/strategy/cofigure-token/connect_token.ts b/test/Dex/cases/strategy/cofigure-token/connect_token.ts new file mode 100644 index 0000000..e69de29 diff --git a/test/Dex/cases/strategy/cofigure-token/index.ts b/test/Dex/cases/strategy/cofigure-token/index.ts new file mode 100644 index 0000000..4987a0c --- /dev/null +++ b/test/Dex/cases/strategy/cofigure-token/index.ts @@ -0,0 +1,4 @@ +export * as configureTokenStrategy from "./configure_strategy"; +// export * as connectTokenToStrategy from "./connect_token"; +export * as setStrategyRebalance from "./is_rebalance"; +// export * as manualRebalanceToken from "./rebalance"; \ No newline at end of file diff --git a/test/Dex/cases/strategy/cofigure-token/is_rebalance.ts b/test/Dex/cases/strategy/cofigure-token/is_rebalance.ts new file mode 100644 index 0000000..bc99a99 --- /dev/null +++ b/test/Dex/cases/strategy/cofigure-token/is_rebalance.ts @@ -0,0 +1,29 @@ +import BigNumber from "bignumber.js"; +import { TezosToolkit } from "@taquito/taquito"; +import Dex from "../../../API"; +import { PairInfo } from "../../../API/types"; + +export async function setIsRebalanceSuccessCase( + dex: Dex, + pool_id: BigNumber, + pool_token_id: BigNumber, + isRebalance: boolean +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + let pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const strategyStore = pool.strategy; + const initConfiguration = strategyStore.configuration.get( + pool_token_id.toString() + ); + expect(initConfiguration).not.toMatchObject({ is_rebalance: isRebalance }); + + await dex.setIsRebalanceStrategy(pool_id, pool_token_id, isRebalance); + + await dex.updateStorage({ pools: [pool_id.toString()] }); + pool = dex.storage.storage.pools[pool_id.toString()]; + const updatedConfiguration = pool.strategy.configuration.get( + pool_token_id.toString() + ); + expect(updatedConfiguration).toMatchObject({ is_rebalance: isRebalance }); +} diff --git a/test/Dex/cases/strategy/cofigure-token/rebalance.ts b/test/Dex/cases/strategy/cofigure-token/rebalance.ts new file mode 100644 index 0000000..e69de29 diff --git a/test/Dex/cases/strategy/connect.ts b/test/Dex/cases/strategy/connect.ts new file mode 100644 index 0000000..542bebf --- /dev/null +++ b/test/Dex/cases/strategy/connect.ts @@ -0,0 +1,46 @@ +import BigNumber from "bignumber.js"; +import { TezosToolkit } from "@taquito/taquito"; +import Dex from "../../API"; +import { PairInfo } from "../../API/types"; + +export async function setStrategyAddrSuccessCase( + dex: Dex, + pool_id: BigNumber, + strategy: string +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + let pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const strategyStore = pool.strategy; + const initStrat = strategyStore.strat_contract; + expect(strategy).not.toStrictEqual(initStrat); + + await dex.connectStrategy(pool_id, strategy); + + await dex.updateStorage({ pools: [pool_id.toString()] }); + pool = dex.storage.storage.pools[pool_id.toString()]; + const updatedStrat = pool.strategy.strat_contract; + expect(strategy).toStrictEqual(updatedStrat); +} + +export async function removeStrategyAddrSuccessCase( + dex: Dex, + pool_id: BigNumber +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + let pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const strategyStore = pool.strategy; + const initStrat = strategyStore.strat_contract; + expect(initStrat).not.toBeNull(); + + await dex.connectStrategy(pool_id, null); + + await dex.updateStorage({ pools: [pool_id.toString()] }); + pool = dex.storage.storage.pools[pool_id.toString()]; + const updatedStrat = pool.strategy.strat_contract; + expect(updatedStrat).toBeNull(); + + // TODO: Remove liquidity from old Strategy checks + +} diff --git a/test/Dex/cases/strategy/index.ts b/test/Dex/cases/strategy/index.ts new file mode 100644 index 0000000..039cf93 --- /dev/null +++ b/test/Dex/cases/strategy/index.ts @@ -0,0 +1,9 @@ +import * as strategyConfigToken from "./cofigure-token"; +import * as strategyConnect from "./connect"; + +export const strategyCases = { + token: strategyConfigToken, + connect: strategyConnect, +}; + +export default strategyCases; diff --git a/test/Dex/cases/views/pool.ts b/test/Dex/cases/views/pool.ts index 6a37891..b5769a6 100644 --- a/test/Dex/cases/views/pool.ts +++ b/test/Dex/cases/views/pool.ts @@ -31,21 +31,23 @@ export async function getTokenMapSuccessCase( idx_map: IndexMap ) { const value = (await dex.contract.contractViews - .get_token_map(pool_id) + .get_token_map(pool_id.toString()) .executeView({ viewCaller: accounts["alice"].pkh })) as MichelsonMap< string, FA12TokenType | FA2TokenType >; value.forEach((value, key) => { - if (key == idx_map.USDtz) { + console.error(key, value); + if (key.toString() == idx_map.USDtz.toString()) { expect(tokens_map.USDtz.contract.address).toStrictEqual( (value as FA12TokenType).fa12 ); - } else if (key == idx_map.kUSD) { + } else if (key.toString() == idx_map.kUSD.toString()) { expect(tokens_map.kUSD.contract.address).toStrictEqual( (value as FA12TokenType).fa12 ); } else { + console.error(value) expect(tokens_map.uUSD.contract.address).toStrictEqual( (value as FA2TokenType).fa2.token_address ); @@ -62,28 +64,26 @@ export async function getLPValueSuccessCase( dex.updateStorage({ pools: [pool_id.toString()] }); const pool_info: PairInfo = dex.storage.storage.pools[pool_id.toString()]; const tokens_info = pool_info.tokens_info; - const view_result = (await dex.contract.contractViews - .get_tok_per_share(pool_id) - .executeView({ viewCaller: accounts["alice"].pkh })) as MichelsonMap< - string, - BigNumber - >; + const view_result = await dex.contract.contractViews + .get_tok_per_share(pool_id.toString()) + .executeView({ viewCaller: accounts["alice"].pkh }); const pp_tks = { USDtz: null, kUSD: null, uUSD: null, }; view_result.forEach((value, key) => { - const token_info = tokens_info.get(key); + const token_info = tokens_info.get(key.toString()); const expected = token_info.reserves .multipliedBy(one_LP) .dividedToIntegerBy(pool_info.total_supply); + value = new BigNumber(value); expect(value.toNumber()).toStrictEqual(expected.toNumber()); - if (key == map_tokens_idx.USDtz) + if (key.toString() == map_tokens_idx.USDtz) pp_tks.USDtz = value.dividedBy(decimals.USDtz); - else if (key == map_tokens_idx.kUSD) + else if (key.toString() == map_tokens_idx.kUSD) pp_tks.kUSD = value.dividedBy(decimals.kUSD); - else if (key == map_tokens_idx.uUSD) + else if (key.toString() == map_tokens_idx.uUSD) pp_tks.uUSD = value.dividedBy(decimals.uUSD); }); console.debug( @@ -128,10 +128,10 @@ export async function getDySuccessCase( const i = token_idxs.uUSD; const j = token_idxs.USDtz; const params = { - pool_id: pool_id, - i: i, - j: j, - dx: dx, + pool_id: pool_id.toString(), + i: i.toString(), + j: j.toString(), + dx: dx.toString(), }; const dy = await dex.contract.contractViews .get_dy(params) diff --git a/test/Factory/API/factoryAPI.ts b/test/Factory/API/factoryAPI.ts index f2ed8db..319e4a7 100644 --- a/test/Factory/API/factoryAPI.ts +++ b/test/Factory/API/factoryAPI.ts @@ -42,7 +42,7 @@ export class DexFactory implements DevEnabledContract { const op = await factory.contract.methods .set_init_function(init_func_bytes) .send(); - await confirmOperation(tezos, op.hash); + await op.confirmation(2); await setFunctionBatchCompilled( tezos, factoryAddress, @@ -149,7 +149,7 @@ export class DexFactory implements DevEnabledContract { await this.updateStorage({}); const operation = await this.contract.methods.set_dev_address(dev).send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -158,7 +158,7 @@ export class DexFactory implements DevEnabledContract { tezos: TezosToolkit ): Promise { const operation = await this.contract.methods.set_dev_fee(fee).send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } async setInitPrice( @@ -166,7 +166,7 @@ export class DexFactory implements DevEnabledContract { tezos: TezosToolkit ): Promise { const operation = await this.contract.methods.set_price(price).send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } async setBurnRate( @@ -174,7 +174,7 @@ export class DexFactory implements DevEnabledContract { tezos: TezosToolkit ): Promise { const operation = await this.contract.methods.set_burn_rate(rate).send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } async addRemWhitelist( @@ -186,13 +186,13 @@ export class DexFactory implements DevEnabledContract { const operation = await this.contract.methods .set_whitelist(add, candidate) .send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } async claimRewards(tezos: TezosToolkit): Promise { await this.updateStorage({}); const operation = await this.contract.methods.claim_rewards(null).send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); return operation; } async addPool( @@ -266,13 +266,13 @@ export class DexFactory implements DevEnabledContract { fees, }); const operation = await opr.send(); - await confirmOperation(tezos, operation.hash); + await operation.confirmation(2); const inputs = new MichelsonMap(); tokens_info.forEach((value, key) => inputs.set(key, { token: input_tokens[key], value: value.reserves }) ); const op = await this.contract.methods.start_dex(inputs).send(); - await confirmOperation(tezos, op.hash); + await op.confirmation(2); return operation; } } diff --git a/test/Factory/cases/before.ts b/test/Factory/cases/before.ts index ad32260..2bf73ab 100644 --- a/test/Factory/cases/before.ts +++ b/test/Factory/cases/before.ts @@ -37,7 +37,7 @@ export async function setupFactoryEnvironment( code: VIEW_LAMBDA.code, storage: VIEW_LAMBDA.storage, }); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); const quipuToken = await setupQuipuGovToken(Tezos); const lambdaContractAddress = op.contractAddress; storage.storage.dev_store = { diff --git a/test/Factory/cases/init_pool.ts b/test/Factory/cases/init_pool.ts index 1c39b66..eed5cf1 100644 --- a/test/Factory/cases/init_pool.ts +++ b/test/Factory/cases/init_pool.ts @@ -33,8 +33,7 @@ export async function initializeExchangeSuccessCase( }, approve = false, quipuToken: TokenFA2, - tezos: TezosToolkit, - lambda: TezosAddress + tezos: TezosToolkit ) { const config = await prepareProviderOptions(sender); tezos.setProvider(config); @@ -42,7 +41,7 @@ export async function initializeExchangeSuccessCase( const init_balance = await quipuToken.contract.views .balance_of([{ owner: sender_addr, token_id: "0" }]) - .read(lambda); + .read(); await factory.updateStorage({}); const init_rew: BigNumber = factory.storage.storage.quipu_rewards; @@ -72,7 +71,7 @@ export async function initializeExchangeSuccessCase( await factory.updateStorage({}); const upd_balance: BigNumber = await quipuToken.contract.views .balance_of([{ owner: sender_addr, token_id: "0" }]) - .read(lambda); + .read(); const upd_rew: BigNumber = factory.storage.storage.quipu_rewards; expect(init_balance[0].balance.minus(price).toNumber()).toStrictEqual( diff --git a/test/Factory/cases/rewards.ts b/test/Factory/cases/rewards.ts index 9d955f3..7e23a07 100644 --- a/test/Factory/cases/rewards.ts +++ b/test/Factory/cases/rewards.ts @@ -36,7 +36,6 @@ export async function getDeveloperRewardsDexSuccessCase( tokens: TokensMap, pool_id: BigNumber, developer: AccountsLiteral, - lambdaContractAddress: string, Tezos: TezosToolkit ) { const config = await prepareProviderOptions(developer); @@ -53,13 +52,13 @@ export async function getDeveloperRewardsDexSuccessCase( }); const initUSDtz = await tokens.USDtz.contract.views .getBalance(developer_address) - .read(lambdaContractAddress); + .read(); const initkUSD = await tokens.kUSD.contract.views .getBalance(developer_address) - .read(lambdaContractAddress); + .read(); const inituUSD = await tokens.uUSD.contract.views .balance_of([{ owner: developer_address, token_id: "0" }]) - .read(lambdaContractAddress); + .read(); const USDtzRewards = await dev_stor.get({ fa12: tokens.USDtz.contract.address, @@ -93,7 +92,7 @@ export async function getDeveloperRewardsDexSuccessCase( let op = await dex.contract.methods .claim_developer("fa12", tokens.USDtz.contract.address, USDtzRewards) .send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); console.debug(`[${chalk.bgGreenBright.red("CLAIM")}:DEVELOPER] USDtz`); await dex.updateStorage({ pools: [pool_id.toString()] }); let upd_dev_stor = await dex.contract @@ -108,7 +107,7 @@ export async function getDeveloperRewardsDexSuccessCase( op = await dex.contract.methods .claim_developer("fa12", tokens.kUSD.contract.address, kUSDRewards) .send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); console.debug(`[${chalk.bgGreenBright.red("CLAIM")}:DEVELOPER] kUSD`); await dex.updateStorage({ pools: [pool_id.toString()] }); upd_dev_stor = await dex.contract.storage().then((storage: DexStorage) => { @@ -126,7 +125,7 @@ export async function getDeveloperRewardsDexSuccessCase( uUSDRewards ) .send(); - await confirmOperation(Tezos, op.hash); + await op.confirmation(2); console.debug(`[${chalk.bgGreenBright.red("CLAIM")}:DEVELOPER] uUSD`); upd_dev_stor = await dex.contract.storage().then((storage: DexStorage) => { return storage.storage.dev_rewards; @@ -140,13 +139,13 @@ export async function getDeveloperRewardsDexSuccessCase( expect(upduUSDRewards.toNumber()).toBe(0); const updUSDtz = await tokens.USDtz.contract.views .getBalance(developer_address) - .read(lambdaContractAddress); + .read(); const updkUSD = await tokens.kUSD.contract.views .getBalance(developer_address) - .read(lambdaContractAddress); + .read(); const upduUSD = await tokens.uUSD.contract.views .balance_of([{ owner: developer_address, token_id: "0" }]) - .read(lambdaContractAddress); + .read(); expect(updUSDtz.minus(initUSDtz).toNumber()).toStrictEqual( init_rewards.USDtz.toNumber() ); diff --git a/test/Token/tokenFA12.ts b/test/Token/tokenFA12.ts index ed0c101..b4ffdab 100644 --- a/test/Token/tokenFA12.ts +++ b/test/Token/tokenFA12.ts @@ -67,7 +67,7 @@ export class TokenFA12 implements Token { const operation = await this.contract.methods .transfer(from, to, amount) .send(); - await confirmOperation(this.Tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -77,7 +77,7 @@ export class TokenFA12 implements Token { tokenId = "0" ): Promise { const operation = await this.contract.methods.approve(to, amount).send(); - await confirmOperation(this.Tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -88,7 +88,7 @@ export class TokenFA12 implements Token { const operation = await this.contract.methods .getBalance(owner, contract) .send(); - await confirmOperation(this.Tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -100,7 +100,7 @@ export class TokenFA12 implements Token { const operation = await this.contract.methods .getAllowance(owner, trusted, contract) .send(); - await confirmOperation(this.Tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -108,7 +108,7 @@ export class TokenFA12 implements Token { const operation = await this.contract.methods .getTotalSupply(null, contract) .send(); - await confirmOperation(this.Tezos, operation.hash); + await operation.confirmation(2); return operation; } } diff --git a/test/Token/tokenFA2.ts b/test/Token/tokenFA2.ts index 992513c..0268ba6 100644 --- a/test/Token/tokenFA2.ts +++ b/test/Token/tokenFA2.ts @@ -84,7 +84,7 @@ export class TokenFA2 implements Token { ]) .send(); - await confirmOperation(this.Tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -115,7 +115,7 @@ export class TokenFA2 implements Token { const operation = await this.contract.methods .balance_of({ requests, contract }) .send(); - await confirmOperation(this.Tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -123,7 +123,7 @@ export class TokenFA2 implements Token { const operation = await this.contract.methods .token_metadata_registry(receiver) .send(); - await confirmOperation(this.Tezos, operation.hash); + await operation.confirmation(2); return operation; } @@ -146,7 +146,7 @@ export class TokenFA2 implements Token { }) ) .send(); - await confirmOperation(this.Tezos, operation.hash); + await operation.confirmation(2); return operation; } } diff --git a/test/utils/tokensSetups.ts b/test/utils/tokensSetups.ts index d54e6ff..42fd431 100644 --- a/test/utils/tokensSetups.ts +++ b/test/utils/tokensSetups.ts @@ -14,13 +14,13 @@ import chalk from "chalk"; async function originateTokens(Tezos: TezosToolkit): Promise { const kUSD = await Tezos.contract.originate(TokenInitValues.kUSD); - await confirmOperation(Tezos, kUSD.hash); + await kUSD.confirmation(2); console.debug(`[${chalk.green("ORIGINATION")}] kUSD`); const USDtz = await Tezos.contract.originate(TokenInitValues.USDtz); - await confirmOperation(Tezos, USDtz.hash); + await USDtz.confirmation(2); console.debug(`[${chalk.green("ORIGINATION")}] USDtz`); const uUSD = await Tezos.contract.originate(TokenInitValues.uUSD); - await confirmOperation(Tezos, uUSD.hash); + await uUSD.confirmation(2); console.debug(`[${chalk.green("ORIGINATION")}] uUSD`); return { kUSD: await TokenFA12.init(Tezos, kUSD.contractAddress), @@ -94,6 +94,6 @@ export async function setupQuipuGovToken( Tezos: TezosToolkit ): Promise { const quipu = await Tezos.contract.originate(TokenInitValues.QUIPU); - await confirmOperation(Tezos, quipu.hash); + await quipu.confirmation(2); return await TokenFA2.init(Tezos, quipu.contractAddress); } diff --git a/utils/helpers.ts b/utils/helpers.ts index c4f006b..6627c3b 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -118,7 +118,7 @@ export async function bakeBlocks(count: number) { to: await Tezos.signer.publicKeyHash(), amount: 1, }); - await confirmOperation(Tezos, operation.hash); + await operation.confirmation(2); } } @@ -181,7 +181,7 @@ export async function setFunctionBatchCompilled( idx = idx + 1; if (idx % batchBy == 0 || idx == comp_funcs_map.length) { const batchOp = await batch.send(); - await confirmOperation(tezos, batchOp.hash); + await batchOp.confirmation(2); console.debug( `[${chalk.bold.bgWhite.bgBlueBright( "BATCH" @@ -211,7 +211,7 @@ export async function setFunctionCompilled( }, }); idx = idx + 1; - await confirmOperation(tezos, op.hash); + await op.confirmation(2); } } diff --git a/yarn.lock b/yarn.lock index 092ccc4..3dfdd5a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -590,6 +590,16 @@ "@stablelib/hash" "^1.0.1" "@stablelib/wipe" "^1.0.1" +"@stablelib/bytes@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/bytes/-/bytes-1.0.1.tgz#0f4aa7b03df3080b878c7dea927d01f42d6a20d8" + integrity sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ== + +"@stablelib/constant-time@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/constant-time/-/constant-time-1.0.1.tgz#bde361465e1cf7b9753061b77e376b0ca4c77e35" + integrity sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg== + "@stablelib/ed25519@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@stablelib/ed25519/-/ed25519-1.0.2.tgz#937a88a2f73a71d9bdc3ea276efe8954776ae0f4" @@ -609,6 +619,32 @@ resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008" integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w== +"@stablelib/keyagreement@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz#4612efb0a30989deb437cd352cee637ca41fc50f" + integrity sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg== + dependencies: + "@stablelib/bytes" "^1.0.1" + +"@stablelib/nacl@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@stablelib/nacl/-/nacl-1.0.4.tgz#b63e0a1b87eccb13ad91dd46b2382112acfa417e" + integrity sha512-PJ2U/MrkXSKUM8C4qFs87WeCNxri7KQwR8Cdwm9q2sweGuAtTvOJGuW0F3N+zn+ySLPJA98SYWSSpogMJ1gCmw== + dependencies: + "@stablelib/poly1305" "^1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/wipe" "^1.0.1" + "@stablelib/x25519" "^1.0.3" + "@stablelib/xsalsa20" "^1.0.2" + +"@stablelib/poly1305@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/poly1305/-/poly1305-1.0.1.tgz#93bfb836c9384685d33d70080718deae4ddef1dc" + integrity sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA== + dependencies: + "@stablelib/constant-time" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + "@stablelib/random@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.1.tgz#4357a00cb1249d484a9a71e6054bc7b8324a7009" @@ -617,6 +653,23 @@ "@stablelib/binary" "^1.0.1" "@stablelib/wipe" "^1.0.1" +"@stablelib/random@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.2.tgz#2dece393636489bf7e19c51229dd7900eddf742c" + integrity sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/salsa20@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@stablelib/salsa20/-/salsa20-1.0.2.tgz#95177331f89a59d1c90f153f53265c925d4de138" + integrity sha512-nfjKzw0KTKrrKBasEP+j7UP4I8Xudom8lVZIBCp0kQNARXq72IlSic0oabg2FC1NU68L4RdHrNJDd8bFwrphYA== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/constant-time" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + "@stablelib/sha512@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/sha512/-/sha512-1.0.1.tgz#6da700c901c2c0ceacbd3ae122a38ac57c72145f" @@ -631,73 +684,101 @@ resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36" integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg== -"@taquito/http-utils@^11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@taquito/http-utils/-/http-utils-11.1.0.tgz#43e53b4f57f4f1aec355c84462ee1839ca6277cf" - integrity sha512-5kig7XKDcWlAxPx0qkGxyaqvS/rcz7DldcqcNvxAq+Z9Bb5viWIXQm4EaBKZ0KDh5PYjSS0HpbpvoGagIGwowQ== +"@stablelib/x25519@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@stablelib/x25519/-/x25519-1.0.3.tgz#13c8174f774ea9f3e5e42213cbf9fc68a3c7b7fd" + integrity sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw== dependencies: - xhr2-cookies "^1.1.0" + "@stablelib/keyagreement" "^1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/wipe" "^1.0.1" -"@taquito/michel-codec@^11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@taquito/michel-codec/-/michel-codec-11.1.0.tgz#a32555ad70d931fd7c2cf3b03d57ba44bf77abe7" - integrity sha512-Gh1ehstk2OOixeQfc3/XQLPrI4Nr/8gJCWm/Zj5FWtn0GTsxGnZR6W4EjqbWF290b4LMO8FrOAc68+I3EvPaFQ== +"@stablelib/xsalsa20@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@stablelib/xsalsa20/-/xsalsa20-1.0.2.tgz#89efc22a7ba432880ef11d876fdeba13529ccdc4" + integrity sha512-7XdBGbcNgBShmuhDXv1G1WPVCkjZdkb1oPMzSidO7Fve0MHntH6TjFkj5bfLI+aRE+61weO076vYpP/jmaAYog== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/salsa20" "^1.0.2" + "@stablelib/wipe" "^1.0.1" -"@taquito/michelson-encoder@^11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@taquito/michelson-encoder/-/michelson-encoder-11.1.0.tgz#b3cd4d88e140f9a6a1b5d3b01f4806aee381d8df" - integrity sha512-XYoegKuQ2wnlQCMkaghI+QAVKH3xnIt7x3ChJvvnbpcKOHihFgWawK0nx1HKoz8GyW6+ZeOC2DgzP5uW0C6WRw== +"@taquito/http-utils@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@taquito/http-utils/-/http-utils-14.0.0.tgz#20470f8e08d33451241742221d416c72a70d881b" + integrity sha512-ZWZzod/+/OEE26b9CnDRjHGfUKBJft3aXv/e/A9bTHAtvRNJqGIhofHcDg/jTaolBMarCF2b3XBYw35aOOSk4A== dependencies: - "@taquito/rpc" "^11.1.0" - "@taquito/utils" "^11.1.0" - bignumber.js "^9.0.1" + axios "^0.26.0" + +"@taquito/local-forging@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@taquito/local-forging/-/local-forging-14.0.0.tgz#6844d90fa530d39ce7aaaa8cd11c8723d494a7d9" + integrity sha512-Nm0xGmS1Jzd+tU0a/8Y8XuTghbiPBgHDLo+e4141TK3OAwTzOw0an+w3xK9QVfzvxfIcZBSMjeMZzOwDdiqkJQ== + dependencies: + "@taquito/utils" "^14.0.0" + bignumber.js "^9.0.2" + +"@taquito/michel-codec@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@taquito/michel-codec/-/michel-codec-14.0.0.tgz#53d09e956b04359b43ff2a1e8a487c6da20c5a5f" + integrity sha512-ftnBvUVddlHBqvQbGPHEb26KrS4lIcaZ1eIpYJWiz+akb4Pcfyq7j/OEsDZbB7Pl2FP9hqu7ZygOF34zY6Lrtw== + +"@taquito/michelson-encoder@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@taquito/michelson-encoder/-/michelson-encoder-14.0.0.tgz#f62a1ef3cb432c4c9163f20161a73d772b98dda1" + integrity sha512-KIS+xl4rKfnd6hf9LUr6W+Pb7gv8F/Qsx0fho9CtM2PodKvdef3YlvkpScBUM9QZntAlvq2XQXUVXcZkbvxygw== + dependencies: + "@taquito/rpc" "^14.0.0" + "@taquito/utils" "^14.0.0" + bignumber.js "^9.0.2" fast-json-stable-stringify "^2.1.0" -"@taquito/rpc@^11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@taquito/rpc/-/rpc-11.1.0.tgz#ec7bc2de1848330ac69f80f87f22655759d856a7" - integrity sha512-AUP1eUmjwwWzCSY00dIzGA2Xe9riO6kGG364TT3626qjDzEE/PxVy65oCiNC3BiXdtO4memQzdVI3gcKZYS3hA== - dependencies: - "@taquito/http-utils" "^11.1.0" - bignumber.js "^9.0.1" - lodash.get "^4.4.2" - lodash.set "^4.3.2" - -"@taquito/signer@^11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@taquito/signer/-/signer-11.1.0.tgz#ffb2656b332c477ee486356a6387cbe0ba48fe6a" - integrity sha512-WJLm2tJPb69F5jL/C4keIzJ/AbhmMzupiCS8jx0CXev+YKZmJE0kW7UpUzorLt9Va0grE9/VRxQiQVdAyp+w6A== - dependencies: - "@taquito/taquito" "^11.1.0" - "@taquito/utils" "^11.1.0" - bignumber.js "^9.0.1" - bip39 "^3.0.4" +"@taquito/rpc@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@taquito/rpc/-/rpc-14.0.0.tgz#30bd353a485abba0a74477e1b0eac454076b30e9" + integrity sha512-FMfb80sA+VJwNx8OTNN07boDAt2roISqLLCUgmOIwy/cFDqhII7gdS4aYWJWqlKbdPKCPqh3a3ZQD1X/jyQHOA== + dependencies: + "@taquito/http-utils" "^14.0.0" + "@taquito/utils" "^14.0.0" + bignumber.js "^9.0.2" + +"@taquito/signer@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@taquito/signer/-/signer-14.0.0.tgz#060318fe1a6f32da87a3f7ad18008ca3ba495ced" + integrity sha512-vDqp/quzAsOiVikUt5MYUKhHI3S9qlasazyXs99xK9qpGLotbx6aseKcfb/dkaTo4/eoMzP4XzTVdnk0AqcCkw== + dependencies: + "@stablelib/blake2b" "^1.0.1" + "@stablelib/ed25519" "^1.0.2" + "@stablelib/nacl" "^1.0.3" + "@taquito/taquito" "^14.0.0" + "@taquito/utils" "^14.0.0" elliptic "^6.5.4" - libsodium-wrappers "0.7.8" pbkdf2 "^3.1.2" typedarray-to-buffer "^4.0.0" -"@taquito/taquito@^11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@taquito/taquito/-/taquito-11.1.0.tgz#96c86fb6c8b7425b0faccca8150fd5127fe278d8" - integrity sha512-aGibJBTi+kCCEhz3E+wHyJ6Pf/n30Tv/m/ag2ZMoWMYxWzOHepfkYaPQ6nq4eXUcWzAAxEuAtvgJBUB2pkHlog== - dependencies: - "@taquito/http-utils" "^11.1.0" - "@taquito/michel-codec" "^11.1.0" - "@taquito/michelson-encoder" "^11.1.0" - "@taquito/rpc" "^11.1.0" - "@taquito/utils" "^11.1.0" - bignumber.js "^9.0.1" +"@taquito/taquito@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@taquito/taquito/-/taquito-14.0.0.tgz#7dc8dccbe164f5ef52d61e40f9a8084da340b172" + integrity sha512-JaXfvqOCF3dkwXxhe00Ravb8WLMC2VqJxerf4GrGUEpJw+NAkwbGEb8k/52+MQQdlxMPepZdPPru/HM3nFG0Tw== + dependencies: + "@taquito/http-utils" "^14.0.0" + "@taquito/local-forging" "^14.0.0" + "@taquito/michel-codec" "^14.0.0" + "@taquito/michelson-encoder" "^14.0.0" + "@taquito/rpc" "^14.0.0" + "@taquito/utils" "^14.0.0" + bignumber.js "^9.0.2" rxjs "^6.6.3" -"@taquito/utils@^11.1.0": - version "11.1.0" - resolved "https://registry.yarnpkg.com/@taquito/utils/-/utils-11.1.0.tgz#f179881e0e211dfb2764fbf2ea4fd467ae3426c5" - integrity sha512-65Ms8lRD7Y7E4X9wqDugtoskRhGvonn4MTVfuWCZJEDHR6iKhy5SO/fy31wWvTc8281BsNelvniiItHgLx69wg== +"@taquito/utils@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@taquito/utils/-/utils-14.0.0.tgz#2fdbf0de677b5ef68e8a6d618a6a996195ae170b" + integrity sha512-0RSHn/CzbcbMdldJJIlXyxOvAajwmL6iPKJ6NaRyYJqqLM2CxYjG72KpXVv716pCMV1MbIWsOAr9FKbxW73PsA== dependencies: "@stablelib/blake2b" "^1.0.1" "@stablelib/ed25519" "^1.0.2" - blakejs "^1.1.0" + "@types/bs58check" "^2.1.0" + bignumber.js "^9.0.2" + blakejs "^1.2.1" bs58check "^2.1.2" buffer "^6.0.3" elliptic "^6.5.4" @@ -761,6 +842,13 @@ dependencies: "@babel/types" "^7.3.0" +"@types/bs58check@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/bs58check/-/bs58check-2.1.0.tgz#7d25a8b88fe7a9e315d2647335ee3c43c8fdb0c0" + integrity sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ== + dependencies: + "@types/node" "*" + "@types/graceful-fs@^4.1.2": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" @@ -805,11 +893,6 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.6.tgz#040a64d7faf9e5d9e940357125f0963012e66f04" integrity sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ== -"@types/node@11.11.6": - version "11.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" - integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== - "@types/prettier@^2.1.5": version "2.3.2" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3" @@ -1033,6 +1116,13 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +axios@^0.26.0: + version "0.26.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9" + integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA== + dependencies: + follow-redirects "^1.14.8" + babel-jest@^27.2.1: version "27.2.1" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.2.1.tgz#48edfa5cf8d59ab293da94321a369ccc7b67a4b1" @@ -1111,25 +1201,15 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -bignumber.js@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.1.tgz#8d7ba124c882bfd8e43260c67475518d0689e4e5" - integrity sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA== - -bip39@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.0.4.tgz#5b11fed966840b5e1b8539f0f54ab6392969b2a0" - integrity sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw== - dependencies: - "@types/node" "11.11.6" - create-hash "^1.1.0" - pbkdf2 "^3.0.9" - randombytes "^2.0.1" +bignumber.js@^9.0.2: + version "9.1.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.0.tgz#8d340146107fe3a6cb8d40699643c302e8773b62" + integrity sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A== -blakejs@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.1.tgz#bf313053978b2cd4c444a48795710be05c785702" - integrity sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg== +blakejs@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" + integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== bn.js@^4.11.9: version "4.12.0" @@ -1344,11 +1424,6 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" -cookiejar@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.2.tgz#dd8a235530752f988f9a0844f3fc589e3111125c" - integrity sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA== - create-hash@^1.1.0, create-hash@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" @@ -1825,6 +1900,11 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== +follow-redirects@^1.14.8: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + form-data@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" @@ -2698,18 +2778,6 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -libsodium-wrappers@0.7.8: - version "0.7.8" - resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.8.tgz#d95cdf3e7236c2aef76844bf8e1929ba9eef3e9e" - integrity sha512-PDhPWXBqd/SaqAFUBgH2Ux7b3VEEJgyD6BQB+VdNFJb9PbExGr/T/myc/MBoSvl8qLzfm0W0IVByOQS5L1MrCg== - dependencies: - libsodium "0.7.8" - -libsodium@0.7.8: - version "0.7.8" - resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.8.tgz#fbd12247b7b1353f88d8de1cbc66bc1a07b2e008" - integrity sha512-/Qc+APf0jbeWSaeEruH0L1/tbbT+sbf884ZL0/zV/0JXaDPBzYkKbyb/wmxMHgAHzm3t6gqe7bOOXAVwfqVikQ== - locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -2717,21 +2785,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.set@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" - integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= - lodash@4.x, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -2975,7 +3033,7 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pbkdf2@^3.0.9, pbkdf2@^3.1.2: +pbkdf2@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== @@ -3075,13 +3133,6 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -randombytes@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" @@ -3165,7 +3216,7 @@ rxjs@^6.6.3: dependencies: tslib "^1.9.0" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -3623,13 +3674,6 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== -xhr2-cookies@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" - integrity sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg= - dependencies: - cookiejar "^2.1.1" - xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" From aa445f6f8163cb6e296de8d3043f315f26718139 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Tue, 1 Nov 2022 16:25:52 +0200 Subject: [PATCH 23/67] upd workflow --- .github/workflows/main.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b6bfaf2..7da2c71 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,9 +6,7 @@ on: - main - develop pull_request: - branches: - - main - - develop + jobs: jest: name: Jest tests From 471e3b436ab88341a27a7b38ef0b2e9809e85058 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Tue, 1 Nov 2022 16:26:13 +0200 Subject: [PATCH 24/67] add check for unclaimed reserves --- contracts/partials/errors.ligo | 1 + contracts/partials/strategy/lambdas.ligo | 11 ++++------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/contracts/partials/errors.ligo b/contracts/partials/errors.ligo index 72c0189..bf8262f 100644 --- a/contracts/partials/errors.ligo +++ b/contracts/partials/errors.ligo @@ -62,4 +62,5 @@ module Strategy is { const out_of_delta_bounds : string = "out-of-delta-bounds"; const no_update_state_entrypoint: string = "no-update-state-EP"; const unknown_token : string = "no-token-strategy-set"; + const unclaimed_reserves : string = "strategy-unclaimed-reserves"; } \ No newline at end of file diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo index 7bf78c6..6f22d66 100644 --- a/contracts/partials/strategy/lambdas.ligo +++ b/contracts/partials/strategy/lambdas.ligo @@ -15,15 +15,12 @@ function connect_strategy( case p of [ | Connect_strategy(params) -> { var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); - function claim_reserves( + function check_reserves( const token_id: token_pool_idx_t; const config : strategy_storage_t) - : strategy_storage_t is - block { - if config.strategy_reserves > 0n - then skip// TODO: claim tokens back - } with config with record[strategy_reserves=0n]; - pool.strategy.configuration := Map.map(claim_reserves, pool.strategy.configuration); + : unit is + require(config.strategy_reserves = 0n, Errors.Strategy.unclaimed_reserves); + Map.iter(check_reserves, pool.strategy.configuration); pool.strategy.strat_contract := params.strategy_contract; s.pools[params.pool_id] := pool; } From 4b9eb30038e037a7cc4e75926bc8dba9f45381f3 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Wed, 2 Nov 2022 16:21:45 +0200 Subject: [PATCH 25/67] Fix tests issues --- config.ts | 2 +- test/00_Dex.test.ts | 6 +++--- test/Dex/cases/pool_part/swap.ts | 22 ++++++++++++---------- test/Dex/cases/views/pool.ts | 2 -- test/Factory/API/factoryAPI.ts | 4 ++-- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/config.ts b/config.ts index 6d6b1a2..cefb471 100644 --- a/config.ts +++ b/config.ts @@ -38,7 +38,7 @@ export const config = { faucet: null, }, mainnet: { - host: "https://mainnet-tezos.giganode.io", + host: "https://mainnet-node.madfish.solutions", port: 443, }, }, diff --git a/test/00_Dex.test.ts b/test/00_Dex.test.ts index 31d56b8..9c50061 100644 --- a/test/00_Dex.test.ts +++ b/test/00_Dex.test.ts @@ -435,8 +435,8 @@ describe("00. Standalone Dex", () => { }); const tokens_map = dex.storage.storage.tokens[pool_id.toNumber()]; const idx_map = mapTokensToIdx(tokens_map, tokens); - const USDtz_amt = amounts.get(idx_map.USDtz); - const in_amt = amounts.set(idx_map.USDtz, new BigNumber(0)); + const USDtz_amt = amounts.get(idx_map.USDtz.toString()); + const in_amt = amounts.set(idx_map.USDtz.toString(), new BigNumber(0)); //min_shares = min_shares.multipliedBy(2).dividedToIntegerBy(3); await TPool.PoolInvest.investLiquiditySuccessCase( dex, @@ -449,7 +449,7 @@ describe("00. Standalone Dex", () => { Tezos ); const USDtz_in = new Map().set( - idx_map.USDtz, + idx_map.USDtz.toString(), USDtz_amt ); //min_shares = min_shares.dividedToIntegerBy(2); diff --git a/test/Dex/cases/pool_part/swap.ts b/test/Dex/cases/pool_part/swap.ts index 2030caa..797c8cc 100644 --- a/test/Dex/cases/pool_part/swap.ts +++ b/test/Dex/cases/pool_part/swap.ts @@ -280,16 +280,18 @@ export async function batchSwap( let min_out = amounts.get(j); min_out = min_out.minus(min_out.multipliedBy(1).div(100)); batch.withContractCall( - dex.contract.methods.swap( - poolId, - i, - j, - amounts.get(i), - min_out, - new BigNumber(exp.getTime()), - null, - ref - ) + dex.contract.methodsObject.swap({ + pool_id: poolId.toString(), + idx_from: i.toString(), + idx_to: j.toString(), + amount: amounts.get(i).toString(), + min_amount_out: min_out.toString(), + deadline: new BigNumber(exp.getTime()) + .dividedToIntegerBy(1000) + .toString(), + receiver: null, + referral: ref, + }) ); } const op = await batch.send(); diff --git a/test/Dex/cases/views/pool.ts b/test/Dex/cases/views/pool.ts index b5769a6..579ac60 100644 --- a/test/Dex/cases/views/pool.ts +++ b/test/Dex/cases/views/pool.ts @@ -37,7 +37,6 @@ export async function getTokenMapSuccessCase( FA12TokenType | FA2TokenType >; value.forEach((value, key) => { - console.error(key, value); if (key.toString() == idx_map.USDtz.toString()) { expect(tokens_map.USDtz.contract.address).toStrictEqual( (value as FA12TokenType).fa12 @@ -47,7 +46,6 @@ export async function getTokenMapSuccessCase( (value as FA12TokenType).fa12 ); } else { - console.error(value) expect(tokens_map.uUSD.contract.address).toStrictEqual( (value as FA2TokenType).fa2.token_address ); diff --git a/test/Factory/API/factoryAPI.ts b/test/Factory/API/factoryAPI.ts index 319e4a7..a085d46 100644 --- a/test/Factory/API/factoryAPI.ts +++ b/test/Factory/API/factoryAPI.ts @@ -95,7 +95,7 @@ export class DexFactory implements DevEnabledContract { // "dev_lambdas", "token_lambdas", "admin_lambdas", - "strat_lambdas" + "strat_lambdas", ].includes(key) ) continue; @@ -123,7 +123,7 @@ export class DexFactory implements DevEnabledContract { // "dev_lambdas", "token_lambdas", "admin_lambdas", - "strat_lambdas" + "strat_lambdas", ].includes(key) ) continue; From 41052268c393745e47e21479380433df9149674a Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Wed, 2 Nov 2022 17:20:39 +0200 Subject: [PATCH 26/67] Update params --- test/Dex/cases/pool_part/swap.ts | 14 +++++++------- test/utils/tokensSetups.ts | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/Dex/cases/pool_part/swap.ts b/test/Dex/cases/pool_part/swap.ts index 797c8cc..4351261 100644 --- a/test/Dex/cases/pool_part/swap.ts +++ b/test/Dex/cases/pool_part/swap.ts @@ -45,8 +45,8 @@ export async function swapSuccessCase( tokens: TokensMap, sender: AccountsLiteral, pool_id: BigNumber, - t_in, - t_to, + t_in: string, + t_to: string, exp: Date, referral: string, idx_map: IndexMap, @@ -82,8 +82,8 @@ export async function swapSuccessCase( : t_out_ep([{ owner: accounts[sender].pkh, token_id: "0" }]) ).read(); - const in_amount = amounts.get(i); - let min_out = amounts.get(j); + const in_amount = amounts.get(i.toString()); + let min_out = amounts.get(j.toString()); min_out = min_out.minus(min_out.multipliedBy(1).div(100)); console.debug( @@ -109,7 +109,7 @@ export async function swapSuccessCase( const upd_reserves = dex.storage.storage.pools[pool_id.toString()].tokens_info; expect(upd_reserves.get(i.toString()).reserves).toStrictEqual( - init_reserves.get(i.toString()).reserves.plus(amounts.get(i)) + init_reserves.get(i.toString()).reserves.plus(amounts.get(i.toString())) ); // Get output from internal transaction @@ -277,14 +277,14 @@ export async function batchSwap( for (const [t_in, t_out] of swap_routes) { const i = map_tokens_idx[t_in]; const j = map_tokens_idx[t_out]; - let min_out = amounts.get(j); + let min_out = amounts.get(j.toString()); min_out = min_out.minus(min_out.multipliedBy(1).div(100)); batch.withContractCall( dex.contract.methodsObject.swap({ pool_id: poolId.toString(), idx_from: i.toString(), idx_to: j.toString(), - amount: amounts.get(i).toString(), + amount: amounts.get(i.toString()).toString(), min_amount_out: min_out.toString(), deadline: new BigNumber(exp.getTime()) .dividedToIntegerBy(1000) diff --git a/test/utils/tokensSetups.ts b/test/utils/tokensSetups.ts index 42fd431..e2c3ff3 100644 --- a/test/utils/tokensSetups.ts +++ b/test/utils/tokensSetups.ts @@ -82,7 +82,7 @@ export async function setupTokenAmounts( if (contract_address) { for (const token in tokens) { if (contract_address == tokens[token].contract.address) { - amounts.set(k, inputs[token]); + amounts.set(k.toString(), inputs[token]); } } } From 1970a599a6f568739735d1094241e4d371eed6aa Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Wed, 2 Nov 2022 17:49:14 +0200 Subject: [PATCH 27/67] [?] add additional sleep --- .github/workflows/main.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7da2c71..ade838b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -38,6 +38,8 @@ jobs: uses: emilioschepis/wait-for-endpoint@v1.0.3 with: url: http://localhost:20000/chains/main/blocks/head + - name: sleep for 10s + run: sleep 10s - name: Test the contracts run: yarn test - name: Stop sandbox From 8f9e06586192d3f5f077b7e7f4ace230ae861967 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 7 Nov 2022 15:48:44 +0200 Subject: [PATCH 28/67] Update helpers to operate with list of tokens --- contracts/partials/strategy/helpers.ligo | 104 ++++++++++------------- contracts/partials/strategy/types.ligo | 8 +- 2 files changed, 50 insertions(+), 62 deletions(-) diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index ae3b1e0..a6fa25e 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -5,7 +5,7 @@ function check_strategy_bounds( const delta_rate_f : nat) : unit is block { - const rate_f = reserves * Constants.precision / desired_reserves; + const rate_f = desired_reserves * Constants.precision / reserves; const in_upper_bound = rate_f < (desired_rate_f + delta_rate_f); const in_lower_bound = rate_f > nat_or_error(desired_rate_f - delta_rate_f, Errors.Math.nat_error); } with require(in_upper_bound and in_lower_bound, Errors.Strategy.out_of_delta_bounds) @@ -35,66 +35,52 @@ function calculate_desired_reserves( Errors.Strategy.no_update_state_entrypoint ); -function update_strategy_reserves( - const token_pool_id : token_pool_idx_t; - const token : token_t; - const old_s_reserves : nat; - const new_s_reserves : nat; - const strat_contract : address) - : list(operation) is - block { - const upd_state_param : upd_strat_state_t = record[ - pool_token_id = token_pool_id; - new_balance = new_s_reserves - ]; - var before_ops := Constants.no_operations; - var after_ops := Constants.no_operations; - case is_nat(new_s_reserves - old_s_reserves) of [ - Some(value) -> { - if value > 0n - then { - // send additional reserves to Yupana through Strategy - before_ops := typed_transfer( - Tezos.self_address(unit), - strat_contract, - nat_or_error(new_s_reserves - old_s_reserves, Errors.Math.nat_error), - token - ) # before_ops; - } - } - | None -> { // means that old_s_reserves > new_s_reserves, waiting for refiling from Strategy - // TODO: make lock flag before receiving tokens from strategy - after_ops := Constants.no_operations; - } - ]; - const ops = concat_lists( - Tezos.transaction( - upd_state_param, - 0mutez, - get_update_state_entrypoint(strat_contract) - ) # before_ops, - after_ops - ) - } with ops function operate_with_strategy( - const token_pool_id : token_pool_idx_t; - const token : token_t; - const reserves : nat; - const strategy_address: address; - var strategy : strategy_storage_t) - : list(operation) * strategy_storage_t is + const token_infos : map(token_pool_idx_t, token_info_t); + const tokens_map_entry: option(tokens_map_t); + var strategy : strategy_full_storage_t) + : list(operation) * strategy_full_storage_t is block { var ops := Constants.no_operations; - if strategy.is_rebalance then { - const new_s_reserves = calculate_desired_reserves(reserves, strategy); - ops := update_strategy_reserves( - token_pool_id, - token, - strategy.strategy_reserves, - new_s_reserves, - strategy_address - ); - strategy.strategy_reserves := new_s_reserves; - } + case strategy.strat_contract of [ + Some(contract) -> { + var rebalance_params: upd_strat_state_t = nil; + var send_ops: list(operation) = nil; + for token_id -> info in map token_infos { + const config = unwrap(strategy.configuration[token_id], Errors.Strategy.unknown_token); + if config.is_rebalance then { + const new_s_reserves = calculate_desired_reserves(info.reserves, config); + rebalance_params := record[ + pool_token_id = token_id; + new_balance = new_s_reserves + ] # rebalance_params; + case is_nat(new_s_reserves - config.strategy_reserves) of [ + | Some(value) -> { + // send additional reserves to Yupana through Strategy + if value > 0n + then send_ops := typed_transfer( + Tezos.self_address(), + contract, + value, + token + ) # send_ops; + } + _ -> skip + ]; + config.strategy_reserves := new_s_reserves; + } + strategy.configuration[token_id] := config; + } + ops := concat_lists( + send_ops, + Tezos.transaction( + rebalance_params, + 0mutez, + get_update_state_entrypoint(contract) + ) # ops + ); + } + | None -> skip + ] } with (ops, strategy) \ No newline at end of file diff --git a/contracts/partials/strategy/types.ligo b/contracts/partials/strategy/types.ligo index 8fee960..85b583d 100644 --- a/contracts/partials/strategy/types.ligo +++ b/contracts/partials/strategy/types.ligo @@ -36,14 +36,16 @@ type tok_strat_upd_fl_param is [@layout:comb] record [ flag : bool; ] -type upd_strat_state_t is [@layout:comb] record [ +type upd_state_prm is [@layout:comb] record [ pool_token_id : nat; new_balance : nat; ] +type upd_strat_state_t is list(upd_state_prm) + type rebalance_param is [@layout:comb] record [ pool_id : pool_id_t; - pool_token_id : nat; + pool_token_id : Set(nat); ] type strat_upd_info_t is [@layout:comb] record [ @@ -58,4 +60,4 @@ type strategy_action_t is | Connect_token_strategy of conn_tok_strat_param | Set_token_strategy of set_tok_strat_param | Set_token_strategy_rebalance of tok_strat_upd_fl_param -| Rebalance of rebalance_param \ No newline at end of file +| Rebalance of list(rebalance_param) \ No newline at end of file From 613109a59a89a2afdf6f09dec23f519f8c71b9bd Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 7 Nov 2022 15:56:50 +0200 Subject: [PATCH 29/67] fix mistypes --- contracts/partials/strategy/helpers.ligo | 16 ++++++++-------- contracts/partials/strategy/types.ligo | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index a6fa25e..f2dcd51 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -45,10 +45,10 @@ function operate_with_strategy( var ops := Constants.no_operations; case strategy.strat_contract of [ Some(contract) -> { - var rebalance_params: upd_strat_state_t = nil; - var send_ops: list(operation) = nil; + var rebalance_params: upd_strat_state_t := nil; + var send_ops: list(operation) := nil; for token_id -> info in map token_infos { - const config = unwrap(strategy.configuration[token_id], Errors.Strategy.unknown_token); + var config := unwrap(strategy.configuration[token_id], Errors.Strategy.unknown_token); if config.is_rebalance then { const new_s_reserves = calculate_desired_reserves(info.reserves, config); rebalance_params := record[ @@ -60,18 +60,18 @@ function operate_with_strategy( // send additional reserves to Yupana through Strategy if value > 0n then send_ops := typed_transfer( - Tezos.self_address(), + Tezos.self_address(unit), contract, value, - token + get_token_by_id(token_id, tokens_map_entry) ) # send_ops; } - _ -> skip + | _ -> skip ]; config.strategy_reserves := new_s_reserves; - } + }; strategy.configuration[token_id] := config; - } + }; ops := concat_lists( send_ops, Tezos.transaction( diff --git a/contracts/partials/strategy/types.ligo b/contracts/partials/strategy/types.ligo index 85b583d..384e1a7 100644 --- a/contracts/partials/strategy/types.ligo +++ b/contracts/partials/strategy/types.ligo @@ -45,7 +45,7 @@ type upd_strat_state_t is list(upd_state_prm) type rebalance_param is [@layout:comb] record [ pool_id : pool_id_t; - pool_token_id : Set(nat); + pool_token_id : set(nat); ] type strat_upd_info_t is [@layout:comb] record [ From 99352a067d5cd8ff03b36ff6b94e8e0d2b551554 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 7 Nov 2022 16:55:54 +0200 Subject: [PATCH 30/67] Temporary comment rebalance failcase --- contracts/compiled/dex4factory.tz | 4 ++-- test/00_Dex.test.ts | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/compiled/dex4factory.tz b/contracts/compiled/dex4factory.tz index 2526b7c..d6351a5 100644 --- a/contracts/compiled/dex4factory.tz +++ b/contracts/compiled/dex4factory.tz @@ -16,7 +16,7 @@ (nat %pool_id) (nat %pool_token_id) (nat %lending_market_id))) - (or (pair %rebalance (nat %pool_id) (nat %pool_token_id)) + (or (list %rebalance (pair (nat %pool_id) (set %pool_token_id nat))) (pair %set_token_strategy (nat %pool_id) (nat %pool_token_id) @@ -416,7 +416,7 @@ (nat %pool_id) (nat %pool_token_id) (nat %lending_market_id))) - (or (pair %rebalance (nat %pool_id) (nat %pool_token_id)) + (or (list %rebalance (pair (nat %pool_id) (set %pool_token_id nat))) (pair %set_token_strategy (nat %pool_id) (nat %pool_token_id) diff --git a/test/00_Dex.test.ts b/test/00_Dex.test.ts index 9c50061..9fb364a 100644 --- a/test/00_Dex.test.ts +++ b/test/00_Dex.test.ts @@ -1076,11 +1076,11 @@ describe("00. Standalone Dex", () => { ), "not-developer" ); - await failCase( - "eve", - async () => await dex.rebalance(pool_id, pool_token_id), - "not-developer" - ); + // await failCase( + // "eve", + // async () => await dex.rebalance([{pool_id, [pool_token_id]}]), + // "not-developer" + // ); }); }); }); From ed61d88ca5745ba8cf0d3d2aad5a3a6cef849d85 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 11 Nov 2022 14:38:41 +0200 Subject: [PATCH 31/67] Fix comments --- contracts/partials/errors.ligo | 1 + contracts/partials/factory/helpers.ligo | 3 +- contracts/partials/factory/lambdas.ligo | 1 - contracts/partials/factory/storage.ligo | 1 - contracts/partials/strategy/helpers.ligo | 43 +++++++++++++++--------- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/contracts/partials/errors.ligo b/contracts/partials/errors.ligo index bf8262f..d2597c9 100644 --- a/contracts/partials/errors.ligo +++ b/contracts/partials/errors.ligo @@ -61,6 +61,7 @@ module Factory is { module Strategy is { const out_of_delta_bounds : string = "out-of-delta-bounds"; const no_update_state_entrypoint: string = "no-update-state-EP"; + const no_prepare_entrypoint : string = "no-prepare-EP"; const unknown_token : string = "no-token-strategy-set"; const unclaimed_reserves : string = "strategy-unclaimed-reserves"; } \ No newline at end of file diff --git a/contracts/partials/factory/helpers.ligo b/contracts/partials/factory/helpers.ligo index 1ddbc27..a7e53ed 100644 --- a/contracts/partials/factory/helpers.ligo +++ b/contracts/partials/factory/helpers.ligo @@ -114,7 +114,6 @@ function form_pool_storage( const tokens_info : map(token_pool_idx_t, token_info_t); const a_constant : nat; const fees : fees_storage_t; - const strategy : option(address); const default_referral: address; const managers : set(address); const quipu_token : fa2_token_t; @@ -132,7 +131,7 @@ function form_pool_storage( tokens_info = tokens_info; fee = fees; strategy = record[ - strat_contract = strategy; + strat_contract = (None: option(address)); configuration = (map[]: map(token_pool_idx_t, strategy_storage_t)); ]; staker_accumulator = record [ diff --git a/contracts/partials/factory/lambdas.ligo b/contracts/partials/factory/lambdas.ligo index ad148b7..bbfe5db 100644 --- a/contracts/partials/factory/lambdas.ligo +++ b/contracts/partials/factory/lambdas.ligo @@ -45,7 +45,6 @@ function add_pool( tokens_info, params.a_constant, params.fees, - params.strategy, params.default_referral, params.managers, s.storage.quipu_token, diff --git a/contracts/partials/factory/storage.ligo b/contracts/partials/factory/storage.ligo index 5bd984a..d1ebc48 100644 --- a/contracts/partials/factory/storage.ligo +++ b/contracts/partials/factory/storage.ligo @@ -24,7 +24,6 @@ type pool_init_param_t is [@layout:comb] record [ default_referral : address; managers : set(address); fees : fees_storage_t; - strategy : option(address); ] type inner_store_t is [@layout:comb] record[ diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index f2dcd51..5167dca 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -1,14 +1,12 @@ function check_strategy_bounds( const reserves : nat; - const desired_reserves: nat; + const virtual_reserves: nat; const desired_rate_f : nat; const delta_rate_f : nat) - : unit is + : bool is block { - const rate_f = desired_reserves * Constants.precision / reserves; - const in_upper_bound = rate_f < (desired_rate_f + delta_rate_f); - const in_lower_bound = rate_f > nat_or_error(desired_rate_f - delta_rate_f, Errors.Math.nat_error); - } with require(in_upper_bound and in_lower_bound, Errors.Strategy.out_of_delta_bounds) + const rate_f = virtual_reserves * Constants.precision / reserves; + } with abs(rate_f - desired_rate_f) < delta_rate_f function calculate_desired_reserves( const reserves : nat; @@ -16,17 +14,24 @@ function calculate_desired_reserves( : nat is block { const desired_reserves : nat = reserves * strat_token_conf.des_reserves_rate_f / Constants.precision; - check_strategy_bounds( + require(check_strategy_bounds( reserves, desired_reserves, strat_token_conf.des_reserves_rate_f, strat_token_conf.delta_rate_f - ); + ), Errors.Strategy.out_of_delta_bounds); } with if desired_reserves > strat_token_conf.min_invest then desired_reserves else 0n -(* Helper function to get mint lending contract entrypoint *) +[@inline] function get_prepare_entrypoint( + const strategy_address: address) + : contract(list(nat)) is + unwrap( + (Tezos.get_entrypoint_opt("%prepare", strategy_address): option(contract(list(nat)))), + Errors.Strategy.no_prepare_entrypoint + ); + [@inline] function get_update_state_entrypoint( const strategy_address: address) : contract(upd_strat_state_t) is @@ -46,15 +51,23 @@ function operate_with_strategy( case strategy.strat_contract of [ Some(contract) -> { var rebalance_params: upd_strat_state_t := nil; + var prepare_params: list(nat) := nil; var send_ops: list(operation) := nil; for token_id -> info in map token_infos { var config := unwrap(strategy.configuration[token_id], Errors.Strategy.unknown_token); - if config.is_rebalance then { + const need_rebalance = check_strategy_bounds( + info.reserves, + config.strategy_reserves, + config.des_reserves_rate_f, + config.delta_rate_f + ); + if config.is_rebalance and need_rebalance then { const new_s_reserves = calculate_desired_reserves(info.reserves, config); rebalance_params := record[ pool_token_id = token_id; new_balance = new_s_reserves ] # rebalance_params; + prepare_params := token_id # prepare_params; case is_nat(new_s_reserves - config.strategy_reserves) of [ | Some(value) -> { // send additional reserves to Yupana through Strategy @@ -72,13 +85,13 @@ function operate_with_strategy( }; strategy.configuration[token_id] := config; }; + ops := [ + Tezos.transaction(prepare_params, 0mutez, get_prepare_entrypoint(contract)), + Tezos.transaction(rebalance_params, 0mutez, get_update_state_entrypoint(contract)) + ]; ops := concat_lists( send_ops, - Tezos.transaction( - rebalance_params, - 0mutez, - get_update_state_entrypoint(contract) - ) # ops + ops ); } | None -> skip From b9e3596e5b0ec3cf2e83548dfb67654ac3e5c357 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 11 Nov 2022 14:42:47 +0200 Subject: [PATCH 32/67] expr fix --- contracts/partials/strategy/helpers.ligo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index 5167dca..23d1ce9 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -85,8 +85,8 @@ function operate_with_strategy( }; strategy.configuration[token_id] := config; }; - ops := [ - Tezos.transaction(prepare_params, 0mutez, get_prepare_entrypoint(contract)), + ops := list [ + Tezos.transaction(prepare_params, 0mutez, get_prepare_entrypoint(contract)); Tezos.transaction(rebalance_params, 0mutez, get_update_state_entrypoint(contract)) ]; ops := concat_lists( From 9bf549ec208f381184a204e105e520d9f1257981 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 11 Nov 2022 16:36:27 +0200 Subject: [PATCH 33/67] Add view and check for registered strategy --- .../partials/dex_core/factory/helpers.ligo | 5 +++++ .../partials/dex_core/standalone/helpers.ligo | 5 +++++ contracts/partials/dex_core/storage.ligo | 1 + contracts/partials/errors.ligo | 3 +++ contracts/partials/factory/methods.ligo | 17 +++++++++-------- contracts/partials/factory/storage.ligo | 2 ++ contracts/partials/factory/views.ligo | 6 ++++++ contracts/partials/strategy/helpers.ligo | 7 +++++++ contracts/partials/strategy/lambdas.ligo | 9 ++++++++- storage/factory.ts | 1 + test/Factory/API/storage.ts | 1 + test/Factory/cases/before.ts | 8 +------- 12 files changed, 49 insertions(+), 16 deletions(-) diff --git a/contracts/partials/dex_core/factory/helpers.ligo b/contracts/partials/dex_core/factory/helpers.ligo index c1314c0..922e0d5 100644 --- a/contracts/partials/dex_core/factory/helpers.ligo +++ b/contracts/partials/dex_core/factory/helpers.ligo @@ -3,6 +3,11 @@ function get_dev_fee( : nat is unwrap((Tezos.call_view("dev_fee", Unit, s.factory_address): option(nat)), Errors.Factory.no_fee) +function get_strategy_factory( + const s : storage_t) + : address is + unwrap((Tezos.call_view("strategy_factory_address", Unit, s.factory_address): option(address)), Errors.Factory.no_strategy_factory) + function get_dev_address( const s : storage_t) : address is diff --git a/contracts/partials/dex_core/standalone/helpers.ligo b/contracts/partials/dex_core/standalone/helpers.ligo index d36cc00..b384a6e 100644 --- a/contracts/partials/dex_core/standalone/helpers.ligo +++ b/contracts/partials/dex_core/standalone/helpers.ligo @@ -7,3 +7,8 @@ function get_dev_address( const s : storage_t) : address is s.dev_store.dev_address + +function get_strategy_factory( + const s : storage_t) + : address is + s.strategy_factory diff --git a/contracts/partials/dex_core/storage.ligo b/contracts/partials/dex_core/storage.ligo index 20c7deb..7bd91de 100644 --- a/contracts/partials/dex_core/storage.ligo +++ b/contracts/partials/dex_core/storage.ligo @@ -85,6 +85,7 @@ type storage_t is [@layout:comb] record [ factory_address : address; started : bool; #else + strategy_factory : address; dev_store : dev_storage_t; #endif ] diff --git a/contracts/partials/errors.ligo b/contracts/partials/errors.ligo index d2597c9..bc8ad78 100644 --- a/contracts/partials/errors.ligo +++ b/contracts/partials/errors.ligo @@ -56,11 +56,14 @@ module Factory is { const not_deployer : string = "not-deployer-of-pool"; const not_dex : string = "not-dex"; const burn_rate_overflow : string = "burn-rate-overflow"; + const no_strategy_factory : string = "no-strategy-factory-view"; } module Strategy is { const out_of_delta_bounds : string = "out-of-delta-bounds"; const no_update_state_entrypoint: string = "no-update-state-EP"; + const not_registered : string = "strategy-not-registered-on-factory"; + const no_is_registered : string = "no-is-registered-view"; const no_prepare_entrypoint : string = "no-prepare-EP"; const unknown_token : string = "no-token-strategy-set"; const unclaimed_reserves : string = "strategy-unclaimed-reserves"; diff --git a/contracts/partials/factory/methods.ligo b/contracts/partials/factory/methods.ligo index ecbaef4..9951723 100644 --- a/contracts/partials/factory/methods.ligo +++ b/contracts/partials/factory/methods.ligo @@ -95,14 +95,15 @@ function use_factory( block { require(Tezos.sender = s.storage.dev_store.dev_address, Errors.Dex.not_developer); case params of [ - | Set_burn_rate(rate) -> if rate <= Constants.burn_rate_precision - then s.storage.burn_rate_f := rate - else failwith(Errors.Factory.burn_rate_overflow) - | Set_price(price) -> s.storage.init_price := price - | Set_whitelist(params) -> s.storage.whitelist := add_rem_candidate(params, s.storage.whitelist) - | _ -> skip + | Set_burn_rate(rate) -> if rate <= Constants.burn_rate_precision + then s.storage.burn_rate_f := rate + else failwith(Errors.Factory.burn_rate_overflow) + | Set_strategy_factory(addr) -> s.storage.strategy_factory := addr + | Set_price(price) -> s.storage.init_price := price + | Set_whitelist(params) -> s.storage.whitelist := add_rem_candidate(params, s.storage.whitelist) + | _ -> skip ] } with case params of [ - | Claim_rewards -> claim_quipu(s) - | _ -> (Constants.no_operations, s) + | Claim_rewards -> claim_quipu(s) + | _ -> (Constants.no_operations, s) ] diff --git a/contracts/partials/factory/storage.ligo b/contracts/partials/factory/storage.ligo index d1ebc48..50852ac 100644 --- a/contracts/partials/factory/storage.ligo +++ b/contracts/partials/factory/storage.ligo @@ -36,6 +36,7 @@ type inner_store_t is [@layout:comb] record[ quipu_token : fa2_token_t; quipu_rewards : nat; whitelist : set(address); + strategy_factory : address; ] type full_storage_t is [@layout:comb] record [ @@ -50,6 +51,7 @@ type full_storage_t is [@layout:comb] record [ type use_factory_t is | Set_whitelist of set_man_param_t +| Set_strategy_factory of address | Set_burn_rate of nat | Set_price of nat | Claim_rewards of unit diff --git a/contracts/partials/factory/views.ligo b/contracts/partials/factory/views.ligo index 23ed6c8..3e7adbb 100644 --- a/contracts/partials/factory/views.ligo +++ b/contracts/partials/factory/views.ligo @@ -10,6 +10,12 @@ : address is s.storage.dev_store.dev_address +[@view] function strategy_factory_address( + const _ : unit; + const s : full_storage_t) + : address is + s.storage.strategy_factory + [@view] function get_pool( const params : record [ tokens:set(token_t); deployer:address ]; const s : full_storage_t) diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index 23d1ce9..661ac3d 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -41,6 +41,13 @@ function calculate_desired_reserves( ); +[@inline] function get_is_registered( + const strategy_address: address; + const factory_address : address) + : bool is + unwrap((Tezos.call_view("is_registered", strategy_address, factory_address): option(bool)), Errors.Strategy.no_is_registered) + + function operate_with_strategy( const token_infos : map(token_pool_idx_t, token_info_t); const tokens_map_entry: option(tokens_map_t); diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo index 6f22d66..8d96689 100644 --- a/contracts/partials/strategy/lambdas.ligo +++ b/contracts/partials/strategy/lambdas.ligo @@ -21,7 +21,14 @@ function connect_strategy( : unit is require(config.strategy_reserves = 0n, Errors.Strategy.unclaimed_reserves); Map.iter(check_reserves, pool.strategy.configuration); - pool.strategy.strat_contract := params.strategy_contract; + pool.strategy.strat_contract := case params.strategy_contract of [ + | Some(addr) -> { + const strategy_factory = get_strategy_factory(s); + const is_registered_strategy = get_is_registered(addr, strategy_factory); + require(is_registered_strategy, Errors.Strategy.not_registered); + } with params.strategy_contract + | None -> params.strategy_contract + ]; s.pools[params.pool_id] := pool; } | _ -> unreachable(Unit) diff --git a/storage/factory.ts b/storage/factory.ts index 38960c1..c3d94e7 100644 --- a/storage/factory.ts +++ b/storage/factory.ts @@ -47,6 +47,7 @@ const factoryDefaultStorage: FactoryStorage = { quipu_rewards: new BigNumber("0"), whitelist: [] as TezosAddress[], deployers: new MichelsonMap(), + strategy_factory: "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg", } as InnerFactoryStore, admin_lambdas: new MichelsonMap(), dex_lambdas: new MichelsonMap(), diff --git a/test/Factory/API/storage.ts b/test/Factory/API/storage.ts index b4cd80d..15af417 100644 --- a/test/Factory/API/storage.ts +++ b/test/Factory/API/storage.ts @@ -20,6 +20,7 @@ export const factory_storage: FactoryStorage = { quipu_rewards: new BigNumber(0), whitelist: [] as TezosAddress[], deployers: new MichelsonMap(), + strategy_factory: "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg", } as InnerFactoryStore, admin_lambdas: new MichelsonMap(), dex_lambdas: new MichelsonMap(), diff --git a/test/Factory/cases/before.ts b/test/Factory/cases/before.ts index 2bf73ab..4bbef6c 100644 --- a/test/Factory/cases/before.ts +++ b/test/Factory/cases/before.ts @@ -29,15 +29,9 @@ export async function setupFactoryEnvironment( factory: DexFactory; // tokens: TokensMap; quipuToken: TokenFA2; - lambdaContractAddress: string; }> { const config = await prepareProviderOptions(developer); Tezos.setProvider(config); - const op = await Tezos.contract.originate({ - code: VIEW_LAMBDA.code, - storage: VIEW_LAMBDA.storage, - }); - await op.confirmation(2); const quipuToken = await setupQuipuGovToken(Tezos); const lambdaContractAddress = op.contractAddress; storage.storage.dev_store = { @@ -65,5 +59,5 @@ export async function setupFactoryEnvironment( chalk.bold.underline(fact_op.contractAddress) ); const factory = await DexFactory.init(Tezos, fact_op.contractAddress); - return { factory, quipuToken, lambdaContractAddress }; + return { factory, quipuToken }; } From 3ce82ae875862314dd4755a507aed7d8ba2f9e41 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Tue, 15 Nov 2022 15:45:05 +0200 Subject: [PATCH 34/67] Preparation for multiple strategies and register flow --- contracts/partials/admin/methods.ligo | 2 ++ .../partials/admin/standalone/lambdas.ligo | 16 ++++++++++++++++ contracts/partials/constants.ligo | 2 +- .../partials/dex_core/factory/helpers.ligo | 7 ++++--- .../partials/dex_core/standalone/helpers.ligo | 14 +++++++++++--- contracts/partials/dex_core/storage.ligo | 2 +- contracts/partials/errors.ligo | 2 ++ contracts/partials/factory/methods.ligo | 2 +- contracts/partials/factory/storage.ligo | 2 +- contracts/partials/factory/views.ligo | 18 +++++++++++++----- contracts/partials/strategy/helpers.ligo | 18 +++++++++++++----- contracts/partials/strategy/lambdas.ligo | 5 +++-- contracts/partials/strategy/types.ligo | 5 +++++ test/lambdas/Admin_lambdas.json | 4 ++++ 14 files changed, 77 insertions(+), 22 deletions(-) diff --git a/contracts/partials/admin/methods.ligo b/contracts/partials/admin/methods.ligo index ee115f2..f68becf 100644 --- a/contracts/partials/admin/methods.ligo +++ b/contracts/partials/admin/methods.ligo @@ -10,6 +10,7 @@ case p of [ | Claim_developer(_) -> skip // Claim_developer has own inner check for developer address + | Set_strategy_factory(_)-> skip | _ -> require(Tezos.sender = s.storage.admin, Errors.Dex.not_contract_admin) ]; @@ -24,6 +25,7 @@ | Set_default_referral(_) -> 6n #if !FACTORY | Add_pool(_) -> 7n + | Set_strategy_factory(_) -> 8n #endif ]; diff --git a/contracts/partials/admin/standalone/lambdas.ligo b/contracts/partials/admin/standalone/lambdas.ligo index 652d3c0..cbb4ccf 100644 --- a/contracts/partials/admin/standalone/lambdas.ligo +++ b/contracts/partials/admin/standalone/lambdas.ligo @@ -80,3 +80,19 @@ function add_pool( | _ -> unreachable(Unit) ] } with (operations, s) + +function set_strategy_factory( + const params : admin_action_t; + var s : storage_t) + : return_t is + block { + var operations: list(operation) := Constants.no_operations; + case p of [ + | Set_strategy_factory(params) -> { + const dev_address = get_dev_address(s); + require(Tezos.sender = dev_address, Errors.Dex.not_developer); + s.strategy_factory = add_rem_candidate(params, s.storage.strategy_factory); + } + | _ -> unreachable(Unit) + ] + } with (operations, s) diff --git a/contracts/partials/constants.ligo b/contracts/partials/constants.ligo index 80cde6d..2cb5d63 100644 --- a/contracts/partials/constants.ligo +++ b/contracts/partials/constants.ligo @@ -6,7 +6,7 @@ const dev_func_count : nat = 2n; const token_func_count : nat = 5n; const strat_func_count : nat = 5n; #if !FACTORY -const admin_func_count : nat = 8n; +const admin_func_count : nat = 9n; #else const admin_func_count : nat = 7n; #endif diff --git a/contracts/partials/dex_core/factory/helpers.ligo b/contracts/partials/dex_core/factory/helpers.ligo index 922e0d5..e9014a8 100644 --- a/contracts/partials/dex_core/factory/helpers.ligo +++ b/contracts/partials/dex_core/factory/helpers.ligo @@ -3,10 +3,11 @@ function get_dev_fee( : nat is unwrap((Tezos.call_view("dev_fee", Unit, s.factory_address): option(nat)), Errors.Factory.no_fee) -function get_strategy_factory( +function check_is_registered_strategy( + const strategy : address; const s : storage_t) - : address is - unwrap((Tezos.call_view("strategy_factory_address", Unit, s.factory_address): option(address)), Errors.Factory.no_strategy_factory) + : bool is + unwrap((Tezos.call_view("is_registered_strategy", strategy, s.factory_address): option(bool)), Errors.Factory.no_strategy_factory) function get_dev_address( const s : storage_t) diff --git a/contracts/partials/dex_core/standalone/helpers.ligo b/contracts/partials/dex_core/standalone/helpers.ligo index b384a6e..982b0ae 100644 --- a/contracts/partials/dex_core/standalone/helpers.ligo +++ b/contracts/partials/dex_core/standalone/helpers.ligo @@ -8,7 +8,15 @@ function get_dev_address( : address is s.dev_store.dev_address -function get_strategy_factory( +function check_is_registered_strategy( + const strategy : address; const s : storage_t) - : address is - s.strategy_factory + : bool is + block { + function check_strategy_factory(const accumulator: bool; const entry: address): bool is + accumulator or unwrap( + (Tezos.call_view("is_registered", strategy, entry): option(bool)), + Errors.Factory.no_strategy_factory + ) + } with Set.fold(check_strategy_factory, s.strategy_factory, False) + diff --git a/contracts/partials/dex_core/storage.ligo b/contracts/partials/dex_core/storage.ligo index 7bd91de..54c6982 100644 --- a/contracts/partials/dex_core/storage.ligo +++ b/contracts/partials/dex_core/storage.ligo @@ -85,7 +85,7 @@ type storage_t is [@layout:comb] record [ factory_address : address; started : bool; #else - strategy_factory : address; + strategy_factory : set(address); dev_store : dev_storage_t; #endif ] diff --git a/contracts/partials/errors.ligo b/contracts/partials/errors.ligo index bc8ad78..839da0a 100644 --- a/contracts/partials/errors.ligo +++ b/contracts/partials/errors.ligo @@ -67,4 +67,6 @@ module Strategy is { const no_prepare_entrypoint : string = "no-prepare-EP"; const unknown_token : string = "no-token-strategy-set"; const unclaimed_reserves : string = "strategy-unclaimed-reserves"; + const no_pool_data_view : string = "no-pool-data-view"; + const wrong_params : string = "wrong-connect-params-strategy" } \ No newline at end of file diff --git a/contracts/partials/factory/methods.ligo b/contracts/partials/factory/methods.ligo index 9951723..bfcfc77 100644 --- a/contracts/partials/factory/methods.ligo +++ b/contracts/partials/factory/methods.ligo @@ -98,7 +98,7 @@ function use_factory( | Set_burn_rate(rate) -> if rate <= Constants.burn_rate_precision then s.storage.burn_rate_f := rate else failwith(Errors.Factory.burn_rate_overflow) - | Set_strategy_factory(addr) -> s.storage.strategy_factory := addr + | Set_strategy_factory(params)-> s.storage.strategy_factory := add_rem_candidate(params, s.storage.strategy_factory) | Set_price(price) -> s.storage.init_price := price | Set_whitelist(params) -> s.storage.whitelist := add_rem_candidate(params, s.storage.whitelist) | _ -> skip diff --git a/contracts/partials/factory/storage.ligo b/contracts/partials/factory/storage.ligo index 50852ac..59fd69c 100644 --- a/contracts/partials/factory/storage.ligo +++ b/contracts/partials/factory/storage.ligo @@ -36,7 +36,7 @@ type inner_store_t is [@layout:comb] record[ quipu_token : fa2_token_t; quipu_rewards : nat; whitelist : set(address); - strategy_factory : address; + strategy_factory : set(address); ] type full_storage_t is [@layout:comb] record [ diff --git a/contracts/partials/factory/views.ligo b/contracts/partials/factory/views.ligo index 3e7adbb..2c33b03 100644 --- a/contracts/partials/factory/views.ligo +++ b/contracts/partials/factory/views.ligo @@ -10,11 +10,19 @@ : address is s.storage.dev_store.dev_address -[@view] function strategy_factory_address( - const _ : unit; - const s : full_storage_t) - : address is - s.storage.strategy_factory +[@view] function is_registered_strategy( + const strategy : address; + const s : storage_t) + : bool is + block { + function check_strategy_factory(const accumulator: bool; const entry: address): bool is + accumulator or unwrap( + (Tezos.call_view("is_registered", strategy, entry): option(bool)), + Errors.Factory.no_strategy_factory + ) + } with Set.fold(check_strategy_factory, s.strategy_factory, False) + + [@view] function get_pool( const params : record [ tokens:set(token_t); deployer:address ]; diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index 661ac3d..6c7f0d9 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -40,12 +40,20 @@ function calculate_desired_reserves( Errors.Strategy.no_update_state_entrypoint ); +function check_strategy_pool_params( + const pool_id : nat; + const strategy: address): bool is + block { + const expected: strat_pool_data_t = record[ + pool_contract = Tezos.get_self_address(); + pool_id = pool_id + ]; + const reponse: strat_pool_data_t = unwrap( + (Tezos.call_view("get_pool_data", Unit, strategy): option(strat_pool_data_t)), + Errors.Strategy.wrong_params + ); + } with response = expected -[@inline] function get_is_registered( - const strategy_address: address; - const factory_address : address) - : bool is - unwrap((Tezos.call_view("is_registered", strategy_address, factory_address): option(bool)), Errors.Strategy.no_is_registered) function operate_with_strategy( diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo index 8d96689..29f9de6 100644 --- a/contracts/partials/strategy/lambdas.ligo +++ b/contracts/partials/strategy/lambdas.ligo @@ -23,9 +23,10 @@ function connect_strategy( Map.iter(check_reserves, pool.strategy.configuration); pool.strategy.strat_contract := case params.strategy_contract of [ | Some(addr) -> { - const strategy_factory = get_strategy_factory(s); - const is_registered_strategy = get_is_registered(addr, strategy_factory); + const is_registered_strategy = check_is_registered_strategy(addr, s); + const is_pool_params_correct = check_strategy_pool_params(params.pool_id, addr); require(is_registered_strategy, Errors.Strategy.not_registered); + require(is_pool_params_correct, Errors.Strategy.wrong_params); } with params.strategy_contract | None -> params.strategy_contract ]; diff --git a/contracts/partials/strategy/types.ligo b/contracts/partials/strategy/types.ligo index 384e1a7..230a7be 100644 --- a/contracts/partials/strategy/types.ligo +++ b/contracts/partials/strategy/types.ligo @@ -11,6 +11,11 @@ type strategy_full_storage_t is [@layout:comb] record [ configuration : map(token_pool_idx_t, strategy_storage_t) ] +type strat_pool_data_t is [@layout:comb] record[ + pool_contract: address; + pool_id: nat; +] + type conn_strategy_param is [@layout:comb] record [ pool_id : pool_id_t; strategy_contract : option(address); diff --git a/test/lambdas/Admin_lambdas.json b/test/lambdas/Admin_lambdas.json index 8c8fbec..fb8d7e5 100644 --- a/test/lambdas/Admin_lambdas.json +++ b/test/lambdas/Admin_lambdas.json @@ -30,5 +30,9 @@ { "index": 7, "name": "add_pool" + }, + { + "index": 8, + "name": "set_strategy_factory" } ] From 9ead4d5312d120182c4746012d46e29c4137931a Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 18 Nov 2022 17:26:52 +0200 Subject: [PATCH 35/67] Add manual rebalance --- .../partials/admin/standalone/lambdas.ligo | 4 ++-- contracts/partials/admin/types.ligo | 5 ++-- contracts/partials/factory/storage.ligo | 4 ++-- contracts/partials/strategy/helpers.ligo | 8 +++---- contracts/partials/strategy/lambdas.ligo | 23 +++++++++++++++---- contracts/partials/strategy/types.ligo | 4 ++-- contracts/partials/utils.ligo | 2 +- 7 files changed, 32 insertions(+), 18 deletions(-) diff --git a/contracts/partials/admin/standalone/lambdas.ligo b/contracts/partials/admin/standalone/lambdas.ligo index cbb4ccf..1c94bdd 100644 --- a/contracts/partials/admin/standalone/lambdas.ligo +++ b/contracts/partials/admin/standalone/lambdas.ligo @@ -82,7 +82,7 @@ function add_pool( } with (operations, s) function set_strategy_factory( - const params : admin_action_t; + const p : admin_action_t; var s : storage_t) : return_t is block { @@ -91,7 +91,7 @@ function set_strategy_factory( | Set_strategy_factory(params) -> { const dev_address = get_dev_address(s); require(Tezos.sender = dev_address, Errors.Dex.not_developer); - s.strategy_factory = add_rem_candidate(params, s.storage.strategy_factory); + s.strategy_factory := add_rem_candidate(params, s.strategy_factory); } | _ -> unreachable(Unit) ] diff --git a/contracts/partials/admin/types.ligo b/contracts/partials/admin/types.ligo index 107afea..5e0c73b 100644 --- a/contracts/partials/admin/types.ligo +++ b/contracts/partials/admin/types.ligo @@ -1,4 +1,4 @@ -type set_man_param_t is [@layout:comb] record [ +type set_cand_param_t is [@layout:comb] record [ add : bool; candidate : address; ] @@ -24,7 +24,7 @@ type init_param_t is [@layout:comb] record [ #endif type admin_action_t is -| Add_rem_managers of set_man_param_t +| Add_rem_managers of set_cand_param_t | Set_admin of address | Claim_developer of claim_by_token_param_t | Ramp_A of ramp_a_param_t @@ -33,4 +33,5 @@ type admin_action_t is | Set_default_referral of address #if !FACTORY | Add_pool of init_param_t (* sets initial liquidity *) +| Set_strategy_factory of set_cand_param_t #endif diff --git a/contracts/partials/factory/storage.ligo b/contracts/partials/factory/storage.ligo index 59fd69c..ffb2016 100644 --- a/contracts/partials/factory/storage.ligo +++ b/contracts/partials/factory/storage.ligo @@ -50,8 +50,8 @@ type full_storage_t is [@layout:comb] record [ ] type use_factory_t is -| Set_whitelist of set_man_param_t -| Set_strategy_factory of address +| Set_whitelist of set_cand_param_t +| Set_strategy_factory of set_cand_param_t | Set_burn_rate of nat | Set_price of nat | Claim_rewards of unit diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index 6c7f0d9..ab4bf6a 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -42,13 +42,13 @@ function calculate_desired_reserves( function check_strategy_pool_params( const pool_id : nat; - const strategy: address): bool is + const strategy: address): bool is block { const expected: strat_pool_data_t = record[ - pool_contract = Tezos.get_self_address(); + pool_contract = Tezos.self_address; pool_id = pool_id ]; - const reponse: strat_pool_data_t = unwrap( + const response: strat_pool_data_t = unwrap( (Tezos.call_view("get_pool_data", Unit, strategy): option(strat_pool_data_t)), Errors.Strategy.wrong_params ); @@ -88,7 +88,7 @@ function operate_with_strategy( // send additional reserves to Yupana through Strategy if value > 0n then send_ops := typed_transfer( - Tezos.self_address(unit), + Tezos.self_address, contract, value, get_token_by_id(token_id, tokens_map_entry) diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo index 29f9de6..b00466f 100644 --- a/contracts/partials/strategy/lambdas.ligo +++ b/contracts/partials/strategy/lambdas.ligo @@ -16,9 +16,9 @@ function connect_strategy( | Connect_strategy(params) -> { var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); function check_reserves( - const token_id: token_pool_idx_t; - const config : strategy_storage_t) - : unit is + const _token_id : token_pool_idx_t; + const config : strategy_storage_t) + : unit is require(config.strategy_reserves = 0n, Errors.Strategy.unclaimed_reserves); Map.iter(check_reserves, pool.strategy.configuration); pool.strategy.strat_contract := case params.strategy_contract of [ @@ -109,7 +109,20 @@ function set_rebalance( block { var operations: list(operation) := Constants.no_operations; case p of [ - | Rebalance(params) -> skip + | Rebalance(params) -> { + const pool : pool_t = unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); + function map_ids( + const acc : map(token_pool_idx_t, token_info_t); + const i : nat) + : map(token_pool_idx_t, token_info_t) is + Map.add(i, get_token_info(i, pool.tokens_info), acc); + const infos = Set.fold(map_ids, params.pool_token_ids,(map[]: map(token_pool_idx_t, token_info_t))); + const (rebalance_ops, strategy_store) = operate_with_strategy(infos, s.tokens[params.pool_id], pool.strategy); + operations := rebalance_ops; + s.pools[params.pool_id] := pool with record[ + strategy = strategy_store + ]; + } | _ -> unreachable(Unit) ] - } with (operations, s) \ No newline at end of file + } with (operations, s) diff --git a/contracts/partials/strategy/types.ligo b/contracts/partials/strategy/types.ligo index 230a7be..814a258 100644 --- a/contracts/partials/strategy/types.ligo +++ b/contracts/partials/strategy/types.ligo @@ -50,7 +50,7 @@ type upd_strat_state_t is list(upd_state_prm) type rebalance_param is [@layout:comb] record [ pool_id : pool_id_t; - pool_token_id : set(nat); + pool_token_ids : set(nat); ] type strat_upd_info_t is [@layout:comb] record [ @@ -65,4 +65,4 @@ type strategy_action_t is | Connect_token_strategy of conn_tok_strat_param | Set_token_strategy of set_tok_strat_param | Set_token_strategy_rebalance of tok_strat_upd_fl_param -| Rebalance of list(rebalance_param) \ No newline at end of file +| Rebalance of rebalance_param \ No newline at end of file diff --git a/contracts/partials/utils.ligo b/contracts/partials/utils.ligo index 6a5f20c..47a2f07 100644 --- a/contracts/partials/utils.ligo +++ b/contracts/partials/utils.ligo @@ -145,7 +145,7 @@ ]; [@inline] function add_rem_candidate( - const params : set_man_param_t; + const params : set_cand_param_t; var whitelist : set(address)) : set(address) is Set.update(params.candidate, params.add, whitelist) From 8cb3b12da062dc99d01ce6490145e13e4e8ef2b1 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 21 Nov 2022 14:10:07 +0200 Subject: [PATCH 36/67] remove unneeded check from desired reserves calculation --- contracts/partials/strategy/helpers.ligo | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index 23d1ce9..94d571e 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -14,12 +14,12 @@ function calculate_desired_reserves( : nat is block { const desired_reserves : nat = reserves * strat_token_conf.des_reserves_rate_f / Constants.precision; - require(check_strategy_bounds( - reserves, - desired_reserves, - strat_token_conf.des_reserves_rate_f, - strat_token_conf.delta_rate_f - ), Errors.Strategy.out_of_delta_bounds); + // require(check_strategy_bounds( + // reserves, + // desired_reserves, + // strat_token_conf.des_reserves_rate_f, + // strat_token_conf.delta_rate_f + // ), Errors.Strategy.out_of_delta_bounds); } with if desired_reserves > strat_token_conf.min_invest then desired_reserves else 0n From 30f20ac3b8d02df9524aae866c5b6244dfb2463d Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 25 Nov 2022 13:52:27 +0200 Subject: [PATCH 37/67] [WIP] Tests for rebalance Token connection to strategy tests done --- contracts/compiled/dex4factory.tz | 33 +- contracts/partials/admin/methods.ligo | 2 + contracts/partials/errors.ligo | 5 +- contracts/partials/factory/views.ligo | 4 +- contracts/partials/strategy/helpers.ligo | 14 +- contracts/partials/strategy/lambdas.ligo | 23 +- contracts/partials/strategy/types.ligo | 1 + scripts/commands/compile/utils.ts | 7 +- test/00_Dex.test.ts | 403 ++++++---- test/Dex/API/dexAPI.ts | 52 +- test/Dex/API/storage.ts | 1 + test/Dex/API/types.ts | 1 + test/Dex/cases/admin.ts | 4 + test/Dex/cases/before.ts | 1 + test/Dex/cases/index.ts | 6 +- test/Dex/cases/strategy/before.ts | 186 +++++ .../strategy/cofigure-token/connect_token.ts | 98 +++ .../cases/strategy/cofigure-token/index.ts | 4 +- .../strategy/cofigure-token/rebalance.ts | 32 + test/Dex/cases/strategy/connect.ts | 1 - test/Dex/cases/strategy/index.ts | 7 +- test/Factory/API/factoryAPI.ts | 24 +- test/Factory/API/storage.ts | 2 +- test/Factory/API/types.ts | 1 + test/Factory/cases/before.ts | 1 - test/Factory/cases/dev.ts | 4 + test/Strategy/API/strategyFactoryMethod.ts | 23 + test/Strategy/cases/index.ts | 34 + test/utils/mocks/artifacts/pf.tz | 43 + test/utils/mocks/artifacts/strategy.tz | 651 +++++++++++++++ .../utils/mocks/artifacts/strategy_factory.tz | 754 ++++++++++++++++++ test/utils/mocks/artifacts/yupana.tz | 586 ++++++++++++++ test/utils/mocks/getMichelsonCode.ts | 5 + 33 files changed, 2803 insertions(+), 210 deletions(-) create mode 100644 test/Dex/cases/strategy/before.ts create mode 100644 test/Strategy/API/strategyFactoryMethod.ts create mode 100644 test/Strategy/cases/index.ts create mode 100644 test/utils/mocks/artifacts/pf.tz create mode 100644 test/utils/mocks/artifacts/strategy.tz create mode 100644 test/utils/mocks/artifacts/strategy_factory.tz create mode 100644 test/utils/mocks/artifacts/yupana.tz create mode 100644 test/utils/mocks/getMichelsonCode.ts diff --git a/contracts/compiled/dex4factory.tz b/contracts/compiled/dex4factory.tz index d6351a5..215d869 100644 --- a/contracts/compiled/dex4factory.tz +++ b/contracts/compiled/dex4factory.tz @@ -16,7 +16,7 @@ (nat %pool_id) (nat %pool_token_id) (nat %lending_market_id))) - (or (list %rebalance (pair (nat %pool_id) (set %pool_token_id nat))) + (or (pair %rebalance (nat %pool_id) (set %pool_token_ids nat)) (pair %set_token_strategy (nat %pool_id) (nat %pool_token_id) @@ -112,7 +112,8 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_rebalance)))) + (bool %is_rebalance) + (bool %connected)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -296,7 +297,8 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_rebalance)))) + (bool %is_rebalance) + (bool %connected)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -345,7 +347,8 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_rebalance)))) + (bool %is_rebalance) + (bool %connected)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -416,7 +419,7 @@ (nat %pool_id) (nat %pool_token_id) (nat %lending_market_id))) - (or (list %rebalance (pair (nat %pool_id) (set %pool_token_id nat))) + (or (pair %rebalance (nat %pool_id) (set %pool_token_ids nat)) (pair %set_token_strategy (nat %pool_id) (nat %pool_token_id) @@ -453,7 +456,8 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_rebalance)))) + (bool %is_rebalance) + (bool %connected)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -502,7 +506,8 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_rebalance)))) + (bool %is_rebalance) + (bool %connected)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -627,7 +632,8 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_rebalance)))) + (bool %is_rebalance) + (bool %connected)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -676,7 +682,8 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_rebalance)))) + (bool %is_rebalance) + (bool %connected)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -769,7 +776,8 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_rebalance)))) + (bool %is_rebalance) + (bool %connected)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -824,7 +832,8 @@ (nat %delta_rate_f) (nat %min_invest) (nat %strategy_reserves) - (bool %is_rebalance)))) + (bool %is_rebalance) + (bool %connected)))) (pair %staker_accumulator (map %accumulator_f nat nat) (map %total_fees nat nat) @@ -1788,7 +1797,7 @@ timestamp (map nat (pair nat nat nat)) (pair nat nat nat) - (pair (option address) (map nat (pair nat nat nat nat bool))) + (pair (option address) (map nat (pair nat nat nat nat bool bool))) (pair (map nat nat) (map nat nat) nat) nat))) nat diff --git a/contracts/partials/admin/methods.ligo b/contracts/partials/admin/methods.ligo index f68becf..3a44e29 100644 --- a/contracts/partials/admin/methods.ligo +++ b/contracts/partials/admin/methods.ligo @@ -10,7 +10,9 @@ case p of [ | Claim_developer(_) -> skip // Claim_developer has own inner check for developer address +#if !FACTORY | Set_strategy_factory(_)-> skip +#endif | _ -> require(Tezos.sender = s.storage.admin, Errors.Dex.not_contract_admin) ]; diff --git a/contracts/partials/errors.ligo b/contracts/partials/errors.ligo index 839da0a..99f522f 100644 --- a/contracts/partials/errors.ligo +++ b/contracts/partials/errors.ligo @@ -62,11 +62,14 @@ module Factory is { module Strategy is { const out_of_delta_bounds : string = "out-of-delta-bounds"; const no_update_state_entrypoint: string = "no-update-state-EP"; + const no_update_info_entrypoint : string = "no-update-info-EP"; const not_registered : string = "strategy-not-registered-on-factory"; const no_is_registered : string = "no-is-registered-view"; const no_prepare_entrypoint : string = "no-prepare-EP"; const unknown_token : string = "no-token-strategy-set"; const unclaimed_reserves : string = "strategy-unclaimed-reserves"; const no_pool_data_view : string = "no-pool-data-view"; - const wrong_params : string = "wrong-connect-params-strategy" + const no_connected_strategy : string = "no-connected-strategy"; + const wrong_params : string = "wrong-connect-params-strategy"; + const already_connected : string = "token-strategy-connected"; } \ No newline at end of file diff --git a/contracts/partials/factory/views.ligo b/contracts/partials/factory/views.ligo index 2c33b03..a4e25b4 100644 --- a/contracts/partials/factory/views.ligo +++ b/contracts/partials/factory/views.ligo @@ -12,7 +12,7 @@ [@view] function is_registered_strategy( const strategy : address; - const s : storage_t) + const s : full_storage_t) : bool is block { function check_strategy_factory(const accumulator: bool; const entry: address): bool is @@ -20,7 +20,7 @@ (Tezos.call_view("is_registered", strategy, entry): option(bool)), Errors.Factory.no_strategy_factory ) - } with Set.fold(check_strategy_factory, s.strategy_factory, False) + } with Set.fold(check_strategy_factory, s.storage.strategy_factory, False) diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index ab4bf6a..d2684d7 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -14,12 +14,6 @@ function calculate_desired_reserves( : nat is block { const desired_reserves : nat = reserves * strat_token_conf.des_reserves_rate_f / Constants.precision; - require(check_strategy_bounds( - reserves, - desired_reserves, - strat_token_conf.des_reserves_rate_f, - strat_token_conf.delta_rate_f - ), Errors.Strategy.out_of_delta_bounds); } with if desired_reserves > strat_token_conf.min_invest then desired_reserves else 0n @@ -40,6 +34,14 @@ function calculate_desired_reserves( Errors.Strategy.no_update_state_entrypoint ); +[@inline] function get_update_token_info_entrypoint( + const strategy_address: address) + : contract(strat_upd_info_t) is + unwrap( + (Tezos.get_entrypoint_opt("%update_token_info", strategy_address): option(contract(strat_upd_info_t))), + Errors.Strategy.no_update_state_entrypoint + ); + function check_strategy_pool_params( const pool_id : nat; const strategy: address): bool is diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo index b00466f..763c3c5 100644 --- a/contracts/partials/strategy/lambdas.ligo +++ b/contracts/partials/strategy/lambdas.ligo @@ -4,6 +4,7 @@ const default_strategy_configuration = record [ min_invest = 0n; strategy_reserves = 0n; is_rebalance = True; + connected = False; ] function connect_strategy( @@ -38,22 +39,36 @@ function connect_strategy( function connect_token_to_strategy( const p : strategy_action_t; - const s : storage_t) + var s : storage_t) : return_t is block { var operations: list(operation) := Constants.no_operations; case p of [ | Connect_token_strategy(params) -> { + var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); + var token_config := unwrap( + pool.strategy.configuration[params.pool_token_id], + Errors.Strategy.unknown_token + ); + require(not token_config.connected, Errors.Strategy.already_connected); const token = get_token_by_id( params.pool_token_id, s.tokens[params.pool_id] ); + const strategy = unwrap(pool.strategy.strat_contract, Errors.Strategy.no_connected_strategy); const connect_token_params: strat_upd_info_t = record[ token = token; - pool_token_id = params.pool_id; + pool_token_id = params.pool_token_id; lending_market_id = params.lending_market_id ]; - // TODO: send connection to strategy + operations := Tezos.transaction( + connect_token_params, + 0mutez, + get_update_token_info_entrypoint(strategy) + ) # operations; + token_config.connected := True; + pool.strategy.configuration[params.pool_token_id] := token_config; + s.pools[params.pool_id] := pool; } | _ -> unreachable(Unit) ] @@ -116,7 +131,7 @@ function set_rebalance( const i : nat) : map(token_pool_idx_t, token_info_t) is Map.add(i, get_token_info(i, pool.tokens_info), acc); - const infos = Set.fold(map_ids, params.pool_token_ids,(map[]: map(token_pool_idx_t, token_info_t))); + const infos = Set.fold(map_ids, params.pool_token_ids, (map[]: map(token_pool_idx_t, token_info_t))); const (rebalance_ops, strategy_store) = operate_with_strategy(infos, s.tokens[params.pool_id], pool.strategy); operations := rebalance_ops; s.pools[params.pool_id] := pool with record[ diff --git a/contracts/partials/strategy/types.ligo b/contracts/partials/strategy/types.ligo index 814a258..da24658 100644 --- a/contracts/partials/strategy/types.ligo +++ b/contracts/partials/strategy/types.ligo @@ -4,6 +4,7 @@ type strategy_storage_t is [@layout:comb] record[ min_invest : nat; strategy_reserves : nat; is_rebalance : bool; + connected : bool; ]; type strategy_full_storage_t is [@layout:comb] record [ diff --git a/scripts/commands/compile/utils.ts b/scripts/commands/compile/utils.ts index 2365c6e..5eaa27b 100644 --- a/scripts/commands/compile/utils.ts +++ b/scripts/commands/compile/utils.ts @@ -219,7 +219,12 @@ export const compileLambdas = async ( for (const lambda of lambdas) { let func; if (factory_path) { - if (lambda.name == "add_pool" && factory_path) continue; + if ( + (lambda.name == "add_pool" || + lambda.name == "set_strategy_factory") && + factory_path + ) + continue; func = `Bytes.pack(${lambda.name})`; } else { func = `Set_${type.toLowerCase()}_function(record [index=${ diff --git a/test/00_Dex.test.ts b/test/00_Dex.test.ts index 9fb364a..636bb0c 100644 --- a/test/00_Dex.test.ts +++ b/test/00_Dex.test.ts @@ -18,6 +18,7 @@ const { decimals, a_const, accounts, zero_amount, swap_routes, dev_fee } = import { AmountsMap, IndexMap, TokensMap } from "./utils/types"; import { TokenFA12, TokenFA2 } from "./Token"; import { defaultTokenId } from "./Token/token"; +import { Contract } from "@taquito/taquito"; describe("00. Standalone Dex", () => { const aliceAddress: TezosAddress = accounts.alice.pkh; @@ -57,18 +58,13 @@ describe("00. Standalone Dex", () => { it( "should fail if not admin try to set admin", async () => - await failCase( - "bob", - async () => await dex.setAdmin(new_admin), - "not-contract-admin" - ), + failCase("bob", dex.setAdmin(new_admin), "not-contract-admin"), 10000 ); it( "should change admin", - async () => - await TMng.setAdminSuccessCase(dex, "alice", new_admin, Tezos), + async () => TMng.setAdminSuccessCase(dex, "alice", new_admin, Tezos), 50000 ); }); @@ -88,24 +84,19 @@ describe("00. Standalone Dex", () => { it( "should fail if not dev try to set fee", async () => - await failCase( - "bob", - async () => await dex.setDevFee(dev_fee), - "not-developer" - ), + failCase("bob", async () => dex.setDevFee(dev_fee), "not-developer"), 20000 ); it( "should change dev address", - async () => - await TMng.setDevAddrSuccessCase(dex, "eve", new_dev, Tezos), + async () => TMng.setDevAddrSuccessCase(dex, "eve", new_dev, Tezos), 20000 ); it( "should change dev fee", - async () => await TMng.setDevFeeSuccessCase(dex, "bob", dev_fee, Tezos), + async () => TMng.setDevFeeSuccessCase(dex, "bob", dev_fee, Tezos), 20000 ); }); @@ -114,9 +105,9 @@ describe("00. Standalone Dex", () => { it( "should fail if not admin try set manager", async () => - await failCase( + failCase( "bob", - async () => dex.addRemManager(true, manager), + dex.addRemManager(true, manager), "not-contract-admin" ), 10000 @@ -153,9 +144,9 @@ describe("00. Standalone Dex", () => { it( "should fail if not admin try change default referral", async () => - await failCase( + failCase( "bob", - async () => dex.setDefaultReferral(aliceAddress), + dex.setDefaultReferral(aliceAddress), "not-contract-admin" ), 10000 @@ -183,9 +174,9 @@ describe("00. Standalone Dex", () => { it( "should fail if not admin try to add pool", async () => - await failCase( + failCase( "alice", - async () => await dex.addPool(a_const, inputs, false), + dex.addPool(a_const, inputs, false), "not-contract-admin" ), 10000 @@ -219,16 +210,15 @@ describe("00. Standalone Dex", () => { it( "should fail if not admin performs ramp A", async () => - await failCase( + failCase( "bob", - async () => - dex.contract.methods - .ramp_A( - pool_id, - TPool.PoolAdmin.Ramp_A.future_a_const.toString(), - TPool.PoolAdmin.Ramp_A.future_a_time.toString() - ) - .send(), + dex.contract.methods + .ramp_A( + pool_id, + TPool.PoolAdmin.Ramp_A.future_a_const.toString(), + TPool.PoolAdmin.Ramp_A.future_a_time.toString() + ) + .send(), "not-contract-admin" ), 10000 @@ -237,7 +227,7 @@ describe("00. Standalone Dex", () => { it( "should ramp A", async () => - await prepareProviderOptions("eve").then((config) => { + prepareProviderOptions("eve").then((config) => { Tezos.setProvider(config); return TPool.PoolAdmin.Ramp_A.rampASuccessCase( dex, @@ -252,17 +242,16 @@ describe("00. Standalone Dex", () => { it( "should fail if not admin performs stopping ramp A", async () => - await failCase( + failCase( "bob", - async () => - await dex.contract.methods.stop_ramp_A(pool_id).send(), + dex.contract.methods.stop_ramp_A(pool_id).send(), "not-contract-admin" ), 10000 ); it("should stop ramp A", async () => - await prepareProviderOptions("eve").then((config) => { + prepareProviderOptions("eve").then((config) => { Tezos.setProvider(config); return TPool.PoolAdmin.Ramp_A.stopRampASuccessCase(dex, pool_id); })); @@ -272,9 +261,9 @@ describe("00. Standalone Dex", () => { it( "should fail if not admin try to set new fee", async () => - await failCase( + failCase( "bob", - async () => await dex.setFees(pool_id, TPool.PoolAdmin.Fee.fees), + dex.setFees(pool_id, TPool.PoolAdmin.Fee.fees), "not-contract-admin" ), 10000 @@ -283,7 +272,7 @@ describe("00. Standalone Dex", () => { it( "should change fees", async () => - await TPool.PoolAdmin.Fee.setFeesSuccessCase( + TPool.PoolAdmin.Fee.setFeesSuccessCase( dex, "eve", pool_id, @@ -310,7 +299,7 @@ describe("00. Standalone Dex", () => { it( `should stake ${input.dividedBy(decimals.QUIPU)} QUIPU to pool`, async () => - await TPool.stake.stakeToPoolSuccessCase( + TPool.stake.stakeToPoolSuccessCase( dex, staker, pool_id, @@ -357,17 +346,16 @@ describe("00. Standalone Dex", () => { it( "should fail if zero input", async () => - await failCase( + failCase( sender, - async () => - dex.investLiquidity( - pool_id, - zero_amounts, - min_shares, - new Date(Date.now() + 1000 * 60 * 60 * 24), - null, - referral - ), + dex.investLiquidity( + pool_id, + zero_amounts, + min_shares, + new Date(Date.now() + 1000 * 60 * 60 * 24), + null, + referral + ), "zero-amount-in" ), 10000 @@ -378,15 +366,14 @@ describe("00. Standalone Dex", () => { async () => failCase( sender, - async () => - dex.investLiquidity( - pool_id, - amounts, - min_shares, - new Date(0), - null, - referral - ), + dex.investLiquidity( + pool_id, + amounts, + min_shares, + new Date(0), + null, + referral + ), "time-expired" ), 10000 @@ -414,7 +401,7 @@ describe("00. Standalone Dex", () => { it( "should invest liq balanced", async () => - await TPool.PoolInvest.investLiquiditySuccessCase( + TPool.PoolInvest.investLiquiditySuccessCase( dex, sender, pool_id, @@ -489,19 +476,18 @@ describe("00. Standalone Dex", () => { it( "should fail if expired", async () => - await failCase( + failCase( "bob", - async () => - await dex.swap( - pool_id, - new BigNumber(idx_map.uUSD), - new BigNumber(idx_map.kUSD), - decimals.uUSD.multipliedBy(normalized), - new BigNumber(0), - new Date(0), - bobAddress, - referral - ), + dex.swap( + pool_id, + new BigNumber(idx_map.uUSD), + new BigNumber(idx_map.kUSD), + decimals.uUSD.multipliedBy(normalized), + new BigNumber(0), + new Date(0), + bobAddress, + referral + ), "time-expired" ), 10000 @@ -510,19 +496,18 @@ describe("00. Standalone Dex", () => { it.each(swap_routes)( "should fail if zero input [%s, %s]", async (t_in, t_to) => - await failCase( + failCase( "bob", - async () => - await dex.swap( - pool_id, - new BigNumber(idx_map[t_in]), - new BigNumber(idx_map[t_to]), - zero_amount, - new BigNumber(1), - new Date(Date.now() + 1000 * 60 * 60 * 24), - bobAddress, - referral - ), + dex.swap( + pool_id, + new BigNumber(idx_map[t_in]), + new BigNumber(idx_map[t_to]), + zero_amount, + new BigNumber(1), + new Date(Date.now() + 1000 * 60 * 60 * 24), + bobAddress, + referral + ), "zero-amount-in" ), 10000 @@ -531,7 +516,7 @@ describe("00. Standalone Dex", () => { it.each(swap_routes)( `should swap [${normalized.toString()} %s, ~ ${normalized.toString()} %s]`, async (t_in, t_to) => - await TPool.PoolSwap.swapSuccessCase( + TPool.PoolSwap.swapSuccessCase( dex, tokens, sender, @@ -587,16 +572,15 @@ describe("00. Standalone Dex", () => { it( "should fail if zero input", async () => - await failCase( + failCase( "eve", - async () => - await dex.divestLiquidity( - pool_id, - min_amounts, - new BigNumber("0"), - new Date(Date.now() + 1000 * 60 * 60 * 24), - null - ), + dex.divestLiquidity( + pool_id, + min_amounts, + new BigNumber("0"), + new Date(Date.now() + 1000 * 60 * 60 * 24), + null + ), "zero-amount-in" ), 10000 @@ -605,16 +589,15 @@ describe("00. Standalone Dex", () => { it( "should fail if expired", async () => - await failCase( + failCase( "eve", - async () => - await dex.divestLiquidity( - pool_id, - min_amounts, - amount_in, - new Date(0), - null - ), + dex.divestLiquidity( + pool_id, + min_amounts, + amount_in, + new Date(0), + null + ), "time-expired" ), 10000 @@ -623,7 +606,7 @@ describe("00. Standalone Dex", () => { it( "should divest liq balanced", async () => - await TPool.PoolDivest.divestLiquiditySuccessCase( + TPool.PoolDivest.divestLiquiditySuccessCase( dex, "eve", pool_id, @@ -638,7 +621,7 @@ describe("00. Standalone Dex", () => { it( "should divest liq imbalanced", async () => - await TPool.PoolDivest.divestLiquidityImbalanceSuccessCase( + TPool.PoolDivest.divestLiquidityImbalanceSuccessCase( dex, "eve", pool_id, @@ -653,7 +636,7 @@ describe("00. Standalone Dex", () => { it( "should divest liq in one coin", async () => - await TPool.PoolDivest.divestLiquidityOneSuccessCase( + TPool.PoolDivest.divestLiquidityOneSuccessCase( dex, "eve", pool_id, @@ -682,10 +665,9 @@ describe("00. Standalone Dex", () => { it( "should fail if low balance", async () => - await failCase( + failCase( "bob", - async () => - await dex.transfer(pool_id, bobAddress, aliceAddress, amount), + dex.transfer(pool_id, bobAddress, aliceAddress, amount), "FA2_INSUFFICIENT_BALANCE" ), 10000 @@ -694,7 +676,7 @@ describe("00. Standalone Dex", () => { it( "should send from self", async () => - await prepareProviderOptions("alice").then((config) => { + prepareProviderOptions("alice").then((config) => { Tezos.setProvider(config); return dex.transfer(pool_id, aliceAddress, bobAddress, amount); }), @@ -706,10 +688,9 @@ describe("00. Standalone Dex", () => { it( "should fail send if not approved", async () => - await failCase( + failCase( "bob", - async () => - await dex.transfer(pool_id, aliceAddress, bobAddress, amount), + dex.transfer(pool_id, aliceAddress, bobAddress, amount), "FA2_NOT_OPERATOR" ), 10000 @@ -718,7 +699,7 @@ describe("00. Standalone Dex", () => { it( "should update operator", async () => - await prepareProviderOptions("alice").then((config) => { + prepareProviderOptions("alice").then((config) => { Tezos.setProvider(config); return dex.approve(bobAddress, amount); }), @@ -728,7 +709,7 @@ describe("00. Standalone Dex", () => { it( "should send as operator", async () => - await prepareProviderOptions("bob").then((config) => { + prepareProviderOptions("bob").then((config) => { Tezos.setProvider(config); return dex.transfer(pool_id, aliceAddress, bobAddress, amount); }), @@ -758,16 +739,16 @@ describe("00. Standalone Dex", () => { describe("4.1. Dex views", () => { it("should return A", async () => - await TView.pool.getASuccessCase(dex, pool_id)); + TView.pool.getASuccessCase(dex, pool_id)); it("should return fees", async () => - await TView.pool.getFeesSuccessCase(dex, pool_id)); + TView.pool.getFeesSuccessCase(dex, pool_id)); it("should return reserves", async () => - await TView.pool.getReservesSuccessCase(dex, pool_id)); + TView.pool.getReservesSuccessCase(dex, pool_id)); it("should return token map", async () => - await TView.pool.getTokenMapSuccessCase( + TView.pool.getTokenMapSuccessCase( dex, pool_id, tokens, @@ -775,10 +756,10 @@ describe("00. Standalone Dex", () => { )); it("should return dy", async () => - await TView.pool.getDySuccessCase(dex, pool_id, map_tokens_idx)); + TView.pool.getDySuccessCase(dex, pool_id, map_tokens_idx)); it("should fail when return dy because of pool_id", async () => - await failCase( + failCase( "bob", async () => { const params = { @@ -795,10 +776,10 @@ describe("00. Standalone Dex", () => { )); it("should return LP value", async () => - await TView.pool.getLPValueSuccessCase(dex, pool_id, map_tokens_idx)); + TView.pool.getLPValueSuccessCase(dex, pool_id, map_tokens_idx)); it("should return calc divest one", async () => - await TView.pool.calcDivestOneSuccessCase( + TView.pool.calcDivestOneSuccessCase( dex, { pool_id: pool_id, @@ -809,7 +790,7 @@ describe("00. Standalone Dex", () => { )); it("should return referral rewards", async () => - await TView.pool.getRefRewardsSuccessCase(dex, [ + TView.pool.getRefRewardsSuccessCase(dex, [ { user: referral, token: { @@ -830,7 +811,7 @@ describe("00. Standalone Dex", () => { ])); it("should return staker info", async () => - await TView.pool.getStkrInfoSuccessCase(dex, [ + TView.pool.getStkrInfoSuccessCase(dex, [ { user: staker, pool_id: pool_id, @@ -840,7 +821,7 @@ describe("00. Standalone Dex", () => { describe("4.2.Token views", () => { it("should return balance of account", async () => - await dex.contract.views + dex.contract.views .balance_of([ { owner: aliceAddress, @@ -863,7 +844,7 @@ describe("00. Standalone Dex", () => { })); it("should return total supply", async () => - await dex.contract.views + dex.contract.views .total_supply(pool_id) .read() .then((total_supply) => { @@ -892,7 +873,7 @@ describe("00. Standalone Dex", () => { decimals.QUIPU )} QUIPU tokens from pool`, async () => - await TPool.stake.unstakeFromPoolSuccessCase( + TPool.stake.unstakeFromPoolSuccessCase( dex, staker, pool_id, @@ -931,7 +912,7 @@ describe("00. Standalone Dex", () => { it( "should get referral rewards", async () => - await TReward.referral.getReferralRewardsSuccessCase( + TReward.referral.getReferralRewardsSuccessCase( dex, tokens, pool_id, @@ -939,7 +920,7 @@ describe("00. Standalone Dex", () => { referral, Tezos ), - 30000 + 60000 ); }); @@ -947,7 +928,7 @@ describe("00. Standalone Dex", () => { it( "should harvest staking rewards", async () => - await prepareProviderOptions("bob").then((config) => { + prepareProviderOptions("bob").then((config) => { Tezos.setProvider(config); return TReward.staker.harvestFromPoolSuccessCase( dex, @@ -962,7 +943,7 @@ describe("00. Standalone Dex", () => { describe("6.3. Developer reward", () => { it("should get dev rewards", async () => - await TReward.developer.getDeveloperRewardsSuccessCase( + TReward.developer.getDeveloperRewardsSuccessCase( dex, tokens, pool_id, @@ -975,14 +956,36 @@ describe("00. Standalone Dex", () => { describe("7. Testing strategy", () => { let pool_id: BigNumber; - let strategy: TezosAddress; - let pool_token_id: BigNumber; + let yupana: Contract; + let price_feed: Contract; + let strategy_factory: Contract; + let strategy: Contract; + let yup_ordering: IndexMap; + let pool_ordering: IndexMap; beforeAll(async () => { - await dex.updateStorage({}); pool_id = dex.storage.storage.pools_count.minus(new BigNumber(1)); - strategy = aliceAddress; - pool_token_id = new BigNumber(0); + await dex.updateStorage({ tokens: [pool_id.toString()] }); + ({ + yupana, + ordering: yup_ordering, + price_feed, + } = await TInit.setupYupanaMocks(tokens, Tezos)); + ({ strategy_factory, strategy } = await TInit.originateStrategy( + dex, + pool_id, + yupana, + price_feed, + Tezos + )); + pool_ordering = mapTokensToIdx( + dex.storage.storage.tokens[pool_id.toString()], + tokens + ); + // eslint-disable-next-line jest/no-standalone-expect + await expect(strategy.storage()).resolves.toMatchObject({ + factory: strategy_factory.address, + }); }); describe("as a developer", () => { @@ -991,48 +994,117 @@ describe("00. Standalone Dex", () => { Tezos.setProvider(config); }); - it("should connect new strategy", async () => - await TStrategy.connect.setStrategyAddrSuccessCase( - dex, - pool_id, - strategy + const test_factory = "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"; + + it("should connect and remove test strategy factory", async () => + TMng.addStrategyFactorySuccessCase(dex, test_factory).then(() => + TMng.removeStrategyFactorySuccessCase(dex, test_factory) )); + it("should connect new strategy factory", async () => + TMng.addStrategyFactorySuccessCase(dex, strategy_factory.address)); + it("should fail when set rebalance flag to non cofigured token", async () => - await failCase( + failCase( "bob", - async () => - await dex.setTokenStrategyRebalance(pool_id, pool_token_id, false), + dex.setTokenStrategyRebalance( + pool_id, + new BigNumber(pool_ordering.kUSD), + false + ), "no-token-strategy-set" )); it("should configure new strategy for token", async () => - await TStrategy.token.configureTokenStrategy.setStrategyParamsSuccessCase( + TStrategy.token.configureTokenStrategy + .setStrategyParamsSuccessCase( + dex, + pool_id, + new BigNumber(pool_ordering.kUSD), + new BigNumber("0.3").multipliedBy("1e18"), + new BigNumber("0.05").multipliedBy("1e18"), + new BigNumber("300").multipliedBy("1e6") + ) + .then(() => + TStrategy.token.configureTokenStrategy.setStrategyParamsSuccessCase( + dex, + pool_id, + new BigNumber(pool_ordering.uUSD), + new BigNumber("0.15").multipliedBy("1e18"), + new BigNumber("0.03").multipliedBy("1e18"), + new BigNumber("1500").multipliedBy("1e6") + ) + )); + + it("should fail connect token to NO strategy", async () => + TStrategy.token.connectTokenToStrategy.connectTokenStrategyFailCaseNoStrategy( + dex, + pool_id, + new BigNumber(pool_ordering.kUSD), + new BigNumber(yup_ordering.kUSD) + )); + + it("should connect new strategy", async () => + TStrategy.connect.setStrategyAddrSuccessCase( + dex, + pool_id, + strategy.address + )); + + it("should connect token to strategy", async () => + TStrategy.token.connectTokenToStrategy + .connectTokenStrategySuccessCase( + dex, + pool_id, + new BigNumber(pool_ordering.kUSD), + new BigNumber(yup_ordering.kUSD) + ) + .then(() => + TStrategy.token.connectTokenToStrategy.connectTokenStrategySuccessCase( + dex, + pool_id, + new BigNumber(pool_ordering.uUSD), + new BigNumber(yup_ordering.uUSD) + ) + )); + + it("should fail connect same token to strategy", async () => + TStrategy.token.connectTokenToStrategy.connectTokenStrategyFailCaseAdded( dex, pool_id, - pool_token_id, - new BigNumber("0.3").multipliedBy("1e18"), - new BigNumber("0.05").multipliedBy("1e18"), - new BigNumber("300").multipliedBy("1e6") + new BigNumber(pool_ordering.kUSD), + new BigNumber(yup_ordering.kUSD) + )); + + it("should call manual rebalance", async () => + TStrategy.token.manualRebalanceToken.manualRebalanceSuccessCase( + dex, + yupana, + strategy, + pool_id, + new Set([ + new BigNumber(pool_ordering.kUSD), + new BigNumber(pool_ordering.uUSD), + ]) )); it("should set is rebalance flag for token", async () => - await TStrategy.token.setStrategyRebalance.setIsRebalanceSuccessCase( + TStrategy.token.setStrategyRebalance.setIsRebalanceSuccessCase( dex, pool_id, - pool_token_id, + new BigNumber(pool_ordering.kUSD), false )); it("should configure strategy for token to zero", async () => - await TStrategy.token.configureTokenStrategy.setStrategyParamsToZeroSuccessCase( + TStrategy.token.configureTokenStrategy.setStrategyParamsToZeroSuccessCase( dex, pool_id, - pool_token_id + new BigNumber(pool_ordering.kUSD) )); it("should disconnect new strategy", async () => - await TStrategy.connect.removeStrategyAddrSuccessCase(dex, pool_id)); + TStrategy.connect.removeStrategyAddrSuccessCase(dex, pool_id)); }); describe("as a non-developer", () => { @@ -1046,12 +1118,16 @@ describe("00. Standalone Dex", () => { await failCase( "eve", async () => - await dex.setTokenStrategyRebalance(pool_id, pool_token_id, false), + await dex.setTokenStrategyRebalance( + pool_id, + new BigNumber(pool_ordering.kUSD), + false + ), "not-developer" ); await failCase( "eve", - async () => await dex.connectStrategy(pool_id, strategy), + async () => await dex.connectStrategy(pool_id, strategy.address), "not-developer" ); await failCase( @@ -1059,7 +1135,7 @@ describe("00. Standalone Dex", () => { async () => await dex.connectTokenStrategy( pool_id, - pool_token_id, + new BigNumber(pool_ordering.kUSD), new BigNumber(0) ), "not-developer" @@ -1069,18 +1145,19 @@ describe("00. Standalone Dex", () => { async () => await dex.setTokenStrategy( pool_id, - pool_token_id, + new BigNumber(pool_ordering.kUSD), new BigNumber("0.3").multipliedBy("1e18"), new BigNumber("0.05").multipliedBy("1e18"), new BigNumber("300").multipliedBy("1e6") ), "not-developer" ); - // await failCase( - // "eve", - // async () => await dex.rebalance([{pool_id, [pool_token_id]}]), - // "not-developer" - // ); + const set = new Set([new BigNumber(pool_ordering.kUSD)]); + await failCase( + "eve", + async () => await dex.rebalance(pool_id, set), + "not-developer" + ); }); }); }); diff --git a/test/Dex/API/dexAPI.ts b/test/Dex/API/dexAPI.ts index 2b243a2..1a2d0d5 100644 --- a/test/Dex/API/dexAPI.ts +++ b/test/Dex/API/dexAPI.ts @@ -24,8 +24,12 @@ import strat_lambdas_comp from "../../../build/lambdas/test/Strategy_lambdas.jso import token_lambdas_comp from "../../../build/lambdas/test/Token_lambdas.json"; import { defaultTokenId, TokenFA12, TokenFA2 } from "../../Token"; import { DevEnabledContract } from "../../Developer/API/devAPI"; +import { StrategyFactorySetter } from "../../Strategy/API/strategyFactoryMethod"; -export class Dex extends TokenFA2 implements DevEnabledContract { +export class Dex + extends TokenFA2 + implements DevEnabledContract, StrategyFactorySetter +{ public contract: ContractAbstraction; public storage: DexStorage; @@ -49,7 +53,7 @@ export class Dex extends TokenFA2 implements DevEnabledContract { tezos, dexAddress, "Admin", - 8, + 9, admin_lambdas_comp ); await setFunctionBatchCompilled( @@ -446,11 +450,14 @@ export class Dex extends TokenFA2 implements DevEnabledContract { async rebalance( poolId: BigNumber, - poolTokenId: BigNumber + poolTokenIds: Set ): Promise { await this.updateStorage({}); const operation = await this.contract.methods - .rebalance(poolId.toString(), poolTokenId.toString()) + .rebalance( + poolId.toString(), + Array.from(poolTokenIds).map((x) => x.toNumber()) + ) .send(); await operation.confirmation(2); @@ -460,8 +467,8 @@ export class Dex extends TokenFA2 implements DevEnabledContract { manualRebalanceStrategy = ( poolId: BigNumber, - poolTokenId: BigNumber - ): Promise => this.rebalance(poolId, poolTokenId); + poolTokenIds: Set + ): Promise => this.rebalance(poolId, poolTokenIds); async connectTokenStrategy( poolId: BigNumber, @@ -469,12 +476,12 @@ export class Dex extends TokenFA2 implements DevEnabledContract { lendingMarketId: BigNumber ): Promise { await this.updateStorage({}); - const operation = await this.contract.methods - .connect_token_strategy( - poolId.toString(), - poolTokenId.toString(), - lendingMarketId.toString() - ) + const operation = await this.contract.methodsObject + .connect_token_strategy({ + pool_id: poolId.toString(), + pool_token_id: poolTokenId.toString(), + lending_market_id: lendingMarketId.toString(), + }) .send(); await operation.confirmation(2); @@ -541,4 +548,25 @@ export class Dex extends TokenFA2 implements DevEnabledContract { await operation.confirmation(2); return operation; } + + async manageStrategyFactories( + strategy_factory: string, + add: boolean + ): Promise { + const op = await this.contract.methods + .set_strategy_factory(add, strategy_factory) + .send(); + await op.confirmation(2); + return op; + } + async addStrategyFactory( + strategy_factory: string + ): Promise { + return this.manageStrategyFactories(strategy_factory, true); + } + async removeStrategyFactory( + strategy_factory: string + ): Promise { + return this.manageStrategyFactories(strategy_factory, false); + } } diff --git a/test/Dex/API/storage.ts b/test/Dex/API/storage.ts index 6948652..4bfc655 100644 --- a/test/Dex/API/storage.ts +++ b/test/Dex/API/storage.ts @@ -26,6 +26,7 @@ const dex_storage: DexStorage = { dev_lambdas: new MichelsonMap(), }, factory_address: null as TezosAddress, + strategy_factory: null as TezosAddress[], }, metadata: new MichelsonMap(), admin_lambdas: new MichelsonMap(), diff --git a/test/Dex/API/types.ts b/test/Dex/API/types.ts index 37dd634..777f282 100644 --- a/test/Dex/API/types.ts +++ b/test/Dex/API/types.ts @@ -85,6 +85,7 @@ export declare type DexMainStorage = { >; dev_store?: DevStorage; factory_address?: TezosAddress; + strategy_factory?: TezosAddress[]; }; export declare type DexStorage = { diff --git a/test/Dex/cases/admin.ts b/test/Dex/cases/admin.ts index 27c15df..285b483 100644 --- a/test/Dex/cases/admin.ts +++ b/test/Dex/cases/admin.ts @@ -8,6 +8,10 @@ export { setDevAddrSuccessCase, setDevFeeSuccessCase, } from "../../Developer/cases"; +export { + addStrategyFactorySuccessCase, + removeStrategyFactorySuccessCase, +} from "../../Strategy/cases"; export async function setAdminSuccessCase( dex: Dex, diff --git a/test/Dex/cases/before.ts b/test/Dex/cases/before.ts index 5cbe05d..b432e02 100644 --- a/test/Dex/cases/before.ts +++ b/test/Dex/cases/before.ts @@ -40,6 +40,7 @@ export async function setupDexEnvironment(Tezos: TezosToolkit): Promise<{ storage.storage.dev_store.dev_lambdas = await setupLambdasToStorage( dev_lambdas_comp ); + storage.storage.strategy_factory = []; const dex_op = await Tezos.contract.originate({ code: dex_contract.michelson, storage: storage, diff --git a/test/Dex/cases/index.ts b/test/Dex/cases/index.ts index 4c9bf47..d0ac00c 100644 --- a/test/Dex/cases/index.ts +++ b/test/Dex/cases/index.ts @@ -1,15 +1,17 @@ -import * as before from "./before"; +import * as common_before from "./before"; import * as admin from "./admin"; import * as pools from "./pool_part"; import * as rewards from "./rewards"; import * as views from "./views"; import strategy from "./strategy"; + +const before = { ...common_before, ...strategy.before }; export const cases = { before, admin, pools, rewards, views, - strategy, + strategy: strategy.cases, }; export default cases; diff --git a/test/Dex/cases/strategy/before.ts b/test/Dex/cases/strategy/before.ts new file mode 100644 index 0000000..e71ceb9 --- /dev/null +++ b/test/Dex/cases/strategy/before.ts @@ -0,0 +1,186 @@ +import { TezosToolkit, Contract, MichelsonMap } from "@taquito/taquito"; +import { + OperationContentsAndResultTransaction, + OperationResultOrigination, +} from "@taquito/rpc"; +import { BigNumber } from "bignumber.js"; + +import { IndexMap, TokensMap } from "../../../utils/types"; +import { getMichelsonCode } from "../../../utils/mocks/getMichelsonCode"; +import { Dex } from "../../API/dexAPI"; + +export async function setupYupanaMocks( + tokens: TokensMap, + Tezos: TezosToolkit +): Promise<{ + yupana: Contract; + ordering: IndexMap; + price_feed: Contract; +}> { + const yupanaStorage = { + ledger: new MichelsonMap(), + tokens: MichelsonMap.fromLiteral({ + 0: { + mainToken: { fa12: tokens.USDtz.contract.address }, + interestUpdateTime: "0", + priceUpdateTime: "0", + exchangeRateF: new BigNumber("1e18"), + totalSupplyF: 0, + totalLiquidityF: 0, + lastPrice: 0, + }, + 1: { + mainToken: { fa12: tokens.kUSD.contract.address }, + interestUpdateTime: "0", + priceUpdateTime: "0", + exchangeRateF: new BigNumber("1e18"), + totalSupplyF: 0, + totalLiquidityF: 0, + lastPrice: 0, + }, + 2: { + mainToken: { + fa2: { + token_address: tokens.uUSD.contract.address, + token_id: 0, + }, + }, + interestUpdateTime: "0", + priceUpdateTime: "0", + exchangeRateF: new BigNumber("1e18"), + totalSupplyF: 0, + totalLiquidityF: 0, + lastPrice: 0, + }, + }), + priceFeedProxy: "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg", + }; + const ordering = { + USDtz: "0", + kUSD: "1", + uUSD: "2", + }; + const mockYupanaContractOrigination = await Tezos.contract.originate({ + code: getMichelsonCode("yupana"), + storage: yupanaStorage, + }); + await mockYupanaContractOrigination.confirmation(1); + const yupana = await mockYupanaContractOrigination.contract(); + console.debug("[MOCKS] Yupana: ", yupana.address); + const priceFeedStorage = { + yToken: yupana.address, + prices: MichelsonMap.fromLiteral({ + 0: 10_000_000, + 1: 11_000_000, + 2: 12_000_000, + }), + }; + const pfContractOrigination = await Tezos.contract.originate({ + code: getMichelsonCode("pf"), + storage: priceFeedStorage, + }); + await pfContractOrigination.confirmation(1); + const price_feed = await pfContractOrigination.contract(); + console.debug("[MOCKS] Price Feed: ", price_feed.address); + await ( + await yupana.methods.setPriceFeed(price_feed.address).send() + ).confirmation(1); + console.debug("[MOCKS] Price Feed Connected"); + + const mint = await Tezos.contract + .batch() + .withContractCall( + tokens.kUSD.contract.methods.approve(yupana.address, 1_000_000) + ) + .withContractCall( + tokens.uUSD.contract.methodsObject.update_operators([ + { + add_operator: { + owner: await Tezos.signer.publicKeyHash(), + operator: yupana.address, + token_id: 0, + }, + }, + ]) + ) + .withContractCall( + price_feed.methodsObject.getPrice([ordering.kUSD, ordering.uUSD]) + ) + .withContractCall(yupana.methodsObject.updateInterest(ordering.kUSD)) + .withContractCall(yupana.methodsObject.updateInterest(ordering.uUSD)) + .withContractCall( + yupana.methodsObject.mint({ + tokenId: ordering.kUSD, + amount: 1_000_000, + minReceived: 1, + }) + ) + .withContractCall( + yupana.methodsObject.mint({ + tokenId: ordering.uUSD, + amount: 1_000_000, + minReceived: 1, + }) + ) + .send(); + await mint.confirmation(1); + console.debug("[MOCKS] Yupana markets minted"); + + return { yupana, ordering, price_feed }; +} + +export async function originateStrategy( + dex: Dex, + pool_id: BigNumber, + yupana: Contract, + price_feed: Contract, + Tezos: TezosToolkit +): Promise<{ + strategy_factory: Contract; + strategy: Contract; +}> { + const dev_address = await Tezos.signer.publicKeyHash(); + const strategy_factory_origination = await Tezos.contract.originate({ + code: getMichelsonCode("strategy_factory"), + storage: { + dev: { + dev_address: dev_address, + temp_dev_address: null, + }, + deployed_strategies: new MichelsonMap(), + connected_pools: new MichelsonMap(), + }, + }); + await strategy_factory_origination.confirmation(1); + const strategy_factory = await strategy_factory_origination.contract(); + console.debug("[STRATEGY] Strategy Factory: ", strategy_factory.address); + const poolInfo = { + pool_contract: dex.contract.address, + pool_id: pool_id, + }; + const deploy_strategy_request = await strategy_factory.methodsObject + .deploy_strategy({ + pool_info: poolInfo, + lending_data: { + lending_contract: yupana.address, + price_feed_contract: price_feed.address, + }, + }) + .send(); + await deploy_strategy_request.confirmation(2); + const deployed_strategy = ( + ( + deploy_strategy_request + .results[0] as OperationContentsAndResultTransaction + ).metadata.internal_operation_results[0] + .result as OperationResultOrigination + ).originated_contracts[0]; + const strategy = await Tezos.contract.at(deployed_strategy); + console.debug( + "[STRATEGY] Deployed Strategy for ", + poolInfo.pool_contract + `[${poolInfo.pool_id.toString()}]`, + " is ", + strategy.address + ); + return { strategy_factory, strategy }; +} diff --git a/test/Dex/cases/strategy/cofigure-token/connect_token.ts b/test/Dex/cases/strategy/cofigure-token/connect_token.ts index e69de29..9e545d1 100644 --- a/test/Dex/cases/strategy/cofigure-token/connect_token.ts +++ b/test/Dex/cases/strategy/cofigure-token/connect_token.ts @@ -0,0 +1,98 @@ +import BigNumber from "bignumber.js"; +import { TezosToolkit } from "@taquito/taquito"; +import Dex from "../../../API"; +import { PairInfo } from "../../../API/types"; + +export async function connectTokenStrategySuccessCase( + dex: Dex, + pool_id: BigNumber, + pool_token_id: BigNumber, + lending_market_id: BigNumber +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + let pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const beforeConfiguration = pool.strategy.configuration.get( + pool_token_id.toString() + ); + expect(beforeConfiguration).toBeDefined(); + expect(beforeConfiguration).toMatchObject({ + connected: false, + }); + + await dex.connectTokenStrategy(pool_id, pool_token_id, lending_market_id); + + await dex.updateStorage({ pools: [pool_id.toString()] }); + pool = dex.storage.storage.pools[pool_id.toString()]; + const updatedConfiguration = pool.strategy.configuration.get( + pool_token_id.toString() + ); + expect(updatedConfiguration).toMatchObject({ + connected: true, + }); +} + +export async function connectTokenStrategyFailCaseAdded( + dex: Dex, + pool_id: BigNumber, + pool_token_id: BigNumber, + lending_market_id: BigNumber +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + let pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const beforeConfiguration = pool.strategy.configuration.get( + pool_token_id.toString() + ); + expect(beforeConfiguration).toBeDefined(); + expect(beforeConfiguration).toMatchObject({ + connected: true, + }); + + await expect( + dex.connectTokenStrategy(pool_id, pool_token_id, lending_market_id) + ).rejects.toMatchObject({ + message: "token-strategy-connected", + }); + await dex.updateStorage({ pools: [pool_id.toString()] }); + pool = dex.storage.storage.pools[pool_id.toString()]; + const updatedConfiguration = pool.strategy.configuration.get( + pool_token_id.toString() + ); + expect(updatedConfiguration).toMatchObject({ + connected: true, + }); +} + +export async function connectTokenStrategyFailCaseNoStrategy( + dex: Dex, + pool_id: BigNumber, + pool_token_id: BigNumber, + lending_market_id: BigNumber +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + let pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + expect(pool.strategy.strat_contract).toBeNull(); + const beforeConfiguration = pool.strategy.configuration.get( + pool_token_id.toString() + ); + expect(beforeConfiguration).toBeDefined(); + expect(beforeConfiguration).toMatchObject({ + connected: false, + }); + + await expect( + dex.connectTokenStrategy(pool_id, pool_token_id, lending_market_id) + ).rejects.toMatchObject({ + message: "no-connected-strategy", + }); + await dex.updateStorage({ pools: [pool_id.toString()] }); + pool = dex.storage.storage.pools[pool_id.toString()]; + const updatedConfiguration = pool.strategy.configuration.get( + pool_token_id.toString() + ); + expect(updatedConfiguration).toMatchObject({ + connected: false, + }); +} \ No newline at end of file diff --git a/test/Dex/cases/strategy/cofigure-token/index.ts b/test/Dex/cases/strategy/cofigure-token/index.ts index 4987a0c..546c873 100644 --- a/test/Dex/cases/strategy/cofigure-token/index.ts +++ b/test/Dex/cases/strategy/cofigure-token/index.ts @@ -1,4 +1,4 @@ export * as configureTokenStrategy from "./configure_strategy"; -// export * as connectTokenToStrategy from "./connect_token"; +export * as connectTokenToStrategy from "./connect_token"; export * as setStrategyRebalance from "./is_rebalance"; -// export * as manualRebalanceToken from "./rebalance"; \ No newline at end of file +export * as manualRebalanceToken from "./rebalance"; \ No newline at end of file diff --git a/test/Dex/cases/strategy/cofigure-token/rebalance.ts b/test/Dex/cases/strategy/cofigure-token/rebalance.ts index e69de29..4fb5005 100644 --- a/test/Dex/cases/strategy/cofigure-token/rebalance.ts +++ b/test/Dex/cases/strategy/cofigure-token/rebalance.ts @@ -0,0 +1,32 @@ +import BigNumber from "bignumber.js"; +import { TezosToolkit, Contract } from "@taquito/taquito"; +import Dex from "../../../API"; +import { PairInfo } from "../../../API/types"; + +export async function manualRebalanceSuccessCase( + dex: Dex, + yupana: Contract, + strategy: Contract, + pool_id: BigNumber, + pool_token_ids: Set +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + let pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const strategyStore = pool.strategy; + expect(strategyStore.strat_contract).toBeDefined(); + + await dex.rebalance(pool_id, pool_token_ids); + + await dex.updateStorage({ pools: [pool_id.toString()] }); + pool = dex.storage.storage.pools[pool_id.toString()]; + pool.strategy.configuration.forEach((value, key) => { + const on_strat = value.strategy_reserves; + const full_res = pool.tokens_info.get(key).reserves; + console.debug( + `[${key.toString()}] - full: ${full_res}, on strategy: ${on_strat} (${on_strat + .div(full_res) + .multipliedBy(100)}%)` + ); + }); +} diff --git a/test/Dex/cases/strategy/connect.ts b/test/Dex/cases/strategy/connect.ts index 542bebf..aa3888b 100644 --- a/test/Dex/cases/strategy/connect.ts +++ b/test/Dex/cases/strategy/connect.ts @@ -42,5 +42,4 @@ export async function removeStrategyAddrSuccessCase( expect(updatedStrat).toBeNull(); // TODO: Remove liquidity from old Strategy checks - } diff --git a/test/Dex/cases/strategy/index.ts b/test/Dex/cases/strategy/index.ts index 039cf93..1c58321 100644 --- a/test/Dex/cases/strategy/index.ts +++ b/test/Dex/cases/strategy/index.ts @@ -6,4 +6,9 @@ export const strategyCases = { connect: strategyConnect, }; -export default strategyCases; +import * as before from "./before"; + +export default { + before, + cases: strategyCases, +}; diff --git a/test/Factory/API/factoryAPI.ts b/test/Factory/API/factoryAPI.ts index a085d46..3c058b7 100644 --- a/test/Factory/API/factoryAPI.ts +++ b/test/Factory/API/factoryAPI.ts @@ -23,11 +23,12 @@ import { defaultTokenId, TokenFA12, TokenFA2 } from "../../Token"; import { FeeType, TokenInfo } from "../../Dex/API/types"; import fs from "fs"; import { DevEnabledContract } from "../../Developer/API/devAPI"; +import { StrategyFactorySetter } from "../../Strategy/API/strategyFactoryMethod"; const init_func_bytes = fs .readFileSync("./build/lambdas/factory/add_pool.txt") .toString(); -export class DexFactory implements DevEnabledContract { +export class DexFactory implements DevEnabledContract, StrategyFactorySetter { public contract: ContractAbstraction; public storage: FactoryStorage; @@ -275,4 +276,25 @@ export class DexFactory implements DevEnabledContract { await op.confirmation(2); return operation; } + + async manageStrategyFactories( + strategy_factory: string, + add: boolean + ): Promise { + const op = await this.contract.methods + .set_strategy_factory(add, strategy_factory) + .send(); + await op.confirmation(2); + return op; + } + async addStrategyFactory( + strategy_factory: string + ): Promise { + return this.manageStrategyFactories(strategy_factory, true); + } + async removeStrategyFactory( + strategy_factory: string + ): Promise { + return this.manageStrategyFactories(strategy_factory, false); + } } diff --git a/test/Factory/API/storage.ts b/test/Factory/API/storage.ts index 15af417..a52678e 100644 --- a/test/Factory/API/storage.ts +++ b/test/Factory/API/storage.ts @@ -20,7 +20,7 @@ export const factory_storage: FactoryStorage = { quipu_rewards: new BigNumber(0), whitelist: [] as TezosAddress[], deployers: new MichelsonMap(), - strategy_factory: "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg", + strategy_factory: [] as TezosAddress[], } as InnerFactoryStore, admin_lambdas: new MichelsonMap(), dex_lambdas: new MichelsonMap(), diff --git a/test/Factory/API/types.ts b/test/Factory/API/types.ts index 492a77d..0ac1602 100644 --- a/test/Factory/API/types.ts +++ b/test/Factory/API/types.ts @@ -14,6 +14,7 @@ export declare type InnerFactoryStore = { quipu_rewards: BigNumber; whitelist: TezosAddress[]; deployers: MichelsonMap; + strategy_factory: TezosAddress[]; }; export declare type FactoryStorage = { diff --git a/test/Factory/cases/before.ts b/test/Factory/cases/before.ts index 4bbef6c..faaaff3 100644 --- a/test/Factory/cases/before.ts +++ b/test/Factory/cases/before.ts @@ -33,7 +33,6 @@ export async function setupFactoryEnvironment( const config = await prepareProviderOptions(developer); Tezos.setProvider(config); const quipuToken = await setupQuipuGovToken(Tezos); - const lambdaContractAddress = op.contractAddress; storage.storage.dev_store = { dev_address: accounts[developer].pkh, dev_fee_f: new BigNumber(0), diff --git a/test/Factory/cases/dev.ts b/test/Factory/cases/dev.ts index 00dbd8c..7090d83 100644 --- a/test/Factory/cases/dev.ts +++ b/test/Factory/cases/dev.ts @@ -2,3 +2,7 @@ export { setDevAddrSuccessCase, setDevFeeSuccessCase, } from "../../Developer/cases"; +export { + addStrategyFactorySuccessCase, + removeStrategyFactorySuccessCase, +} from "../../Strategy/cases"; diff --git a/test/Strategy/API/strategyFactoryMethod.ts b/test/Strategy/API/strategyFactoryMethod.ts new file mode 100644 index 0000000..e1b7585 --- /dev/null +++ b/test/Strategy/API/strategyFactoryMethod.ts @@ -0,0 +1,23 @@ +import { Contract } from "../../utils/types"; +import { TezosAddress } from "../../../utils/helpers"; +import { DevStorage } from "../../Developer/API/storage"; +import { TezosToolkit, TransactionOperation } from "@taquito/taquito"; + +export declare interface StrategyFactorySetter extends Contract { + storage: any & { + storage: any & { + dev_store: DevStorage; + strategy_factory: TezosAddress[]; + }; + }; + manageStrategyFactories: ( + strategy_factory: TezosAddress, + add: boolean + ) => Promise; + addStrategyFactory: ( + strategy_factory: TezosAddress + ) => Promise; + removeStrategyFactory: ( + strategy_factory: TezosAddress + ) => Promise; +} diff --git a/test/Strategy/cases/index.ts b/test/Strategy/cases/index.ts new file mode 100644 index 0000000..db5cb7b --- /dev/null +++ b/test/Strategy/cases/index.ts @@ -0,0 +1,34 @@ +import { TezosAddress } from "../../../utils/helpers"; +import { StrategyFactorySetter } from "../API/strategyFactoryMethod"; + +export async function addStrategyFactorySuccessCase( + contract: StrategyFactorySetter, + strategy_factory: TezosAddress +) { + await contract.updateStorage({}); + const factories: Set = + contract.storage.storage.strategy_factory; + expect(factories).not.toContain(strategy_factory); + await contract.addStrategyFactory(strategy_factory); + + await contract.updateStorage({}); + const new_factories: Set = + contract.storage.storage.strategy_factory; + expect(new_factories).toContain(strategy_factory); +} + +export async function removeStrategyFactorySuccessCase( + contract: StrategyFactorySetter, + strategy_factory: TezosAddress +) { + await contract.updateStorage({}); + const factories: Set = + contract.storage.storage.strategy_factory; + expect(factories).toContain(strategy_factory); + await contract.removeStrategyFactory(strategy_factory); + + await contract.updateStorage({}); + const new_factories: Set = + contract.storage.storage.strategy_factory; + expect(new_factories).not.toContain(strategy_factory); +} diff --git a/test/utils/mocks/artifacts/pf.tz b/test/utils/mocks/artifacts/pf.tz new file mode 100644 index 0000000..314ea1e --- /dev/null +++ b/test/utils/mocks/artifacts/pf.tz @@ -0,0 +1,43 @@ +{ parameter + (or (or (unit %default) (set %getPrice nat)) + (pair %setPrice (nat %token_id) (nat %price))) ; + storage (pair (address %yToken) (big_map %prices nat nat)) ; + code { UNPAIR ; + IF_LEFT + { IF_LEFT + { DROP 2 ; PUSH string "42" ; FAILWITH } + { DUP 2 ; + NIL operation ; + DIG 2 ; + ITER { SWAP ; + PUSH string "wrong Yupana pCb entrypoint" ; + DUP 5 ; + CAR ; + CONTRACT %priceCallback (pair (nat %tokenId) (nat %amount)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DUP 6 ; + CDR ; + DUP 5 ; + GET ; + IF_NONE { PUSH nat 1000000 } {} ; + DIG 4 ; + PAIR ; + TRANSFER_TOKENS ; + CONS } ; + DIG 2 ; + DROP ; + PAIR } } + { DUP 2 ; + DIG 2 ; + CDR ; + DUP 3 ; + CDR ; + SOME ; + DIG 3 ; + CAR ; + UPDATE ; + UPDATE 2 ; + NIL operation ; + PAIR } } } + diff --git a/test/utils/mocks/artifacts/strategy.tz b/test/utils/mocks/artifacts/strategy.tz new file mode 100644 index 0000000..4192b72 --- /dev/null +++ b/test/utils/mocks/artifacts/strategy.tz @@ -0,0 +1,651 @@ +{ parameter + (or (or (or %dev_part + (list %claim_rewards nat) + (pair %update_lending (address %lending_contract) (address %price_feed_contract))) + (or %dex_part + (pair %update_token_info + (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + (nat %pool_token_id) + (nat %lending_market_id)) + (list %update_token_state (pair (nat %pool_token_id) (nat %new_balance))))) + (list %prepare nat)) ; + storage + (pair (address %factory) + (pair %lending_data (address %lending_contract) (address %price_feed_contract)) + (pair %pool_data (address %pool_contract) (nat %pool_id)) + (map %token_map + nat + (pair (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + (nat %lending_market_id) + (nat %invested_tokens) + (timestamp %upd_time) + (bool %approved) + (timestamp %prepared_time)))) ; + code { LAMBDA + (pair (pair (pair nat nat) address bool) bool) + nat + { UNPAIR ; + UNPAIR ; + UNPAIR ; + DIG 2 ; + UNPAIR ; + PUSH string "Lending has no suited convert view" ; + SWAP ; + DIG 5 ; + DIG 4 ; + DIG 5 ; + DIG 5 ; + PAIR 4 ; + VIEW "convert" + (pair (nat %amount) (timestamp %interestUpdateTime) (timestamp %priceUpdateTime)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + CAR } ; + PUSH string "Factory has no suited dev_address view" ; + PUSH string "No Token yet" ; + PUSH string "Contract hasn't update_operators/approve entrypoint" ; + PUSH string "Contract has no transfer entrypoint" ; + PUSH string "'Update interest' and 'get price' for market should be called" ; + LAMBDA + (pair (option address) string) + address + { UNPAIR ; IF_NONE { FAILWITH } { SWAP ; DROP } } ; + LAMBDA + int + nat + { ISNAT ; IF_NONE { PUSH string "Value is not natural" ; FAILWITH } {} } ; + PUSH timestamp 946684800 ; + PUSH bool False ; + NOW ; + PUSH nat 0 ; + PUSH nat 0 ; + PUSH address "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg" ; + LEFT (pair address nat) ; + PAIR 6 ; + DIG 9 ; + UNPAIR ; + SWAP ; + PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + GT ; + IF { PUSH string "Sending XTZ not allowed here" ; FAILWITH } {} ; + SWAP ; + IF_LEFT + { IF_LEFT + { DIG 2 ; + DIG 7 ; + DROP 2 ; + PUSH string "Only developer is allowed here" ; + DUP 9 ; + DUP 4 ; + CAR ; + UNIT ; + VIEW "dev_address" address ; + PAIR ; + DUP 6 ; + SWAP ; + EXEC ; + SENDER ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + IF_LEFT + { SWAP ; + NIL operation ; + DUP 2 ; + GET 6 ; + PUSH bool True ; + DUP 4 ; + GET 3 ; + CAR ; + DUP 6 ; + MAP { DUP 4 ; SWAP ; GET ; IF_NONE { DUP 11 ; FAILWITH } {} ; GET 3 } ; + DIG 3 ; + DROP ; + PUSH string "Lending has no suited balanceOf view" ; + DIG 2 ; + DIG 3 ; + DIG 3 ; + MAP { SELF_ADDRESS ; PAIR } ; + PAIR ; + VIEW "balanceOf" + (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + EMPTY_MAP nat nat ; + SWAP ; + ITER { SWAP ; DUP 2 ; CDR ; SOME ; DIG 2 ; CAR ; CDR ; UPDATE } ; + DIG 3 ; + ITER { DUP 9 ; + DUP 5 ; + GET 6 ; + DUP 3 ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 8 ; + NOW ; + DUP 3 ; + GET 10 ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + PUSH nat 1 ; + DUP 4 ; + DIG 3 ; + GET ; + IF_NONE + { PUSH string "No balance for token returned in balance response" ; FAILWITH } + {} ; + SUB ; + DUP 6 ; + SWAP ; + EXEC ; + PUSH bool True ; + PUSH bool False ; + DUP 7 ; + GET 3 ; + CAR ; + PAIR ; + DUP 4 ; + GET 3 ; + DIG 3 ; + PAIR ; + PAIR ; + PAIR ; + DUP 12 ; + SWAP ; + EXEC ; + DUP 2 ; + GET 5 ; + SWAP ; + SUB ; + DUP 6 ; + SWAP ; + EXEC ; + DIG 3 ; + DUP 3 ; + CAR ; + DUP 3 ; + PAIR ; + DUP 6 ; + CAR ; + DUP 13 ; + SWAP ; + UNIT ; + VIEW "dev_address" address ; + PAIR ; + DUP 9 ; + SWAP ; + EXEC ; + SELF_ADDRESS ; + DIG 2 ; + UNPAIR ; + SWAP ; + IF_LEFT + { DUP 13 ; + SWAP ; + CONTRACT %transfer (pair (address %from) (address %to) (nat %value)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 2 ; + DIG 4 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS } + { DUP 13 ; + DUP 2 ; + CAR ; + CONTRACT %transfer + (list (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount))))) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + NIL (pair address (list (pair address nat nat))) ; + NIL (pair address nat nat) ; + DIG 5 ; + DIG 5 ; + CDR ; + DIG 7 ; + PAIR 3 ; + CONS ; + DIG 4 ; + PAIR ; + CONS ; + TRANSFER_TOKENS } ; + CONS ; + DUP 5 ; + GET 3 ; + CDR ; + PUSH string "Lending has no suited redeem entrypoint" ; + SWAP ; + CONTRACT %redeem (pair (nat %tokenId) (nat %amount) (nat %minReceived)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DUP 4 ; + DIG 4 ; + DIG 5 ; + GET 3 ; + PAIR 3 ; + TRANSFER_TOKENS ; + CONS ; + SWAP } ; + DIG 3 ; + DIG 4 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DIG 8 ; + DIG 9 ; + DROP 8 } + { DIG 2 ; + DIG 3 ; + DIG 4 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DIG 8 ; + DROP 7 ; + UPDATE 3 ; + NIL operation } } + { DIG 4 ; + DIG 9 ; + DROP 2 ; + PUSH string "Only dex is allowed here" ; + DUP 3 ; + GET 5 ; + CAR ; + SENDER ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + IF_LEFT + { DIG 3 ; + DIG 4 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DIG 8 ; + DROP 6 ; + SWAP ; + PUSH string "Token already added" ; + DUP 2 ; + GET 6 ; + DUP 4 ; + GET 3 ; + MEM ; + NOT ; + IF { DROP } { FAILWITH } ; + DUP ; + GET 6 ; + DIG 3 ; + DUP 4 ; + CAR ; + UPDATE 1 ; + DUP 4 ; + GET 4 ; + UPDATE 3 ; + DIG 3 ; + GET 3 ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 6 ; + NIL operation } + { DIG 2 ; + DROP ; + SWAP ; + NIL operation ; + EMPTY_MAP + nat + (pair (pair (or address (pair address nat)) nat nat timestamp bool timestamp) nat) ; + DIG 3 ; + ITER { DUP 9 ; + DUP 5 ; + GET 6 ; + DUP 3 ; + CAR ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 7 ; + NOW ; + DUP 3 ; + GET 10 ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + DUP ; + GET 5 ; + DUP 3 ; + CDR ; + SUB ; + ISNAT ; + IF_NONE + { DUP 2 ; + CDR ; + DUP 2 ; + GET 5 ; + SUB ; + DUP 7 ; + SWAP ; + EXEC ; + DIG 4 ; + DUP 3 ; + CAR ; + DUP 3 ; + PAIR ; + DUP 7 ; + GET 5 ; + CAR ; + SELF_ADDRESS ; + DIG 2 ; + UNPAIR ; + SWAP ; + IF_LEFT + { DUP 13 ; + SWAP ; + CONTRACT %transfer (pair (address %from) (address %to) (nat %value)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 2 ; + DIG 4 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS } + { DUP 13 ; + DUP 2 ; + CAR ; + CONTRACT %transfer + (list (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount))))) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + NIL (pair address (list (pair address nat nat))) ; + NIL (pair address nat nat) ; + DIG 5 ; + DIG 5 ; + CDR ; + DIG 7 ; + PAIR 3 ; + CONS ; + DIG 4 ; + PAIR ; + CONS ; + TRANSFER_TOKENS } ; + CONS ; + DUP 6 ; + GET 3 ; + CAR ; + PUSH string "Lending has no suited redeem entrypoint" ; + SWAP ; + CONTRACT %redeem (pair (nat %tokenId) (nat %amount) (nat %minReceived)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DUP 4 ; + DIG 4 ; + DUP 6 ; + GET 3 ; + PAIR 3 ; + TRANSFER_TOKENS ; + CONS ; + DUG 3 } + { PUSH bool False ; + PUSH bool True ; + DUP 8 ; + GET 3 ; + CAR ; + PAIR ; + DUP 4 ; + GET 3 ; + DUP 4 ; + PAIR ; + PAIR ; + PAIR ; + DUP 13 ; + SWAP ; + EXEC ; + PUSH nat 0 ; + DUP 2 ; + COMPARE ; + GT ; + PUSH nat 0 ; + DUP 4 ; + COMPARE ; + GT ; + AND ; + IF { DIG 5 ; + DUP 7 ; + GET 3 ; + CAR ; + PUSH string "Lending has no suited mint entrypoint" ; + SWAP ; + CONTRACT %mint (pair (nat %tokenId) (nat %amount) (nat %minReceived)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 3 ; + DUP 5 ; + DUP 7 ; + GET 3 ; + PAIR 3 ; + TRANSFER_TOKENS ; + CONS ; + DUG 4 ; + DIG 3 ; + SWAP ; + DUP 3 ; + PAIR ; + DUP 4 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + DUG 2 } + { DROP 2 } } ; + DUP 5 ; + DIG 5 ; + GET 6 ; + DIG 2 ; + DUP 4 ; + CDR ; + UPDATE 5 ; + NOW ; + UPDATE 7 ; + DIG 3 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 6 ; + DUG 2 } ; + DIG 3 ; + DIG 4 ; + DIG 5 ; + DIG 8 ; + DROP 4 ; + DUP 3 ; + GET 3 ; + CAR ; + SWAP ; + EMPTY_MAP nat bool ; + NIL operation ; + PAIR ; + SWAP ; + ITER { SWAP ; + DUP 2 ; + CDR ; + DUP ; + CAR ; + GET 9 ; + NOT ; + IF { DUP 2 ; + DIG 2 ; + CAR ; + DUP 3 ; + CAR ; + CAR ; + DUP 4 ; + CDR ; + PAIR ; + DUP 6 ; + SELF_ADDRESS ; + DIG 2 ; + UNPAIR ; + SWAP ; + IF_LEFT + { DIG 2 ; + DROP ; + DUP 11 ; + SWAP ; + CONTRACT %approve (pair (address %spender) (nat %value)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 2 ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS } + { DUP 12 ; + DUP 2 ; + CAR ; + CONTRACT %update_operators + (list (or (pair %add_operator (address %owner) (address %operator) (nat %token_id)) + (pair %remove_operator (address %owner) (address %operator) (nat %token_id)))) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + NIL (or (pair address address nat) (pair address address nat)) ; + PUSH nat 0 ; + DIG 5 ; + COMPARE ; + GT ; + IF { DIG 3 ; CDR ; DIG 5 ; DIG 5 ; PAIR 3 ; LEFT (pair address address nat) } + { DIG 3 ; CDR ; DIG 5 ; DIG 5 ; PAIR 3 ; RIGHT (pair address address nat) } ; + CONS ; + TRANSFER_TOKENS } ; + CONS ; + UPDATE 1 ; + SWAP } + {} ; + DUP ; + CAR ; + CAR ; + IF_LEFT + { SWAP ; DIG 3 ; DROP 3 } + { DROP ; + CAR ; + GET 9 ; + NOT ; + IF { DUP ; + CDR ; + PUSH bool True ; + DIG 3 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 2 } + { SWAP ; DROP } } } ; + SWAP ; + DIG 4 ; + DROP 2 ; + DUP ; + CDR ; + ITER { UNPAIR ; + DUP 5 ; + DUP 6 ; + GET 6 ; + DUP 8 ; + DIG 7 ; + GET 6 ; + DUP 5 ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DIG 4 ; + UPDATE 9 ; + DIG 3 ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 6 ; + DUG 2 } ; + DIG 3 ; + DROP ; + CAR ; + NIL operation ; + SWAP ; + ITER { CONS } ; + ITER { CONS } } } } + { DIG 2 ; + DIG 3 ; + DIG 4 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DIG 9 ; + DIG 10 ; + DROP 8 ; + SWAP ; + NIL operation ; + EMPTY_SET nat ; + DIG 3 ; + ITER { DUP 5 ; + DUP 5 ; + GET 6 ; + DUP 3 ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DIG 2 ; + DUP 2 ; + GET 3 ; + PUSH bool True ; + SWAP ; + UPDATE ; + DUG 2 ; + DIG 3 ; + DUP 5 ; + GET 3 ; + CAR ; + PUSH string "Lending has no suited updateInterest entrypoint" ; + SWAP ; + CONTRACT %updateInterest nat ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DUP 4 ; + GET 3 ; + TRANSFER_TOKENS ; + CONS ; + DUG 3 ; + DUP 5 ; + DIG 5 ; + GET 6 ; + DIG 2 ; + NOW ; + UPDATE 10 ; + DIG 3 ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 6 ; + DUG 2 } ; + DIG 3 ; + DROP ; + SWAP ; + DUP 3 ; + GET 3 ; + CDR ; + PUSH string "Lending's PriceFeed has no suited getPrice entrypoint" ; + SWAP ; + CONTRACT %getPrice (set nat) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 3 ; + TRANSFER_TOKENS ; + CONS } ; + PAIR } ; + view "get_pool_data" + unit + (pair (address %pool_contract) (nat %pool_id)) + { CDR ; GET 5 } } + diff --git a/test/utils/mocks/artifacts/strategy_factory.tz b/test/utils/mocks/artifacts/strategy_factory.tz new file mode 100644 index 0000000..aa03621 --- /dev/null +++ b/test/utils/mocks/artifacts/strategy_factory.tz @@ -0,0 +1,754 @@ +{ parameter + (or (pair %deploy_strategy + (pair %pool_info (address %pool_contract) (nat %pool_id)) + (pair %lending_data (address %lending_contract) (address %price_feed_contract))) + (or %use_dev (unit %approve_developer) (address %change_developer))) ; + storage + (pair (pair %dev (address %dev_address) (option %temp_dev_address address)) + (big_map %deployed_strategies + (pair (address %pool_contract) (nat %pool_id)) + address) + (big_map %connected_pools address (pair (address %pool_contract) (nat %pool_id)))) ; + code { PUSH string "Only developer is allowed here" ; + SWAP ; + UNPAIR ; + SWAP ; + PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + GT ; + IF { PUSH string "Sending XTZ not allowed here" ; FAILWITH } {} ; + SWAP ; + IF_LEFT + { SWAP ; + DIG 2 ; + DUP 2 ; + CAR ; + CAR ; + SENDER ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + EMPTY_MAP nat (pair (or address (pair address nat)) nat nat timestamp bool timestamp) ; + DUP 3 ; + CAR ; + DUP 4 ; + CDR ; + SELF_ADDRESS ; + PAIR 4 ; + PUSH mutez 0 ; + NONE key_hash ; + PAIR ; + PAIR ; + UNPPAIIR ; + CREATE_CONTRACT + { parameter + (or (or (or %dev_part + (list %claim_rewards nat) + (pair %update_lending (address %lending_contract) (address %price_feed_contract))) + (or %dex_part + (pair %update_token_info + (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + (nat %pool_token_id) + (nat %lending_market_id)) + (list %update_token_state (pair (nat %pool_token_id) (nat %new_balance))))) + (list %prepare nat)) ; + storage + (pair (address %factory) + (pair %lending_data (address %lending_contract) (address %price_feed_contract)) + (pair %pool_data (address %pool_contract) (nat %pool_id)) + (map %token_map + nat + (pair (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + (nat %lending_market_id) + (nat %invested_tokens) + (timestamp %upd_time) + (bool %approved) + (timestamp %prepared_time)))) ; + code { LAMBDA + (pair (pair (pair nat nat) address bool) bool) + nat + { UNPAIR ; + UNPAIR ; + UNPAIR ; + DIG 2 ; + UNPAIR ; + PUSH string "Lending has no suited convert view" ; + SWAP ; + DIG 5 ; + DIG 4 ; + DIG 5 ; + DIG 5 ; + PAIR 4 ; + VIEW "convert" + (pair (nat %amount) (timestamp %interestUpdateTime) (timestamp %priceUpdateTime)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + CAR } ; + PUSH string "Factory has no suited dev_address view" ; + PUSH string "No Token yet" ; + PUSH string "Contract hasn't update_operators/approve entrypoint" ; + PUSH string "Contract has no transfer entrypoint" ; + PUSH string "'Update interest' and 'get price' for market should be called" ; + LAMBDA + (pair (option address) string) + address + { UNPAIR ; IF_NONE { FAILWITH } { SWAP ; DROP } } ; + LAMBDA + int + nat + { ISNAT ; IF_NONE { PUSH string "Value is not natural" ; FAILWITH } {} } ; + PUSH timestamp 946684800 ; + PUSH bool False ; + NOW ; + PUSH nat 0 ; + PUSH nat 0 ; + PUSH address "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg" ; + LEFT (pair address nat) ; + PAIR 6 ; + DIG 9 ; + UNPAIR ; + SWAP ; + PUSH mutez 0 ; + AMOUNT ; + COMPARE ; + GT ; + IF { PUSH string "Sending XTZ not allowed here" ; FAILWITH } {} ; + SWAP ; + IF_LEFT + { IF_LEFT + { DIG 2 ; + DIG 7 ; + DROP 2 ; + PUSH string "Only developer is allowed here" ; + DUP 9 ; + DUP 4 ; + CAR ; + UNIT ; + VIEW "dev_address" address ; + PAIR ; + DUP 6 ; + SWAP ; + EXEC ; + SENDER ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + IF_LEFT + { SWAP ; + NIL operation ; + DUP 2 ; + GET 6 ; + PUSH bool True ; + DUP 4 ; + GET 3 ; + CAR ; + DUP 6 ; + MAP { DUP 4 ; SWAP ; GET ; IF_NONE { DUP 11 ; FAILWITH } {} ; GET 3 } ; + DIG 3 ; + DROP ; + PUSH string "Lending has no suited balanceOf view" ; + DIG 2 ; + DIG 3 ; + DIG 3 ; + MAP { SELF_ADDRESS ; PAIR } ; + PAIR ; + VIEW "balanceOf" + (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + EMPTY_MAP nat nat ; + SWAP ; + ITER { SWAP ; DUP 2 ; CDR ; SOME ; DIG 2 ; CAR ; CDR ; UPDATE } ; + DIG 3 ; + ITER { DUP 9 ; + DUP 5 ; + GET 6 ; + DUP 3 ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 8 ; + NOW ; + DUP 3 ; + GET 10 ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + PUSH nat 1 ; + DUP 4 ; + DIG 3 ; + GET ; + IF_NONE + { PUSH string "No balance for token returned in balance response" ; FAILWITH } + {} ; + SUB ; + DUP 6 ; + SWAP ; + EXEC ; + PUSH bool True ; + PUSH bool False ; + DUP 7 ; + GET 3 ; + CAR ; + PAIR ; + DUP 4 ; + GET 3 ; + DIG 3 ; + PAIR ; + PAIR ; + PAIR ; + DUP 12 ; + SWAP ; + EXEC ; + DUP 2 ; + GET 5 ; + SWAP ; + SUB ; + DUP 6 ; + SWAP ; + EXEC ; + DIG 3 ; + DUP 3 ; + CAR ; + DUP 3 ; + PAIR ; + DUP 6 ; + CAR ; + DUP 13 ; + SWAP ; + UNIT ; + VIEW "dev_address" address ; + PAIR ; + DUP 9 ; + SWAP ; + EXEC ; + SELF_ADDRESS ; + DIG 2 ; + UNPAIR ; + SWAP ; + IF_LEFT + { DUP 13 ; + SWAP ; + CONTRACT %transfer (pair (address %from) (address %to) (nat %value)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 2 ; + DIG 4 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS } + { DUP 13 ; + DUP 2 ; + CAR ; + CONTRACT %transfer + (list (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount))))) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + NIL (pair address (list (pair address nat nat))) ; + NIL (pair address nat nat) ; + DIG 5 ; + DIG 5 ; + CDR ; + DIG 7 ; + PAIR 3 ; + CONS ; + DIG 4 ; + PAIR ; + CONS ; + TRANSFER_TOKENS } ; + CONS ; + DUP 5 ; + GET 3 ; + CDR ; + PUSH string "Lending has no suited redeem entrypoint" ; + SWAP ; + CONTRACT %redeem (pair (nat %tokenId) (nat %amount) (nat %minReceived)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DUP 4 ; + DIG 4 ; + DIG 5 ; + GET 3 ; + PAIR 3 ; + TRANSFER_TOKENS ; + CONS ; + SWAP } ; + DIG 3 ; + DIG 4 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DIG 8 ; + DIG 9 ; + DROP 8 } + { DIG 2 ; + DIG 3 ; + DIG 4 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DIG 8 ; + DROP 7 ; + UPDATE 3 ; + NIL operation } } + { DIG 4 ; + DIG 9 ; + DROP 2 ; + PUSH string "Only dex is allowed here" ; + DUP 3 ; + GET 5 ; + CAR ; + SENDER ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + IF_LEFT + { DIG 3 ; + DIG 4 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DIG 8 ; + DROP 6 ; + SWAP ; + PUSH string "Token already added" ; + DUP 2 ; + GET 6 ; + DUP 4 ; + GET 3 ; + MEM ; + NOT ; + IF { DROP } { FAILWITH } ; + DUP ; + GET 6 ; + DIG 3 ; + DUP 4 ; + CAR ; + UPDATE 1 ; + DUP 4 ; + GET 4 ; + UPDATE 3 ; + DIG 3 ; + GET 3 ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 6 ; + NIL operation } + { DIG 2 ; + DROP ; + SWAP ; + NIL operation ; + EMPTY_MAP + nat + (pair (pair (or address (pair address nat)) nat nat timestamp bool timestamp) nat) ; + DIG 3 ; + ITER { DUP 9 ; + DUP 5 ; + GET 6 ; + DUP 3 ; + CAR ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 7 ; + NOW ; + DUP 3 ; + GET 10 ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + DUP ; + GET 5 ; + DUP 3 ; + CDR ; + SUB ; + ISNAT ; + IF_NONE + { DUP 2 ; + CDR ; + DUP 2 ; + GET 5 ; + SUB ; + DUP 7 ; + SWAP ; + EXEC ; + DIG 4 ; + DUP 3 ; + CAR ; + DUP 3 ; + PAIR ; + DUP 7 ; + GET 5 ; + CAR ; + SELF_ADDRESS ; + DIG 2 ; + UNPAIR ; + SWAP ; + IF_LEFT + { DUP 13 ; + SWAP ; + CONTRACT %transfer (pair (address %from) (address %to) (nat %value)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 2 ; + DIG 4 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS } + { DUP 13 ; + DUP 2 ; + CAR ; + CONTRACT %transfer + (list (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount))))) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + NIL (pair address (list (pair address nat nat))) ; + NIL (pair address nat nat) ; + DIG 5 ; + DIG 5 ; + CDR ; + DIG 7 ; + PAIR 3 ; + CONS ; + DIG 4 ; + PAIR ; + CONS ; + TRANSFER_TOKENS } ; + CONS ; + DUP 6 ; + GET 3 ; + CAR ; + PUSH string "Lending has no suited redeem entrypoint" ; + SWAP ; + CONTRACT %redeem (pair (nat %tokenId) (nat %amount) (nat %minReceived)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DUP 4 ; + DIG 4 ; + DUP 6 ; + GET 3 ; + PAIR 3 ; + TRANSFER_TOKENS ; + CONS ; + DUG 3 } + { PUSH bool False ; + PUSH bool True ; + DUP 8 ; + GET 3 ; + CAR ; + PAIR ; + DUP 4 ; + GET 3 ; + DUP 4 ; + PAIR ; + PAIR ; + PAIR ; + DUP 13 ; + SWAP ; + EXEC ; + PUSH nat 0 ; + DUP 2 ; + COMPARE ; + GT ; + PUSH nat 0 ; + DUP 4 ; + COMPARE ; + GT ; + AND ; + IF { DIG 5 ; + DUP 7 ; + GET 3 ; + CAR ; + PUSH string "Lending has no suited mint entrypoint" ; + SWAP ; + CONTRACT %mint (pair (nat %tokenId) (nat %amount) (nat %minReceived)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 3 ; + DUP 5 ; + DUP 7 ; + GET 3 ; + PAIR 3 ; + TRANSFER_TOKENS ; + CONS ; + DUG 4 ; + DIG 3 ; + SWAP ; + DUP 3 ; + PAIR ; + DUP 4 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + DUG 2 } + { DROP 2 } } ; + DUP 5 ; + DIG 5 ; + GET 6 ; + DIG 2 ; + DUP 4 ; + CDR ; + UPDATE 5 ; + NOW ; + UPDATE 7 ; + DIG 3 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 6 ; + DUG 2 } ; + DIG 3 ; + DIG 4 ; + DIG 5 ; + DIG 8 ; + DROP 4 ; + DUP 3 ; + GET 3 ; + CAR ; + SWAP ; + EMPTY_MAP nat bool ; + NIL operation ; + PAIR ; + SWAP ; + ITER { SWAP ; + DUP 2 ; + CDR ; + DUP ; + CAR ; + GET 9 ; + NOT ; + IF { DUP 2 ; + DIG 2 ; + CAR ; + DUP 3 ; + CAR ; + CAR ; + DUP 4 ; + CDR ; + PAIR ; + DUP 6 ; + SELF_ADDRESS ; + DIG 2 ; + UNPAIR ; + SWAP ; + IF_LEFT + { DIG 2 ; + DROP ; + DUP 11 ; + SWAP ; + CONTRACT %approve (pair (address %spender) (nat %value)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 2 ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS } + { DUP 12 ; + DUP 2 ; + CAR ; + CONTRACT %update_operators + (list (or (pair %add_operator (address %owner) (address %operator) (nat %token_id)) + (pair %remove_operator (address %owner) (address %operator) (nat %token_id)))) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + NIL (or (pair address address nat) (pair address address nat)) ; + PUSH nat 0 ; + DIG 5 ; + COMPARE ; + GT ; + IF { DIG 3 ; CDR ; DIG 5 ; DIG 5 ; PAIR 3 ; LEFT (pair address address nat) } + { DIG 3 ; CDR ; DIG 5 ; DIG 5 ; PAIR 3 ; RIGHT (pair address address nat) } ; + CONS ; + TRANSFER_TOKENS } ; + CONS ; + UPDATE 1 ; + SWAP } + {} ; + DUP ; + CAR ; + CAR ; + IF_LEFT + { SWAP ; DIG 3 ; DROP 3 } + { DROP ; + CAR ; + GET 9 ; + NOT ; + IF { DUP ; + CDR ; + PUSH bool True ; + DIG 3 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 2 } + { SWAP ; DROP } } } ; + SWAP ; + DIG 4 ; + DROP 2 ; + DUP ; + CDR ; + ITER { UNPAIR ; + DUP 5 ; + DUP 6 ; + GET 6 ; + DUP 8 ; + DIG 7 ; + GET 6 ; + DUP 5 ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DIG 4 ; + UPDATE 9 ; + DIG 3 ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 6 ; + DUG 2 } ; + DIG 3 ; + DROP ; + CAR ; + NIL operation ; + SWAP ; + ITER { CONS } ; + ITER { CONS } } } } + { DIG 2 ; + DIG 3 ; + DIG 4 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DIG 9 ; + DIG 10 ; + DROP 8 ; + SWAP ; + NIL operation ; + EMPTY_SET nat ; + DIG 3 ; + ITER { DUP 5 ; + DUP 5 ; + GET 6 ; + DUP 3 ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DIG 2 ; + DUP 2 ; + GET 3 ; + PUSH bool True ; + SWAP ; + UPDATE ; + DUG 2 ; + DIG 3 ; + DUP 5 ; + GET 3 ; + CAR ; + PUSH string "Lending has no suited updateInterest entrypoint" ; + SWAP ; + CONTRACT %updateInterest nat ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DUP 4 ; + GET 3 ; + TRANSFER_TOKENS ; + CONS ; + DUG 3 ; + DUP 5 ; + DIG 5 ; + GET 6 ; + DIG 2 ; + NOW ; + UPDATE 10 ; + DIG 3 ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 6 ; + DUG 2 } ; + DIG 3 ; + DROP ; + SWAP ; + DUP 3 ; + GET 3 ; + CDR ; + PUSH string "Lending's PriceFeed has no suited getPrice entrypoint" ; + SWAP ; + CONTRACT %getPrice (set nat) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 3 ; + TRANSFER_TOKENS ; + CONS } ; + PAIR } ; + view "get_pool_data" + unit + (pair (address %pool_contract) (nat %pool_id)) + { CDR ; GET 5 } } ; + DUP 3 ; + DIG 3 ; + GET 3 ; + DUP 4 ; + DUP 6 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 3 ; + DUG 2 ; + DUP 3 ; + DIG 3 ; + GET 4 ; + DIG 4 ; + CAR ; + DIG 4 ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 4 ; + NIL operation ; + DIG 2 ; + CONS } + { DUP 2 ; + DIG 2 ; + CAR ; + DIG 2 ; + IF_LEFT + { DROP ; + PUSH string "No new Admin awaited" ; + DUP 2 ; + CDR ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DIG 3 ; + SENDER ; + DUP 3 ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + UPDATE 1 ; + NONE address ; + UPDATE 2 } + { DIG 3 ; + SENDER ; + DUP 4 ; + CAR ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + SOME ; + UPDATE 2 } ; + UPDATE 1 ; + NIL operation } ; + PAIR } ; + view "dev_address" unit address { CDR ; CAR ; CAR } ; + view "is_registered" address bool { UNPAIR ; SWAP ; GET 4 ; SWAP ; MEM } } + diff --git a/test/utils/mocks/artifacts/yupana.tz b/test/utils/mocks/artifacts/yupana.tz new file mode 100644 index 0000000..f99b7ab --- /dev/null +++ b/test/utils/mocks/artifacts/yupana.tz @@ -0,0 +1,586 @@ +{ parameter + (or (or (or (pair %mint (nat %tokenId) (nat %amount) (nat %minReceived)) + (pair %priceCallback (nat %tokenId) (nat %amount))) + (or (pair %redeem (nat %tokenId) (nat %amount) (nat %minReceived)) + (pair %setExchangeRate (nat %marketId) (nat %rateF)))) + (or (address %setPriceFeed) (nat %updateInterest))) ; + storage + (pair (big_map %ledger (pair address nat) nat) + (big_map %tokens + nat + (pair (or %mainToken (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + (timestamp %interestUpdateTime) + (timestamp %priceUpdateTime) + (nat %exchangeRateF) + (nat %totalSupplyF) + (nat %totalLiquidityF) + (nat %lastPrice))) + (address %priceFeedProxy)) ; + code { PUSH string "Contract has no transfer entrypoint" ; + LAMBDA + (pair (option (contract (list (pair address (list (pair address nat nat)))))) string) + (contract (list (pair address (list (pair address nat nat))))) + { UNPAIR ; IF_NONE { FAILWITH } { SWAP ; DROP } } ; + LAMBDA + int + nat + { ISNAT ; IF_NONE { PUSH string "Value is not natural" ; FAILWITH } {} } ; + PUSH nat 1000000 ; + PUSH string "No market on lending" ; + LAMBDA + (pair nat + (pair (pair bool nat nat bool) + (big_map (pair address nat) nat) + (big_map + nat + (pair (or address (pair address nat)) timestamp timestamp nat nat nat nat)) + address)) + (pair nat timestamp timestamp) + { UNPAIR ; + SWAP ; + UNPAIR ; + SWAP ; + GET 3 ; + DUP 2 ; + GET 3 ; + GET ; + IF_NONE { PUSH string "No Token yet" ; FAILWITH } {} ; + DUP ; + GET 11 ; + DUP 3 ; + GET 5 ; + DUP 4 ; + CAR ; + IF { DIG 3 ; + GET 6 ; + IF { DUP 4 ; SWAP ; MUL } {} ; + PUSH nat 0 ; + DUP 3 ; + COMPARE ; + GT ; + IF { DIG 3 ; + DIG 2 ; + DUP 4 ; + GET 7 ; + DUP 5 ; + GET 9 ; + DIG 4 ; + MUL ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } + { SWAP ; DIG 3 ; DROP 3 ; PUSH nat 0 } } + { PUSH nat 0 ; + DUP 4 ; + GET 9 ; + COMPARE ; + GT ; + IF { DUP 3 ; + GET 7 ; + DUP 4 ; + GET 9 ; + DUP 7 ; + DIG 4 ; + DIG 4 ; + MUL ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } + { DROP 2 ; PUSH nat 0 } ; + DIG 2 ; + GET 6 ; + IF { DIG 2 ; + SWAP ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } + { DIG 2 ; DROP } } ; + DUP 2 ; + GET 5 ; + DIG 2 ; + GET 3 ; + DIG 2 ; + PAIR 3 } ; + DUP 3 ; + APPLY ; + DIG 6 ; + UNPAIR ; + SWAP ; + NIL operation ; + DIG 2 ; + IF_LEFT + { IF_LEFT + { DIG 6 ; + DROP ; + IF_LEFT + { DIG 4 ; + DUP 4 ; + GET 3 ; + DUP 3 ; + CAR ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH string "TIMEOUT" ; + DUP 2 ; + GET 3 ; + NOW ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + DUP 4 ; + DIG 4 ; + GET 3 ; + DUP 3 ; + DUP 8 ; + DUP 6 ; + GET 3 ; + MUL ; + DUP 5 ; + GET 9 ; + ADD ; + UPDATE 9 ; + DIG 7 ; + DUP 6 ; + GET 3 ; + MUL ; + DUP 5 ; + GET 11 ; + ADD ; + UPDATE 11 ; + DUP 5 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 3 ; + DUG 3 ; + DUP 4 ; + PUSH bool True ; + DUP 4 ; + GET 3 ; + DUP 5 ; + CAR ; + PUSH bool True ; + PAIR 4 ; + PAIR ; + DIG 5 ; + SWAP ; + EXEC ; + SENDER ; + DIG 4 ; + DIG 3 ; + CAR ; + DUP 5 ; + GET 3 ; + PAIR ; + SELF_ADDRESS ; + DUP 4 ; + DIG 2 ; + UNPAIR ; + SWAP ; + IF_LEFT + { DIG 9 ; + DROP ; + DIG 9 ; + SWAP ; + CONTRACT %transfer (pair (address %from) (address %to) (nat %value)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 2 ; + DIG 4 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS } + { DIG 10 ; + DUP 2 ; + CAR ; + CONTRACT %transfer + (list (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount))))) ; + PAIR ; + DIG 10 ; + SWAP ; + EXEC ; + PUSH mutez 0 ; + NIL (pair address (list (pair address nat nat))) ; + NIL (pair address nat nat) ; + DIG 5 ; + DIG 5 ; + CDR ; + DIG 7 ; + PAIR 3 ; + CONS ; + DIG 4 ; + PAIR ; + CONS ; + TRANSFER_TOKENS } ; + CONS ; + DUG 3 ; + DUP 5 ; + DUP 6 ; + CAR ; + DIG 3 ; + CAR ; + DIG 6 ; + CAR ; + DUP 6 ; + CAR ; + DUP 6 ; + PAIR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + ADD ; + DIG 4 ; + CAR ; + DIG 4 ; + PAIR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 1 } + { DIG 3 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DROP 4 ; + PUSH string "Only price feed is allowed here" ; + DUP 4 ; + GET 4 ; + SENDER ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + DUP 3 ; + DUP 4 ; + GET 3 ; + DIG 5 ; + DIG 5 ; + GET 3 ; + DUP 5 ; + CAR ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + NOW ; + UPDATE 5 ; + DUP 4 ; + CDR ; + UPDATE 12 ; + DIG 3 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 3 } } + { IF_LEFT + { DIG 4 ; + DUP 4 ; + GET 3 ; + DUP 3 ; + CAR ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH string "TIMEOUT" ; + DUP 2 ; + GET 3 ; + NOW ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + PUSH string "TIMEOUT" ; + DUP 2 ; + GET 5 ; + NOW ; + COMPARE ; + EQ ; + IF { DROP } { FAILWITH } ; + DUP 4 ; + DIG 4 ; + GET 3 ; + DUP 3 ; + DUP 8 ; + DUP 6 ; + GET 3 ; + MUL ; + DUP 5 ; + GET 9 ; + SUB ; + DUP 10 ; + SWAP ; + EXEC ; + UPDATE 9 ; + DIG 7 ; + DUP 6 ; + GET 3 ; + MUL ; + DUP 5 ; + GET 11 ; + SUB ; + DUP 9 ; + SWAP ; + EXEC ; + UPDATE 11 ; + DUP 5 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 3 ; + DUG 3 ; + DUP 4 ; + PUSH bool True ; + DUP 4 ; + GET 3 ; + DUP 5 ; + CAR ; + PUSH bool True ; + PAIR 4 ; + PAIR ; + DIG 5 ; + SWAP ; + EXEC ; + SENDER ; + DIG 4 ; + DIG 3 ; + CAR ; + DUP 5 ; + GET 3 ; + PAIR ; + DUP 3 ; + SELF_ADDRESS ; + DIG 2 ; + UNPAIR ; + SWAP ; + IF_LEFT + { DIG 10 ; + DROP ; + DIG 10 ; + SWAP ; + CONTRACT %transfer (pair (address %from) (address %to) (nat %value)) ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH mutez 0 ; + DIG 2 ; + DIG 4 ; + PAIR ; + DIG 3 ; + PAIR ; + TRANSFER_TOKENS } + { DIG 11 ; + DUP 2 ; + CAR ; + CONTRACT %transfer + (list (pair (address %from_) (list %txs (pair (address %to_) (nat %token_id) (nat %amount))))) ; + PAIR ; + DIG 11 ; + SWAP ; + EXEC ; + PUSH mutez 0 ; + NIL (pair address (list (pair address nat nat))) ; + NIL (pair address nat nat) ; + DIG 5 ; + DIG 5 ; + CDR ; + DIG 7 ; + PAIR 3 ; + CONS ; + DIG 4 ; + PAIR ; + CONS ; + TRANSFER_TOKENS } ; + CONS ; + DUG 3 ; + DUP 5 ; + DUP 6 ; + CAR ; + DIG 3 ; + CAR ; + DIG 6 ; + CAR ; + DUP 6 ; + CAR ; + DUP 6 ; + PAIR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + SUB ; + DIG 6 ; + SWAP ; + EXEC ; + DIG 4 ; + CAR ; + DIG 4 ; + PAIR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 1 } + { DIG 3 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DIG 8 ; + DROP 5 ; + DUP 3 ; + DUP 4 ; + GET 3 ; + DIG 5 ; + DIG 5 ; + GET 3 ; + DUP 5 ; + CAR ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 4 ; + CDR ; + UPDATE 7 ; + DIG 3 ; + CAR ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 3 } } } + { DIG 3 ; + DIG 5 ; + DIG 6 ; + DIG 7 ; + DIG 8 ; + DROP 5 ; + IF_LEFT + { DIG 3 ; DROP ; DIG 2 ; SWAP ; UPDATE 4 } + { DUP 3 ; + DUP 4 ; + GET 3 ; + DIG 5 ; + DIG 5 ; + GET 3 ; + DUP 5 ; + GET ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + NOW ; + UPDATE 3 ; + DIG 3 ; + SWAP ; + SOME ; + SWAP ; + UPDATE ; + UPDATE 3 } } ; + SWAP ; + PAIR } ; + view "balanceOf" + (pair (list %requests (pair (address %owner) (nat %token_id))) (bool %precision)) + (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))) + { UNPAIR ; + DUP ; + CAR ; + MAP { DUP 3 ; + CAR ; + DUP 2 ; + CDR ; + DUP 3 ; + CAR ; + PAIR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + DUP 3 ; + CDR ; + IF { PUSH nat 1000000 ; + SWAP ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } + {} ; + SWAP ; + PAIR } ; + SWAP ; + DIG 2 ; + DROP 2 } ; + view "convert" + (pair (bool %toShares) (nat %tokenId) (nat %amount) (bool %precision)) + (pair (nat %amount) (timestamp %interestUpdateTime) (timestamp %priceUpdateTime)) + { PUSH nat 1000000 ; + SWAP ; + UNPAIR ; + SWAP ; + GET 3 ; + DUP 2 ; + GET 3 ; + GET ; + IF_NONE { PUSH string "No Token yet" ; FAILWITH } {} ; + DUP ; + GET 11 ; + DUP 3 ; + GET 5 ; + DUP 4 ; + CAR ; + IF { DIG 3 ; + GET 6 ; + IF { DUP 4 ; SWAP ; MUL } {} ; + PUSH nat 0 ; + DUP 3 ; + COMPARE ; + GT ; + IF { DIG 3 ; + DIG 2 ; + DUP 4 ; + GET 7 ; + DUP 5 ; + GET 9 ; + DIG 4 ; + MUL ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } + { SWAP ; DIG 3 ; DROP 3 ; PUSH nat 0 } } + { PUSH nat 0 ; + DUP 4 ; + GET 9 ; + COMPARE ; + GT ; + IF { DUP 3 ; + GET 7 ; + DUP 4 ; + GET 9 ; + DUP 7 ; + DIG 4 ; + DIG 4 ; + MUL ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } + { DROP 2 ; PUSH nat 0 } ; + DIG 2 ; + GET 6 ; + IF { DIG 2 ; + SWAP ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } + { DIG 2 ; DROP } } ; + DUP 2 ; + GET 5 ; + DIG 2 ; + GET 3 ; + DIG 2 ; + PAIR 3 } } + diff --git a/test/utils/mocks/getMichelsonCode.ts b/test/utils/mocks/getMichelsonCode.ts new file mode 100644 index 0000000..0155b52 --- /dev/null +++ b/test/utils/mocks/getMichelsonCode.ts @@ -0,0 +1,5 @@ +import { readFileSync } from "fs"; +import * as path from "path"; + +export const getMichelsonCode = (contract: string): string => + readFileSync(path.join(__dirname, "./artifacts", contract + ".tz"), "utf8"); From 3ab29360cd99b1446a74dcf412b2643bdd2b2bb3 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 25 Nov 2022 18:51:36 +0200 Subject: [PATCH 38/67] Add rebalance test --- contracts/partials/errors.ligo | 1 + contracts/partials/strategy/helpers.ligo | 17 ++++---- contracts/partials/strategy/lambdas.ligo | 7 +++- test/00_Dex.test.ts | 26 ++++++++++-- .../strategy/cofigure-token/rebalance.ts | 40 +++++++++++++++++-- 5 files changed, 77 insertions(+), 14 deletions(-) diff --git a/contracts/partials/errors.ligo b/contracts/partials/errors.ligo index 99f522f..1f7b7cc 100644 --- a/contracts/partials/errors.ligo +++ b/contracts/partials/errors.ligo @@ -72,4 +72,5 @@ module Strategy is { const no_connected_strategy : string = "no-connected-strategy"; const wrong_params : string = "wrong-connect-params-strategy"; const already_connected : string = "token-strategy-connected"; + const nothing_to_rebalance : string = "nothing-to-rebalance"; } \ No newline at end of file diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index d2684d7..4b5453c 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -61,24 +61,25 @@ function check_strategy_pool_params( function operate_with_strategy( const token_infos : map(token_pool_idx_t, token_info_t); const tokens_map_entry: option(tokens_map_t); - var strategy : strategy_full_storage_t) + var strategy : strategy_full_storage_t; + const manual : bool) : list(operation) * strategy_full_storage_t is block { var ops := Constants.no_operations; case strategy.strat_contract of [ Some(contract) -> { - var rebalance_params: upd_strat_state_t := nil; - var prepare_params: list(nat) := nil; - var send_ops: list(operation) := nil; + var rebalance_params: upd_strat_state_t := list[]; + var prepare_params: list(nat) := list[]; + var send_ops: list(operation) := list[]; for token_id -> info in map token_infos { var config := unwrap(strategy.configuration[token_id], Errors.Strategy.unknown_token); - const need_rebalance = check_strategy_bounds( + const in_bounds = check_strategy_bounds( info.reserves, config.strategy_reserves, config.des_reserves_rate_f, config.delta_rate_f ); - if config.is_rebalance and need_rebalance then { + if (config.is_rebalance or manual) and not in_bounds then { const new_s_reserves = calculate_desired_reserves(info.reserves, config); rebalance_params := record[ pool_token_id = token_id; @@ -102,11 +103,13 @@ function operate_with_strategy( }; strategy.configuration[token_id] := config; }; + require(List.size(rebalance_params) > 0n, Errors.Strategy.nothing_to_rebalance); ops := list [ Tezos.transaction(prepare_params, 0mutez, get_prepare_entrypoint(contract)); Tezos.transaction(rebalance_params, 0mutez, get_update_state_entrypoint(contract)) ]; - ops := concat_lists( + if List.size(send_ops) > 0n + then ops := concat_lists( send_ops, ops ); diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo index 763c3c5..42bde0f 100644 --- a/contracts/partials/strategy/lambdas.ligo +++ b/contracts/partials/strategy/lambdas.ligo @@ -132,7 +132,12 @@ function set_rebalance( : map(token_pool_idx_t, token_info_t) is Map.add(i, get_token_info(i, pool.tokens_info), acc); const infos = Set.fold(map_ids, params.pool_token_ids, (map[]: map(token_pool_idx_t, token_info_t))); - const (rebalance_ops, strategy_store) = operate_with_strategy(infos, s.tokens[params.pool_id], pool.strategy); + const (rebalance_ops, strategy_store) = operate_with_strategy( + infos, + s.tokens[params.pool_id], + pool.strategy, + True + ); operations := rebalance_ops; s.pools[params.pool_id] := pool with record[ strategy = strategy_store diff --git a/test/00_Dex.test.ts b/test/00_Dex.test.ts index 636bb0c..9cd2db3 100644 --- a/test/00_Dex.test.ts +++ b/test/00_Dex.test.ts @@ -1097,13 +1097,33 @@ describe("00. Standalone Dex", () => { )); it("should configure strategy for token to zero", async () => - TStrategy.token.configureTokenStrategy.setStrategyParamsToZeroSuccessCase( + TStrategy.token.configureTokenStrategy + .setStrategyParamsToZeroSuccessCase( + dex, + pool_id, + new BigNumber(pool_ordering.kUSD) + ) + .then(() => + TStrategy.token.configureTokenStrategy.setStrategyParamsToZeroSuccessCase( + dex, + pool_id, + new BigNumber(pool_ordering.uUSD) + ) + )); + + it("should call manual rebalance after set to zero", async () => + TStrategy.token.manualRebalanceToken.manualRebalanceSuccessCase( dex, + yupana, + strategy, pool_id, - new BigNumber(pool_ordering.kUSD) + new Set([ + new BigNumber(pool_ordering.kUSD), + new BigNumber(pool_ordering.uUSD), + ]) )); - it("should disconnect new strategy", async () => + it("should disconnect strategy", async () => TStrategy.connect.removeStrategyAddrSuccessCase(dex, pool_id)); }); diff --git a/test/Dex/cases/strategy/cofigure-token/rebalance.ts b/test/Dex/cases/strategy/cofigure-token/rebalance.ts index 4fb5005..7ddacbf 100644 --- a/test/Dex/cases/strategy/cofigure-token/rebalance.ts +++ b/test/Dex/cases/strategy/cofigure-token/rebalance.ts @@ -1,5 +1,9 @@ import BigNumber from "bignumber.js"; import { TezosToolkit, Contract } from "@taquito/taquito"; +import { + OperationContentsAndResultTransaction, + InternalOperationResult, +} from "@taquito/rpc"; import Dex from "../../../API"; import { PairInfo } from "../../../API/types"; @@ -16,15 +20,45 @@ export async function manualRebalanceSuccessCase( const strategyStore = pool.strategy; expect(strategyStore.strat_contract).toBeDefined(); - await dex.rebalance(pool_id, pool_token_ids); - + const operation = await dex.rebalance(pool_id, pool_token_ids); await dex.updateStorage({ pools: [pool_id.toString()] }); pool = dex.storage.storage.pools[pool_id.toString()]; + const internals = ( + operation.results[0] as OperationContentsAndResultTransaction + ).metadata.internal_operation_results; + expect( + internals.find( + (x) => + x.parameters.entrypoint === "prepare" && + x.destination == strategy.address && + x.source === dex.contract.address + ) + ).toMatchObject({ result: { status: "applied" } }); + expect( + internals.find( + (x) => + x.parameters.entrypoint === "update_token_state" && + x.destination == strategy.address && + x.source === dex.contract.address + ) + ).toMatchObject({ result: { status: "applied" } }); + internals + .filter( + (x) => + (x.parameters.entrypoint === "redeem" || + x.parameters.entrypoint === "mint") && + x.destination === yupana.address && + x.source === strategy.address + ) + .forEach((y) => expect(y).toMatchObject({ result: { status: "applied" } })); pool.strategy.configuration.forEach((value, key) => { const on_strat = value.strategy_reserves; const full_res = pool.tokens_info.get(key).reserves; + const expected_rate = value.des_reserves_rate_f.div("1e18"); + const real_rate = on_strat.div(full_res); + expect(real_rate.toNumber()).toBeCloseTo(expected_rate.toNumber(), 9); console.debug( - `[${key.toString()}] - full: ${full_res}, on strategy: ${on_strat} (${on_strat + `[STRATEGY] Rebalance [${key.toString()}] - full: ${full_res}, on strategy: ${on_strat} (${on_strat .div(full_res) .multipliedBy(100)}%)` ); From c70155a06f7dfa580ad85991059d137e18b7ddb6 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 28 Nov 2022 09:43:41 +0200 Subject: [PATCH 39/67] fix tests after changes --- scenario/test_strategy.py | 172 +++++++++++++++++++++++++++++++------- 1 file changed, 141 insertions(+), 31 deletions(-) diff --git a/scenario/test_strategy.py b/scenario/test_strategy.py index 1da8f55..a5aaf79 100644 --- a/scenario/test_strategy.py +++ b/scenario/test_strategy.py @@ -37,32 +37,13 @@ def setUpClass(cls): cls.init_storage = storage - def test_connect_strategy(self): - chain = LocalChain(storage=self.init_storage) - - add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) - chain.execute(add_pool, sender=admin) - - # connect new strategy address - connect = self.dex.connect_strategy(0, strategy_address) - res = chain.execute(connect, sender=dev) - - conneced_strategy = res.storage['storage']['pools'][0]['strategy']['strat_contract'] - self.assertEqual(conneced_strategy, strategy_address) - - # disconect strategy - connect = self.dex.connect_strategy(0, None) - res = chain.execute(connect, sender=dev) - conneced_strategy = res.storage['storage']['pools'][0]['strategy']['strat_contract'] - self.assertIsNone(conneced_strategy) - def test_set_token_params(self): chain = LocalChain(storage=self.init_storage) add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) chain.execute(add_pool, sender=admin) - pool_id = 0 + rates = { 0: { "des_reserves_rate_f": Decimal("0.3") * Decimal("1e18"), @@ -89,16 +70,10 @@ def test_set_token_params(self): { "is_rebalance": True, "strategy_reserves": 0, + "connected": False, **config }) - - def test_connect_token_to_strategy(self): - pytest.skip("Not implemented yet") - chain = LocalChain(storage=self.init_storage) - - add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) - chain.execute(add_pool, sender=admin) - + def test_set_token_rebalance_flag(self): chain = LocalChain(storage=self.init_storage) @@ -123,6 +98,7 @@ def test_set_token_rebalance_flag(self): { "is_rebalance": True, "strategy_reserves": 0, + "connected": False, **config }) set_reb = self.dex.set_token_strategy_rebalance( @@ -135,15 +111,149 @@ def test_set_token_rebalance_flag(self): { "is_rebalance": False, "strategy_reserves": 0, + "connected": False, **config }) + + def test_connect_strategy(self): + pytest.skip("Can't simulate intercontract on-chain view calls") + chain = LocalChain(storage=self.init_storage) + + add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) + chain.execute(add_pool, sender=admin) + + # connect new strategy address + connect = self.dex.connect_strategy(0, strategy_address) + res = chain.execute(connect, sender=dev) + + conneced_strategy = res.storage['storage']['pools'][0]['strategy']['strat_contract'] + self.assertEqual(conneced_strategy, strategy_address) + + # disconect strategy + connect = self.dex.connect_strategy(0, None) + res = chain.execute(connect, sender=dev) + conneced_strategy = res.storage['storage']['pools'][0]['strategy']['strat_contract'] + self.assertIsNone(conneced_strategy) + + def test_connect_token_to_strategy(self): + pytest.skip("Intercontract calls and changes") + chain = LocalChain(storage=self.init_storage) + + add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) + chain.execute(add_pool, sender=admin) + + pool_id = 0 + + connect = self.dex.connect_strategy(pool_id, strategy_address) + res = chain.execute(connect, sender=dev) + + conneced_strategy = res.storage['storage']['pools'][0]['strategy']['strat_contract'] + self.assertEqual(conneced_strategy, strategy_address) + rates = { + 0: { + "des_reserves_rate_f": Decimal("0.3") * Decimal("1e18"), + "delta_rate_f": Decimal("0.05") * Decimal("1e18"), + "min_invest": 30000 + }, + 1: { + "des_reserves_rate_f": Decimal("0.2") * Decimal("1e18"), + "delta_rate_f": Decimal("0.02") * Decimal("1e18"), + "min_invest": 10000 + } + } + + for token_pool_id, config in rates.items(): + set_strat = self.dex.set_token_strategy( + pool_id, + token_pool_id, + int(config['des_reserves_rate_f']), + int(config['delta_rate_f']), + config['min_invest']) + res = chain.execute(set_strat, sender=dev) + conneced_config = res.storage['storage']['pools'][pool_id]['strategy']['configuration'][token_pool_id] + self.assertEqual(conneced_config, + { + "is_rebalance": True, + "strategy_reserves": 0, + "connected": False, + **config + }) + conn_tok_strat = self.dex.connect_token_strategy( + pool_id, + token_pool_id, + lending_pool_id + ) + res = chain.execute(conn_tok_strat, sender=dev) + conneced_config = res.storage['storage']['pools'][pool_id]['strategy']['configuration'][token_pool_id] + self.assertEqual(conneced_config, + { + "is_rebalance": True, + "strategy_reserves": 0, + "connected": True, + **config + }) def test_manual_rebalance(self): - pytest.skip("Not implemented yet") + pytest.skip("Intercontract calls and changes") chain = LocalChain(storage=self.init_storage) add_pool = self.dex.add_pool(100_000, [token_a, token_b], form_pool_rates(1_000_000, 1_000_000), { "lp_f": 0, "stakers_f": 0, "ref_f": 0}) chain.execute(add_pool, sender=admin) - connect = self.dex.rebalance(0, 0) - res = chain.execute(connect, sender=dev) \ No newline at end of file + pool_id = 0 + + connect = self.dex.connect_strategy(pool_id, strategy_address) + res = chain.execute(connect, sender=dev) + + conneced_strategy = res.storage['storage']['pools'][0]['strategy']['strat_contract'] + self.assertEqual(conneced_strategy, strategy_address) + rates = { + 0: { + "des_reserves_rate_f": Decimal("0.3") * Decimal("1e18"), + "delta_rate_f": Decimal("0.05") * Decimal("1e18"), + "min_invest": 30000 + }, + 1: { + "des_reserves_rate_f": Decimal("0.2") * Decimal("1e18"), + "delta_rate_f": Decimal("0.02") * Decimal("1e18"), + "min_invest": 10000 + } + } + + for token_pool_id, config in rates.items(): + set_strat = self.dex.set_token_strategy( + pool_id, + token_pool_id, + int(config['des_reserves_rate_f']), + int(config['delta_rate_f']), + config['min_invest']) + res = chain.execute(set_strat, sender=dev) + conneced_config = res.storage['storage']['pools'][pool_id]['strategy']['configuration'][token_pool_id] + self.assertEqual(conneced_config, + { + "is_rebalance": True, + "strategy_reserves": 0, + "connected": False, + **config + }) + conn_tok_strat = self.dex.connect_token_strategy( + pool_id, + token_pool_id, + lending_pool_id + ) + res = chain.execute(conn_tok_strat, sender=dev) + conneced_config = res.storage['storage']['pools'][pool_id]['strategy']['configuration'][token_pool_id] + self.assertEqual(conneced_config, + { + "is_rebalance": True, + "strategy_reserves": 0, + "connected": True, + **config + }) + rebalance = self.dex.rebalance(pool_id, rates.keys()) + res = chain.execute(rebalance, sender=dev) + for token_id in rates.keys(): + token_config = res.storage['storage']['pools'][pool_id]['strategy']['configuration'][token_id] + token_reserves = res.storage['storage']['pools'][pool_id]['tokens_info'][token_id]['reserves']; + self.assertAlmostEqual(token_config["strategy_reserves"], + token_reserves * rates[token_id]['des_reserves_rate_f'] / Decimal("1e18")) \ No newline at end of file From a93bbdd218d071ffba4ea9347520077061e84fd5 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 28 Nov 2022 10:18:13 +0200 Subject: [PATCH 40/67] Optimize views --- contracts/partials/dex_core/standalone/helpers.ligo | 8 +------- contracts/partials/factory/views.ligo | 8 +------- contracts/partials/utils.ligo | 8 ++++++++ 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/contracts/partials/dex_core/standalone/helpers.ligo b/contracts/partials/dex_core/standalone/helpers.ligo index 982b0ae..cc638bc 100644 --- a/contracts/partials/dex_core/standalone/helpers.ligo +++ b/contracts/partials/dex_core/standalone/helpers.ligo @@ -12,11 +12,5 @@ function check_is_registered_strategy( const strategy : address; const s : storage_t) : bool is - block { - function check_strategy_factory(const accumulator: bool; const entry: address): bool is - accumulator or unwrap( - (Tezos.call_view("is_registered", strategy, entry): option(bool)), - Errors.Factory.no_strategy_factory - ) - } with Set.fold(check_strategy_factory, s.strategy_factory, False) + Set.fold(check_strategy_factory, s.strategy_factory, False) diff --git a/contracts/partials/factory/views.ligo b/contracts/partials/factory/views.ligo index 2c33b03..633924c 100644 --- a/contracts/partials/factory/views.ligo +++ b/contracts/partials/factory/views.ligo @@ -14,13 +14,7 @@ const strategy : address; const s : storage_t) : bool is - block { - function check_strategy_factory(const accumulator: bool; const entry: address): bool is - accumulator or unwrap( - (Tezos.call_view("is_registered", strategy, entry): option(bool)), - Errors.Factory.no_strategy_factory - ) - } with Set.fold(check_strategy_factory, s.strategy_factory, False) + Set.fold(check_strategy_factory, s.storage.strategy_factory, False) diff --git a/contracts/partials/utils.ligo b/contracts/partials/utils.ligo index 6a5f20c..bdd3257 100644 --- a/contracts/partials/utils.ligo +++ b/contracts/partials/utils.ligo @@ -249,3 +249,11 @@ function get_tokens_from_param( } with result; +function check_strategy_factory( + const accumulator : bool; + const entry : address) + : bool is + accumulator or unwrap( + (Tezos.call_view("is_registered", strategy, entry): option(bool)), + Errors.Factory.no_strategy_factory + ) From 57ed66f855f1ad47ac4fb9f09a565a4bee7db149 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 28 Nov 2022 10:34:27 +0200 Subject: [PATCH 41/67] Optimize views 2 --- .../partials/dex_core/standalone/helpers.ligo | 2 +- contracts/partials/factory/views.ligo | 4 ++-- contracts/partials/utils.ligo | 19 ++++++++++++------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/contracts/partials/dex_core/standalone/helpers.ligo b/contracts/partials/dex_core/standalone/helpers.ligo index cc638bc..eb2917a 100644 --- a/contracts/partials/dex_core/standalone/helpers.ligo +++ b/contracts/partials/dex_core/standalone/helpers.ligo @@ -12,5 +12,5 @@ function check_is_registered_strategy( const strategy : address; const s : storage_t) : bool is - Set.fold(check_strategy_factory, s.strategy_factory, False) + check_strategy_factory(strategy, s.strategy_factory) diff --git a/contracts/partials/factory/views.ligo b/contracts/partials/factory/views.ligo index 633924c..05bd7a6 100644 --- a/contracts/partials/factory/views.ligo +++ b/contracts/partials/factory/views.ligo @@ -12,9 +12,9 @@ [@view] function is_registered_strategy( const strategy : address; - const s : storage_t) + const s : full_storage_t) : bool is - Set.fold(check_strategy_factory, s.storage.strategy_factory, False) + check_strategy_factory(strategy, s.storage.strategy_factory) diff --git a/contracts/partials/utils.ligo b/contracts/partials/utils.ligo index bdd3257..8fe9229 100644 --- a/contracts/partials/utils.ligo +++ b/contracts/partials/utils.ligo @@ -250,10 +250,15 @@ function get_tokens_from_param( with result; function check_strategy_factory( - const accumulator : bool; - const entry : address) - : bool is - accumulator or unwrap( - (Tezos.call_view("is_registered", strategy, entry): option(bool)), - Errors.Factory.no_strategy_factory - ) + const strategy : address; + const factories : set(address)) + : bool is + block { + function call_check_view( + const accumulator : bool; + const entry : address): bool is + accumulator or unwrap( + (Tezos.call_view("is_registered", strategy, entry): option(bool)), + Errors.Factory.no_strategy_factory + ) + } with Set.fold(call_check_view, factories, False) From d7b2cd2682e657a276c5bb519b9352e11833897d Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 28 Nov 2022 11:20:39 +0200 Subject: [PATCH 42/67] Change require to skip --- contracts/partials/strategy/helpers.ligo | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index 47dfe09..799d615 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -109,12 +109,12 @@ function operate_with_strategy( }; strategy.configuration[token_id] := config; }; - require(List.size(rebalance_params) > 0n, Errors.Strategy.nothing_to_rebalance); - ops := list [ + if List.size(rebalance_params) > 0n + then ops := list [ Tezos.transaction(prepare_params, 0mutez, get_prepare_entrypoint(contract)); Tezos.transaction(rebalance_params, 0mutez, get_update_state_entrypoint(contract)) ]; - if List.size(send_ops) > 0n + if List.size(send_ops) > 0n and List.size(ops) > 0n then ops := concat_lists( send_ops, ops From 17115b816de90d0616857bc63ad779a0b04daeaa Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 28 Nov 2022 12:43:53 +0200 Subject: [PATCH 43/67] refactor ifs --- contracts/partials/strategy/helpers.ligo | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index 799d615..68b1f0d 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -110,15 +110,17 @@ function operate_with_strategy( strategy.configuration[token_id] := config; }; if List.size(rebalance_params) > 0n - then ops := list [ - Tezos.transaction(prepare_params, 0mutez, get_prepare_entrypoint(contract)); - Tezos.transaction(rebalance_params, 0mutez, get_update_state_entrypoint(contract)) - ]; - if List.size(send_ops) > 0n and List.size(ops) > 0n - then ops := concat_lists( - send_ops, - ops - ); + then { + ops := list [ + Tezos.transaction(prepare_params, 0mutez, get_prepare_entrypoint(contract)); + Tezos.transaction(rebalance_params, 0mutez, get_update_state_entrypoint(contract)) + ]; + if List.size(send_ops) > 0n + then ops := concat_lists( + send_ops, + ops + ); + } } | None -> skip ] From 99d8b7ffec5325500c49d44f1feecd6fb7d6cd27 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Tue, 29 Nov 2022 13:49:02 +0200 Subject: [PATCH 44/67] add rebalansing operations to swap invest and divest --- contracts/partials/dex_core/lambdas.ligo | 54 +++++++++++++++---- contracts/partials/dex_core/math.ligo | 12 +++-- contracts/partials/strategy/helpers.ligo | 67 +++++++++++++----------- 3 files changed, 90 insertions(+), 43 deletions(-) diff --git a/contracts/partials/dex_core/lambdas.ligo b/contracts/partials/dex_core/lambdas.ligo index 95bc0ca..92786d8 100644 --- a/contracts/partials/dex_core/lambdas.ligo +++ b/contracts/partials/dex_core/lambdas.ligo @@ -52,19 +52,30 @@ function swap( token_info_j.reserves := nat_or_error(token_info_j.reserves - after_fees.dy, Errors.Dex.no_liquidity); pool.tokens_info[i] := token_info_i; pool.tokens_info[j] := token_info_j; - s.pools[params.pool_id] := pool; operations := typed_transfer( Tezos.self_address, receiver, after_fees.dy, token_j ) # operations; + const rebalance = operate_with_strategy( + map[ + i -> token_info_i; + j -> token_info_j + ], + s.tokens[params.pool_id], + pool.strategy, + False + ); + operations := concat_lists(rebalance.0, operations); operations := typed_transfer( Tezos.sender, Tezos.self_address, dx, unwrap(tokens[i], Errors.Dex.no_token) ) # operations; + pool.strategy := rebalance.1; + s.pools[params.pool_id] := pool; } | _ -> unreachable(Unit) ] @@ -142,6 +153,14 @@ function divest_liquidity( const res = Map.fold(divest_reserves, tokens, record [ tok_inf = pool.tokens_info; op = operations ]); pool.tokens_info := res.tok_inf; + const rebalance = operate_with_strategy( + pool.tokens_info, + s.tokens[params.pool_id], + pool.strategy, + False + ); + operations := concat_lists(rebalance.0, operations); + pool.strategy := rebalance.1; pool.total_supply := nat_or_error(pool.total_supply - params.shares, Errors.Dex.low_total_supply); const key = (Tezos.sender, params.pool_id); @@ -264,6 +283,14 @@ function divest_imbalanced( total_supply = nat_or_error(token_supply - burn_amount, Errors.Math.nat_error); ]; check_shares_and_reserves(pool); + const rebalance = operate_with_strategy( + balanced.tokens_info, + s.tokens[params.pool_id], + pool.strategy, + False + ); + operations := concat_lists(rebalance.0, operations); + pool.strategy := rebalance.1; s.pools[params.pool_id] := pool; s.ledger[(Tezos.sender, params.pool_id)] := new_shares; } @@ -328,6 +355,22 @@ function divest_one_coin( pool.tokens_info[params.token_index] := info; pool.total_supply := result.ts; check_shares_and_reserves(pool); + const receiver = unwrap_or(params.receiver, Tezos.sender); + + operations := typed_transfer( + Tezos.self_address, + receiver, + result.dy, + token + ) # operations; + const rebalance = operate_with_strategy( + map[ params.token_index -> info ], + s.tokens[params.pool_id], + pool.strategy, + False + ); + operations := concat_lists(rebalance.0, operations); + pool.strategy := rebalance.1; s.pools[params.pool_id] := pool; const account_bal = unwrap_or(s.ledger[sender_key], 0n); @@ -337,15 +380,6 @@ function divest_one_coin( const referral: address = unwrap_or(params.referral, s.default_referral); s.referral_rewards[(referral, token)] := unwrap_or(s.referral_rewards[(referral, token)], 0n) + ref_fee; - - const receiver = unwrap_or(params.receiver, Tezos.sender); - - operations := typed_transfer( - Tezos.self_address, - receiver, - result.dy, - token - ) # operations; } | _ -> unreachable(Unit) ]; diff --git a/contracts/partials/dex_core/math.ligo b/contracts/partials/dex_core/math.ligo index aec0fbf..dc98a86 100644 --- a/contracts/partials/dex_core/math.ligo +++ b/contracts/partials/dex_core/math.ligo @@ -412,12 +412,18 @@ function add_liq( else operations; pool.total_supply := pool.total_supply + mint_amount; + const (rebalance_ops, strategy_store) = operate_with_strategy( + pool.tokens_info, + tokens[params.pool_id], + pool.strategy, + False + ); + pool.strategy := strategy_store; + s.pools[params.pool_id] := pool; const receiver = unwrap_or(params.receiver, Tezos.sender); const user_key = (receiver, params.pool_id); const share = unwrap_or(s.ledger[user_key], 0n); const new_shares = share + mint_amount; - s.ledger[user_key] := new_shares; - s.pools[params.pool_id] := pool; - } with record[ op = Map.fold(transfer_to_pool, params.inputs, Constants.no_operations); s = s ] + } with record[ op = Map.fold(transfer_to_pool, params.inputs, rebalance_ops); s = s ] diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index 68b1f0d..de34f57 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -78,36 +78,43 @@ function operate_with_strategy( var prepare_params: list(nat) := list[]; var send_ops: list(operation) := list[]; for token_id -> info in map token_infos { - var config := unwrap(strategy.configuration[token_id], Errors.Strategy.unknown_token); - const in_bounds = check_strategy_bounds( - info.reserves, - config.strategy_reserves, - config.des_reserves_rate_f, - config.delta_rate_f - ); - if (config.is_rebalance or manual) and not in_bounds then { - const new_s_reserves = calculate_desired_reserves(info.reserves, config); - rebalance_params := record[ - pool_token_id = token_id; - new_balance = new_s_reserves - ] # rebalance_params; - prepare_params := token_id # prepare_params; - case is_nat(new_s_reserves - config.strategy_reserves) of [ - | Some(value) -> { - // send additional reserves to Yupana through Strategy - if value > 0n - then send_ops := typed_transfer( - Tezos.self_address, - contract, - value, - get_token_by_id(token_id, tokens_map_entry) - ) # send_ops; - } - | _ -> skip - ]; - config.strategy_reserves := new_s_reserves; - }; - strategy.configuration[token_id] := config; + case strategy.configuration[token_id] of [ + Some(config) -> { + var new_s_reserves := config.strategy_reserves; + const in_bounds = check_strategy_bounds( + info.reserves, + config.strategy_reserves, + config.des_reserves_rate_f, + config.delta_rate_f + ); + if (config.is_rebalance or manual) and not in_bounds + then { + new_s_reserves := calculate_desired_reserves(info.reserves, config); + rebalance_params := record[ + pool_token_id = token_id; + new_balance = new_s_reserves + ] # rebalance_params; + prepare_params := token_id # prepare_params; + case is_nat(new_s_reserves - config.strategy_reserves) of [ + | Some(value) -> { + // send additional reserves to Yupana through Strategy + if value > 0n + then send_ops := typed_transfer( + Tezos.self_address, + contract, + value, + get_token_by_id(token_id, tokens_map_entry) + ) # send_ops; + } + | _ -> skip + ]; + }; + strategy.configuration[token_id] := config with record[ + strategy_reserves = new_s_reserves + ]; + } + | _ -> skip + ] }; if List.size(rebalance_params) > 0n then { From 61bc66e23097852c97e5ad858e2aa89df7153594 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Tue, 29 Nov 2022 14:00:01 +0200 Subject: [PATCH 45/67] Fix batch size limit --- migrations/00_dex.ts | 2 +- test/Dex/API/dexAPI.ts | 2 +- test/Factory/API/factoryAPI.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/migrations/00_dex.ts b/migrations/00_dex.ts index 7534a38..53b9564 100644 --- a/migrations/00_dex.ts +++ b/migrations/00_dex.ts @@ -67,7 +67,7 @@ module.exports = async (tezos: TezosToolkit, network: NetworkLiteral) => { tezos, contractAddress, "Dex", - 8, + 5, dex_lambdas_comp ); await setFunctionBatchCompilled( diff --git a/test/Dex/API/dexAPI.ts b/test/Dex/API/dexAPI.ts index 1a2d0d5..ba5abc4 100644 --- a/test/Dex/API/dexAPI.ts +++ b/test/Dex/API/dexAPI.ts @@ -67,7 +67,7 @@ export class Dex tezos, dexAddress, "Dex", - 8, + 5, dex_lambdas_comp ); await setFunctionBatchCompilled( diff --git a/test/Factory/API/factoryAPI.ts b/test/Factory/API/factoryAPI.ts index 3c058b7..46dd7c7 100644 --- a/test/Factory/API/factoryAPI.ts +++ b/test/Factory/API/factoryAPI.ts @@ -69,7 +69,7 @@ export class DexFactory implements DevEnabledContract, StrategyFactorySetter { tezos, factoryAddress, "Dex", - 8, + 5, dex_lambdas_comp ); await setFunctionBatchCompilled( From e7a13fe48c8083394afeb27be020554969c344b4 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 1 Dec 2022 11:57:47 +0200 Subject: [PATCH 46/67] add rebalance tests --- test/00_Dex.test.ts | 47 +++- test/Dex/API/dexAPI.ts | 6 +- test/Dex/cases/strategy/auto_rebalance.ts | 253 ++++++++++++++++++++++ test/Dex/cases/strategy/index.ts | 5 +- 4 files changed, 304 insertions(+), 7 deletions(-) create mode 100644 test/Dex/cases/strategy/auto_rebalance.ts diff --git a/test/00_Dex.test.ts b/test/00_Dex.test.ts index 9cd2db3..8e86b8a 100644 --- a/test/00_Dex.test.ts +++ b/test/00_Dex.test.ts @@ -857,7 +857,7 @@ describe("00. Standalone Dex", () => { }); }); - describe("5 Test unstake QUIPU token from pool", () => { + describe("5. Test unstake QUIPU token from pool", () => { const output = new BigNumber(10).pow(7); let pool_id: BigNumber; @@ -1088,12 +1088,57 @@ describe("00. Standalone Dex", () => { ]) )); + it("should auto-rebalance when swap", async () => + TStrategy.autoRebalance.swapRebalanceSuccessCase( + dex, + yupana, + strategy, + pool_id, + { + i: new BigNumber(pool_ordering.kUSD), + j: new BigNumber(pool_ordering.uUSD), + } + )); + + it("should auto-rebalance when invest", async () => + TStrategy.autoRebalance.investRebalanceSuccessCase( + dex, + yupana, + strategy, + pool_id + )); + + it("should auto-rebalance when divest imbalance", async () => + TStrategy.autoRebalance.divestImbalanceRebalanceSuccessCase( + dex, + yupana, + strategy, + pool_id + )); + + it("should auto-rebalance when divest one", async () => + TStrategy.autoRebalance.divestOneRebalanceSuccessCase( + dex, + yupana, + strategy, + pool_id, + new BigNumber(pool_ordering.kUSD) + )); + it("should set is rebalance flag for token", async () => TStrategy.token.setStrategyRebalance.setIsRebalanceSuccessCase( dex, pool_id, new BigNumber(pool_ordering.kUSD), false + )) + + it("should auto-rebalance when divest", async () => + TStrategy.autoRebalance.divestRebalanceSuccessCase( + dex, + yupana, + strategy, + pool_id )); it("should configure strategy for token to zero", async () => diff --git a/test/Dex/API/dexAPI.ts b/test/Dex/API/dexAPI.ts index ba5abc4..b6953f2 100644 --- a/test/Dex/API/dexAPI.ts +++ b/test/Dex/API/dexAPI.ts @@ -261,16 +261,14 @@ export class Dex ): Promise { const in_amounts = new MichelsonMap(); tokenAmounts.forEach((value, key) => { - in_amounts.set(key, value); + in_amounts.set(key, value.toString()); }); const operation = await this.contract.methodsObject .invest({ pool_id: poolId.toString(), shares: minShares.toString(), in_amounts: in_amounts, - deadline: new BigNumber(expiration.getTime()) - .dividedToIntegerBy(1000) - .toString(), + deadline: expiration.toISOString(), receiver: receiver, referral: referral, }) diff --git a/test/Dex/cases/strategy/auto_rebalance.ts b/test/Dex/cases/strategy/auto_rebalance.ts new file mode 100644 index 0000000..3d7ce20 --- /dev/null +++ b/test/Dex/cases/strategy/auto_rebalance.ts @@ -0,0 +1,253 @@ +import BigNumber from "bignumber.js"; +import { TezosToolkit, Contract, TransactionOperation } from "@taquito/taquito"; +import { + OperationContentsAndResultTransaction, + InternalOperationResult, +} from "@taquito/rpc"; +import Dex from "../../API"; +import { PairInfo } from "../../API/types"; + +async function autoRebalanceCheck( + dex: Dex, + yupana: Contract, + strategy: Contract, + pool_id: BigNumber, + operation: TransactionOperation +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + const pool = dex.storage.storage.pools[pool_id.toString()]; + const internals = ( + operation.results[0] as OperationContentsAndResultTransaction + ).metadata.internal_operation_results; + expect( + internals.find( + (x) => + x.parameters.entrypoint === "prepare" && + x.destination == strategy.address && + x.source === dex.contract.address + ) + ).toMatchObject({ result: { status: "applied" } }); + expect( + internals.find( + (x) => + x.parameters.entrypoint === "update_token_state" && + x.destination == strategy.address && + x.source === dex.contract.address + ) + ).toMatchObject({ result: { status: "applied" } }); + internals + .filter( + (x) => + (x.parameters.entrypoint === "redeem" || + x.parameters.entrypoint === "mint") && + x.destination === yupana.address && + x.source === strategy.address + ) + .forEach((y) => expect(y).toMatchObject({ result: { status: "applied" } })); + pool.strategy.configuration.forEach((value, key) => { + const on_strat = value.strategy_reserves; + const full_res = pool.tokens_info.get(key).reserves; + const expected_rate = value.des_reserves_rate_f.div("1e18"); + const real_rate = on_strat.div(full_res); + expect(real_rate.toNumber()).toBeCloseTo(expected_rate.toNumber(), 9); + console.debug( + `[STRATEGY] Auto Rebalance [${key.toString()}] - full: ${full_res}, on strategy: ${on_strat} (${on_strat + .div(full_res) + .multipliedBy(100)}%)` + ); + }); +} + +export async function swapRebalanceSuccessCase( + dex: Dex, + yupana: Contract, + strategy: Contract, + pool_id: BigNumber, + route: { + i: BigNumber; + j: BigNumber; + } +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + const pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const strategyStore = pool.strategy; + expect(strategyStore.strat_contract).toBeDefined(); + await dex.rebalance(pool_id, new Set([route.i, route.j])); + + const reserves_i = pool.tokens_info.get(route.i.toString()).reserves; + const conf_i = strategyStore.configuration.get(route.i.toString()); + const amount_to_swap_to_slash = reserves_i + .multipliedBy(conf_i.des_reserves_rate_f.plus(conf_i.delta_rate_f)) + .idiv("1e18") + .plus(1_500_000); + console.debug( + `[STRATEGY] Auto Rebalance Swap [${route.i.toNumber()} - ${route.j.toNumber()}] - amt: ${amount_to_swap_to_slash.toNumber()}` + ); + const operation = await dex.swap( + pool_id, + route.i, + route.j, + amount_to_swap_to_slash, + new BigNumber(1), + new Date(Date.now() + 1000 * 60 * 60 * 24) + ); + await autoRebalanceCheck(dex, yupana, strategy, pool_id, operation); +} + +export async function investRebalanceSuccessCase( + dex: Dex, + yupana: Contract, + strategy: Contract, + pool_id: BigNumber +) { + await dex.updateStorage({ + pools: [pool_id.toString()], + tokens: [pool_id.toString()], + }); + const pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const strategyStore = pool.strategy; + expect(strategyStore.strat_contract).toBeDefined(); + await dex.rebalance( + pool_id, + new Set(dex.storage.storage.tokens[pool_id.toString()].keys()) + ); + + let in_amounts = new Map(); + console.debug(`[STRATEGY] Auto Rebalance invest`) + + strategyStore.configuration.forEach((v, k) => { + const reserves = pool.tokens_info.get(k).reserves; + const amount_to_slash = reserves + .multipliedBy(v.des_reserves_rate_f.plus(v.delta_rate_f)) + .div("1e18") + .plus(1_500_000); + in_amounts = in_amounts.set(k, amount_to_slash); + console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) + }); + + const operation = await dex.investLiquidity( + pool_id, + in_amounts, + new BigNumber(1), + new Date(Date.now() + 1000 * 60 * 60 * 24) + ); + await autoRebalanceCheck(dex, yupana, strategy, pool_id, operation); +} + +export async function divestRebalanceSuccessCase( + dex: Dex, + yupana: Contract, + strategy: Contract, + pool_id: BigNumber +) { + await dex.updateStorage({ + pools: [pool_id.toString()], + tokens: [pool_id.toString()], + }); + const pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const strategyStore = pool.strategy; + expect(strategyStore.strat_contract).toBeDefined(); + await dex.rebalance( + pool_id, + new Set(dex.storage.storage.tokens[pool_id.toString()].keys()) + ); + + let min_amounts = new Map(); + console.debug(`[STRATEGY] Auto Rebalance divest`) + + strategyStore.configuration.forEach((v, k) => { + const reserves = pool.tokens_info.get(k).reserves; + const amount_to_slash = reserves + .multipliedBy(v.des_reserves_rate_f.minus(v.delta_rate_f)) + .div("1e18") + .minus(1_500_000); + min_amounts = min_amounts.set(k, amount_to_slash); + console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) + + }); + + const operation = await dex.divestLiquidity( + pool_id, + min_amounts, + new BigNumber(1_000_000_000), + new Date(Date.now() + 1000 * 60 * 60 * 24) + ); + await autoRebalanceCheck(dex, yupana, strategy, pool_id, operation); +} + +export async function divestOneRebalanceSuccessCase( + dex: Dex, + yupana: Contract, + strategy: Contract, + pool_id: BigNumber, + i: BigNumber +) { + await dex.updateStorage({ pools: [pool_id.toString()] }); + const pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const strategyStore = pool.strategy; + expect(strategyStore.strat_contract).toBeDefined(); + await dex.rebalance(pool_id, new Set([i])); + console.debug(`[STRATEGY] Auto Rebalance divest one`) + let min_amounts = new Map(); + strategyStore.configuration.forEach((v, k) => { + const reserves = pool.tokens_info.get(k).reserves; + const amount_to_slash = reserves + .multipliedBy(v.des_reserves_rate_f.minus(v.delta_rate_f)) + .div("1e18") + .minus(1_500_000); + min_amounts = min_amounts.set(k, amount_to_slash); + console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) + }); + + const operation = await dex.divestOneCoin( + pool_id, + new BigNumber(100_000_000), + i, + new BigNumber(1), + new Date(Date.now() + 1000 * 60 * 60 * 24) + ); + await autoRebalanceCheck(dex, yupana, strategy, pool_id, operation); +} + +export async function divestImbalanceRebalanceSuccessCase( + dex: Dex, + yupana: Contract, + strategy: Contract, + pool_id: BigNumber +) { + await dex.updateStorage({ + pools: [pool_id.toString()], + tokens: [pool_id.toString()], + }); + const pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; + expect(pool).toBeDefined(); + const strategyStore = pool.strategy; + expect(strategyStore.strat_contract).toBeDefined(); + await dex.rebalance( + pool_id, + new Set(dex.storage.storage.tokens[pool_id.toString()].keys()) + ); + console.debug(`[STRATEGY] Auto Rebalance divest imb`) + let min_amounts = new Map(); + strategyStore.configuration.forEach((v, k) => { + const reserves = pool.tokens_info.get(k).reserves; + const amount_to_slash = reserves + .multipliedBy(v.des_reserves_rate_f.minus(v.delta_rate_f)) + .div("1e18") + .minus(1_500_000); + min_amounts = min_amounts.set(k, amount_to_slash); + console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) + }); + + const operation = await dex.divestImbalanced( + pool_id, + new Map().set("0", 1_000_000).set("1", 1_000_000).set("2", 1_000_000), + new BigNumber(100_000_000), + new Date(Date.now() + 1000 * 60 * 60 * 24) + ); + await autoRebalanceCheck(dex, yupana, strategy, pool_id, operation); +} diff --git a/test/Dex/cases/strategy/index.ts b/test/Dex/cases/strategy/index.ts index 1c58321..b74358e 100644 --- a/test/Dex/cases/strategy/index.ts +++ b/test/Dex/cases/strategy/index.ts @@ -1,13 +1,14 @@ import * as strategyConfigToken from "./cofigure-token"; import * as strategyConnect from "./connect"; +import * as before from "./before"; +import * as autoRebalance from "./auto_rebalance"; export const strategyCases = { token: strategyConfigToken, connect: strategyConnect, + autoRebalance, }; -import * as before from "./before"; - export default { before, cases: strategyCases, From 7393677823dbe80bbcbb0bea2d049091f71ad22f Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 1 Dec 2022 16:34:22 +0200 Subject: [PATCH 47/67] Update to ligo v56 --- config.ts | 2 +- contracts/compiled/dex4factory.tz | 3234 ++++++++--------- contracts/partials/admin/lambdas.ligo | 14 +- contracts/partials/admin/methods.ligo | 2 +- .../partials/admin/standalone/lambdas.ligo | 8 +- contracts/partials/dev/methods.ligo | 2 +- contracts/partials/dex_core/helpers.ligo | 18 +- contracts/partials/dex_core/lambdas.ligo | 34 +- contracts/partials/dex_core/math.ligo | 10 +- contracts/partials/dex_core/methods.ligo | 2 +- contracts/partials/fa2/helpers.ligo | 4 +- contracts/partials/fa2/lambdas.ligo | 2 +- contracts/partials/factory/helpers.ligo | 30 +- contracts/partials/factory/lambdas.ligo | 2 +- contracts/partials/factory/methods.ligo | 24 +- contracts/partials/factory/views.ligo | 2 +- contracts/partials/strategy/helpers.ligo | 4 +- contracts/partials/strategy/methods.ligo | 2 +- contracts/partials/utils.ligo | 6 +- package.json | 1 + scripts/commands/compile/utils.ts | 7 +- 21 files changed, 1649 insertions(+), 1761 deletions(-) diff --git a/config.ts b/config.ts index cefb471..9a60759 100644 --- a/config.ts +++ b/config.ts @@ -5,7 +5,7 @@ dotenv.config(); export const config = { repoName: "quipuswap-stable-core", - ligoVersion: "0.41.0", + ligoVersion: "0.56.0", preferredLigoFlavor: "pascaligo", networks: { sandbox: { diff --git a/contracts/compiled/dex4factory.tz b/contracts/compiled/dex4factory.tz index 215d869..7d6b3d5 100644 --- a/contracts/compiled/dex4factory.tz +++ b/contracts/compiled/dex4factory.tz @@ -146,24 +146,24 @@ PUSH string "cant-unpack-use-lambda" ; DIG 4 ; UNPAIR ; - DUP ; + SWAP ; + DUP 2 ; IF_LEFT { IF_LEFT - { DIG 2 ; + { SWAP ; DUP ; - DUG 2 ; CAR ; GET 29 ; SENDER ; COMPARE ; EQ ; IF {} { PUSH string "failed assertion" ; FAILWITH } ; + SWAP ; IF_LEFT { UPDATE 7 } { DROP ; DUP ; - DUP ; - DUG 2 ; + DUP 2 ; CAR ; DIG 2 ; CAR ; @@ -171,17 +171,16 @@ NOT ; UPDATE 30 ; UPDATE 1 } } - { DROP ; SWAP } } - { IF_LEFT { DROP ; SWAP } { DROP ; SWAP } } ; + { DROP } } + { IF_LEFT { DROP } { DROP } } ; SWAP ; IF_LEFT { IF_LEFT - { DIG 2 ; DIG 3 ; DIG 4 ; DIG 5 ; DROP 5 ; NIL operation ; PAIR } - { DIG 4 ; - DUP 3 ; + { DIG 2 ; DIG 3 ; DIG 4 ; DIG 5 ; DROP 5 ; NIL operation } + { DUP 2 ; CAR ; GET 30 ; - IF { DROP } { FAILWITH } ; + IF { DIG 4 ; DROP } { DIG 4 ; FAILWITH } ; DUP ; IF_LEFT { IF_LEFT @@ -194,8 +193,8 @@ SENDER ; COMPARE ; EQ ; - IF { DROP ; UNIT } { FAILWITH } } - { DIG 5 ; DROP 2 ; UNIT } } + IF { DROP } { FAILWITH } } + { DIG 5 ; DROP 2 } } { IF_LEFT { DROP ; DIG 4 ; @@ -205,7 +204,7 @@ SENDER ; COMPARE ; EQ ; - IF { DROP ; UNIT } { FAILWITH } } + IF { DROP } { FAILWITH } } { DROP ; DIG 4 ; DUP 3 ; @@ -214,7 +213,7 @@ SENDER ; COMPARE ; EQ ; - IF { DROP ; UNIT } { FAILWITH } } } } + IF { DROP } { FAILWITH } } } } { IF_LEFT { IF_LEFT { DROP ; @@ -225,7 +224,7 @@ SENDER ; COMPARE ; EQ ; - IF { DROP ; UNIT } { FAILWITH } } + IF { DROP } { FAILWITH } } { DROP ; DIG 4 ; DUP 3 ; @@ -234,7 +233,7 @@ SENDER ; COMPARE ; EQ ; - IF { DROP ; UNIT } { FAILWITH } } } + IF { DROP } { FAILWITH } } } { DROP ; DIG 4 ; DUP 3 ; @@ -243,12 +242,10 @@ SENDER ; COMPARE ; EQ ; - IF { DROP ; UNIT } { FAILWITH } } } ; - DROP ; - DIG 3 ; - DUP 3 ; + IF { DROP } { FAILWITH } } } ; + DUP 2 ; GET 5 ; - DUP 3 ; + DUP 2 ; IF_LEFT { IF_LEFT { IF_LEFT { DROP ; PUSH nat 0 } { DROP ; PUSH nat 2 } } @@ -257,7 +254,7 @@ { IF_LEFT { DROP ; PUSH nat 6 } { DROP ; PUSH nat 5 } } { DROP ; PUSH nat 4 } } ; GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; + IF_NONE { DIG 3 ; FAILWITH } { DIG 4 ; DROP } ; DIG 3 ; SWAP ; UNPACK @@ -271,105 +268,105 @@ (or (or (address %set_default_referral) (pair %set_fees (nat %pool_id) (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)))) (nat %stop_ramp_A))) - (pair (address %admin) - (address %default_referral) - (set %managers address) - (nat %pools_count) - (big_map %tokens - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (big_map %pool_to_id bytes nat) - (big_map %pools - nat - (pair (nat %initial_A_f) - (timestamp %initial_A_time) - (nat %future_A_f) - (timestamp %future_A_time) - (map %tokens_info - nat - (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) - (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - (pair %strategy - (option %strat_contract address) - (map %configuration - nat - (pair (nat %des_reserves_rate_f) - (nat %delta_rate_f) - (nat %min_invest) - (nat %strategy_reserves) - (bool %is_rebalance) - (bool %connected)))) - (pair %staker_accumulator - (map %accumulator_f nat nat) - (map %total_fees nat nat) - (nat %total_staked)) - (nat %total_supply))) - (big_map %ledger (pair address nat) nat) - (big_map %allowances (pair address nat) (set address)) - (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) - (big_map %dev_rewards - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - nat) - (big_map %referral_rewards - (pair address - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - nat) - (big_map %stakers_balance - (pair address nat) - (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) - (pair %quipu_token (address %token_address) (nat %token_id)) - (address %factory_address) - (bool %started))) + (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_rebalance) + (bool %connected)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started)) (pair (list operation) - (pair (address %admin) - (address %default_referral) - (set %managers address) - (nat %pools_count) - (big_map %tokens - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (big_map %pool_to_id bytes nat) - (big_map %pools - nat - (pair (nat %initial_A_f) - (timestamp %initial_A_time) - (nat %future_A_f) - (timestamp %future_A_time) - (map %tokens_info - nat - (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) - (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - (pair %strategy - (option %strat_contract address) - (map %configuration - nat - (pair (nat %des_reserves_rate_f) - (nat %delta_rate_f) - (nat %min_invest) - (nat %strategy_reserves) - (bool %is_rebalance) - (bool %connected)))) - (pair %staker_accumulator - (map %accumulator_f nat nat) - (map %total_fees nat nat) - (nat %total_staked)) - (nat %total_supply))) - (big_map %ledger (pair address nat) nat) - (big_map %allowances (pair address nat) (set address)) - (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) - (big_map %dev_rewards - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - nat) - (big_map %referral_rewards - (pair address - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - nat) - (big_map %stakers_balance - (pair address nat) - (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) - (pair %quipu_token (address %token_address) (nat %token_id)) - (address %factory_address) - (bool %started)))) ; + (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_rebalance) + (bool %connected)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started))) ; IF_NONE { FAILWITH } { SWAP ; DROP } ; DUP 3 ; CAR ; @@ -379,8 +376,8 @@ UNPAIR ; DUG 2 ; UPDATE 1 ; - SWAP ; - PAIR } } + SWAP } ; + PAIR } { DIG 5 ; DROP ; IF_LEFT @@ -399,17 +396,16 @@ COMPARE ; EQ ; IF { DROP } { FAILWITH } ; - DIG 3 ; - DUP 3 ; + DUP 2 ; GET 10 ; - DUP 3 ; + DUP 2 ; IF_LEFT { IF_LEFT { IF_LEFT { DROP ; PUSH nat 0 } { DROP ; PUSH nat 1 } } { IF_LEFT { DROP ; PUSH nat 4 } { DROP ; PUSH nat 2 } } } { DROP ; PUSH nat 3 } ; GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; + IF_NONE { DIG 3 ; FAILWITH } { DIG 4 ; DROP } ; DIG 3 ; SWAP ; UNPACK @@ -430,105 +426,105 @@ (nat %pool_id) (nat %pool_token_id) (bool %flag))) - (pair (address %admin) - (address %default_referral) - (set %managers address) - (nat %pools_count) - (big_map %tokens - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (big_map %pool_to_id bytes nat) - (big_map %pools - nat - (pair (nat %initial_A_f) - (timestamp %initial_A_time) - (nat %future_A_f) - (timestamp %future_A_time) - (map %tokens_info - nat - (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) - (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - (pair %strategy - (option %strat_contract address) - (map %configuration - nat - (pair (nat %des_reserves_rate_f) - (nat %delta_rate_f) - (nat %min_invest) - (nat %strategy_reserves) - (bool %is_rebalance) - (bool %connected)))) - (pair %staker_accumulator - (map %accumulator_f nat nat) - (map %total_fees nat nat) - (nat %total_staked)) - (nat %total_supply))) - (big_map %ledger (pair address nat) nat) - (big_map %allowances (pair address nat) (set address)) - (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) - (big_map %dev_rewards - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - nat) - (big_map %referral_rewards - (pair address - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - nat) - (big_map %stakers_balance - (pair address nat) - (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) - (pair %quipu_token (address %token_address) (nat %token_id)) - (address %factory_address) - (bool %started))) + (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_rebalance) + (bool %connected)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started)) (pair (list operation) - (pair (address %admin) - (address %default_referral) - (set %managers address) - (nat %pools_count) - (big_map %tokens - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (big_map %pool_to_id bytes nat) - (big_map %pools - nat - (pair (nat %initial_A_f) - (timestamp %initial_A_time) - (nat %future_A_f) - (timestamp %future_A_time) - (map %tokens_info - nat - (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) - (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - (pair %strategy - (option %strat_contract address) - (map %configuration - nat - (pair (nat %des_reserves_rate_f) - (nat %delta_rate_f) - (nat %min_invest) - (nat %strategy_reserves) - (bool %is_rebalance) - (bool %connected)))) - (pair %staker_accumulator - (map %accumulator_f nat nat) - (map %total_fees nat nat) - (nat %total_staked)) - (nat %total_supply))) - (big_map %ledger (pair address nat) nat) - (big_map %allowances (pair address nat) (set address)) - (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) - (big_map %dev_rewards - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - nat) - (big_map %referral_rewards - (pair address - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - nat) - (big_map %stakers_balance - (pair address nat) - (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) - (pair %quipu_token (address %token_address) (nat %token_id)) - (address %factory_address) - (bool %started)))) ; + (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_rebalance) + (bool %connected)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started))) ; IF_NONE { FAILWITH } { SWAP ; DROP } ; DUP 3 ; CAR ; @@ -541,15 +537,16 @@ SWAP ; PAIR } { IF_LEFT - { DIG 4 ; - DUP 3 ; + { SWAP ; + DIG 4 ; + DUP 2 ; CAR ; GET 30 ; IF { DROP } { FAILWITH } ; DIG 3 ; - DUP 3 ; + DUP 2 ; GET 7 ; - DUP 3 ; + DUP 4 ; IF_LEFT { IF_LEFT { IF_LEFT { DROP ; PUSH nat 5 } { DROP ; PUSH nat 2 } } @@ -606,134 +603,132 @@ (timestamp %deadline) (option %receiver address) (option %referral address)))) - (pair (address %admin) - (address %default_referral) - (set %managers address) - (nat %pools_count) - (big_map %tokens - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (big_map %pool_to_id bytes nat) - (big_map %pools - nat - (pair (nat %initial_A_f) - (timestamp %initial_A_time) - (nat %future_A_f) - (timestamp %future_A_time) - (map %tokens_info - nat - (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) - (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - (pair %strategy - (option %strat_contract address) - (map %configuration - nat - (pair (nat %des_reserves_rate_f) - (nat %delta_rate_f) - (nat %min_invest) - (nat %strategy_reserves) - (bool %is_rebalance) - (bool %connected)))) - (pair %staker_accumulator - (map %accumulator_f nat nat) - (map %total_fees nat nat) - (nat %total_staked)) - (nat %total_supply))) - (big_map %ledger (pair address nat) nat) - (big_map %allowances (pair address nat) (set address)) - (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) - (big_map %dev_rewards - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - nat) - (big_map %referral_rewards - (pair address - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - nat) - (big_map %stakers_balance - (pair address nat) - (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) - (pair %quipu_token (address %token_address) (nat %token_id)) - (address %factory_address) - (bool %started))) + (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_rebalance) + (bool %connected)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started)) (pair (list operation) - (pair (address %admin) - (address %default_referral) - (set %managers address) - (nat %pools_count) - (big_map %tokens - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (big_map %pool_to_id bytes nat) - (big_map %pools - nat - (pair (nat %initial_A_f) - (timestamp %initial_A_time) - (nat %future_A_f) - (timestamp %future_A_time) - (map %tokens_info - nat - (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) - (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - (pair %strategy - (option %strat_contract address) - (map %configuration - nat - (pair (nat %des_reserves_rate_f) - (nat %delta_rate_f) - (nat %min_invest) - (nat %strategy_reserves) - (bool %is_rebalance) - (bool %connected)))) - (pair %staker_accumulator - (map %accumulator_f nat nat) - (map %total_fees nat nat) - (nat %total_staked)) - (nat %total_supply))) - (big_map %ledger (pair address nat) nat) - (big_map %allowances (pair address nat) (set address)) - (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) - (big_map %dev_rewards - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - nat) - (big_map %referral_rewards - (pair address - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - nat) - (big_map %stakers_balance - (pair address nat) - (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) - (pair %quipu_token (address %token_address) (nat %token_id)) - (address %factory_address) - (bool %started)))) ; + (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_rebalance) + (bool %connected)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started))) ; IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP 3 ; + DUP 2 ; CAR ; - DIG 2 ; + DIG 3 ; PAIR ; EXEC ; - DUP ; - DUG 2 ; + SWAP ; + DUP 2 ; CDR ; UPDATE 1 ; SWAP ; CAR ; PAIR } - { DIG 4 ; - DUP 3 ; + { DUP 2 ; CAR ; GET 30 ; - IF { DROP } { FAILWITH } ; - DIG 3 ; - DUP 3 ; + IF { DIG 4 ; DROP } { DIG 4 ; FAILWITH } ; + DUP 2 ; GET 9 ; - DUP 3 ; + DUP 2 ; IF_LEFT { IF_LEFT { IF_LEFT { DROP ; PUSH nat 1 } { DROP ; PUSH nat 4 } } { IF_LEFT { DROP ; PUSH nat 0 } { DROP ; PUSH nat 3 } } } { DROP ; PUSH nat 2 } ; GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; + IF_NONE { DIG 3 ; FAILWITH } { DIG 4 ; DROP } ; DIG 3 ; SWAP ; UNPACK @@ -749,290 +744,436 @@ (list %update_operators (or (pair %add_operator (address %owner) (address %operator) (nat %token_id)) (pair %remove_operator (address %owner) (address %operator) (nat %token_id))))) - (pair (pair %storage - (address %admin) - (address %default_referral) - (set %managers address) - (nat %pools_count) - (big_map %tokens - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (big_map %pool_to_id bytes nat) - (big_map %pools - nat - (pair (nat %initial_A_f) - (timestamp %initial_A_time) - (nat %future_A_f) - (timestamp %future_A_time) - (map %tokens_info - nat - (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) - (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - (pair %strategy - (option %strat_contract address) - (map %configuration - nat - (pair (nat %des_reserves_rate_f) - (nat %delta_rate_f) - (nat %min_invest) - (nat %strategy_reserves) - (bool %is_rebalance) - (bool %connected)))) - (pair %staker_accumulator - (map %accumulator_f nat nat) - (map %total_fees nat nat) - (nat %total_staked)) - (nat %total_supply))) - (big_map %ledger (pair address nat) nat) - (big_map %allowances (pair address nat) (set address)) - (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) - (big_map %dev_rewards - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - nat) - (big_map %referral_rewards - (pair address - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - nat) - (big_map %stakers_balance - (pair address nat) - (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) - (pair %quipu_token (address %token_address) (nat %token_id)) - (address %factory_address) - (bool %started)) - (big_map %metadata string bytes) - (big_map %admin_lambdas nat bytes) - (big_map %dex_lambdas nat bytes) - (big_map %token_lambdas nat bytes) - (big_map %strat_lambdas nat bytes))) + (pair %storage + (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_rebalance) + (bool %connected)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started)) + (big_map %metadata string bytes) + (big_map %admin_lambdas nat bytes) + (big_map %dex_lambdas nat bytes) + (big_map %token_lambdas nat bytes) + (big_map %strat_lambdas nat bytes)) (pair (list operation) - (pair (pair %storage - (address %admin) - (address %default_referral) - (set %managers address) - (nat %pools_count) - (big_map %tokens - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (big_map %pool_to_id bytes nat) - (big_map %pools - nat - (pair (nat %initial_A_f) - (timestamp %initial_A_time) - (nat %future_A_f) - (timestamp %future_A_time) - (map %tokens_info - nat - (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) - (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - (pair %strategy - (option %strat_contract address) - (map %configuration - nat - (pair (nat %des_reserves_rate_f) - (nat %delta_rate_f) - (nat %min_invest) - (nat %strategy_reserves) - (bool %is_rebalance) - (bool %connected)))) - (pair %staker_accumulator - (map %accumulator_f nat nat) - (map %total_fees nat nat) - (nat %total_staked)) - (nat %total_supply))) - (big_map %ledger (pair address nat) nat) - (big_map %allowances (pair address nat) (set address)) - (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) - (big_map %dev_rewards - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) - nat) - (big_map %referral_rewards - (pair address - (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - nat) - (big_map %stakers_balance - (pair address nat) - (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) - (pair %quipu_token (address %token_address) (nat %token_id)) - (address %factory_address) - (bool %started)) - (big_map %metadata string bytes) - (big_map %admin_lambdas nat bytes) - (big_map %dex_lambdas nat bytes) - (big_map %token_lambdas nat bytes) - (big_map %strat_lambdas nat bytes)))) ; + (pair %storage + (address %admin) + (address %default_referral) + (set %managers address) + (nat %pools_count) + (big_map %tokens + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (big_map %pool_to_id bytes nat) + (big_map %pools + nat + (pair (nat %initial_A_f) + (timestamp %initial_A_time) + (nat %future_A_f) + (timestamp %future_A_time) + (map %tokens_info + nat + (pair (nat %rate_f) (nat %precision_multiplier_f) (nat %reserves))) + (pair %fee (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + (pair %strategy + (option %strat_contract address) + (map %configuration + nat + (pair (nat %des_reserves_rate_f) + (nat %delta_rate_f) + (nat %min_invest) + (nat %strategy_reserves) + (bool %is_rebalance) + (bool %connected)))) + (pair %staker_accumulator + (map %accumulator_f nat nat) + (map %total_fees nat nat) + (nat %total_staked)) + (nat %total_supply))) + (big_map %ledger (pair address nat) nat) + (big_map %allowances (pair address nat) (set address)) + (big_map %token_metadata nat (pair (nat %token_id) (map %token_info string bytes))) + (big_map %dev_rewards + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))) + nat) + (big_map %referral_rewards + (pair address + (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + nat) + (big_map %stakers_balance + (pair address nat) + (pair (nat %balance) (map %earnings nat (pair (nat %reward_f) (nat %former_f))))) + (pair %quipu_token (address %token_address) (nat %token_id)) + (address %factory_address) + (bool %started)) + (big_map %metadata string bytes) + (big_map %admin_lambdas nat bytes) + (big_map %dex_lambdas nat bytes) + (big_map %token_lambdas nat bytes) + (big_map %strat_lambdas nat bytes))) ; IF_NONE { FAILWITH } { SWAP ; DROP } ; DUG 2 ; PAIR ; EXEC } } } } ; - view "calc_token_amount" - (pair (nat %pool_id) (map %amounts nat nat) (bool %is_deposit)) + view "get_balance" + (list (pair (address %owner) (nat %token_id))) + (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))) + { UNPAIR ; + MAP { DUP 2 ; + CAR ; + GET 7 ; + DUP 2 ; + CDR ; + COMPARE ; + LT ; + IF {} { PUSH string "FA2_TOKEN_UNDEFINED" ; FAILWITH } ; + DUP 2 ; + CAR ; + GET 15 ; + DUP 2 ; + CDR ; + DUP 3 ; + CAR ; + PAIR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + SWAP ; + PAIR } ; + SWAP ; + DROP } ; + view "get_total_supply" + nat + nat + { UNPAIR ; + SWAP ; + CAR ; + GET 13 ; + SWAP ; + GET ; + IF_NONE { PUSH string "not-launched" ; FAILWITH } {} ; + GET 16 } ; + view "get_reserves" + nat + (map nat nat) + { UNPAIR ; + SWAP ; + CAR ; + GET 13 ; + SWAP ; + GET ; + IF_NONE { PUSH string "not-launched" ; FAILWITH } {} ; + GET 9 ; + MAP { CDR ; GET 4 } } ; + view "get_token_map" + nat + (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + { UNPAIR ; + SWAP ; + CAR ; + GET 9 ; + SWAP ; + GET ; + IF_NONE { PUSH string "not-launched" ; FAILWITH } {} } ; + view "get_tok_per_share" + nat + (map nat nat) + { UNPAIR ; + SWAP ; + CAR ; + GET 13 ; + SWAP ; + GET ; + IF_NONE { PUSH string "not-launched" ; FAILWITH } {} ; + DUP ; + GET 9 ; + MAP { CDR ; + DUP 2 ; + GET 16 ; + PUSH nat 1000000000000000000 ; + DIG 2 ; + GET 4 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } ; + SWAP ; + DROP } ; + view "calc_divest_one_coin" + (pair (nat %pool_id) (nat %token_amount) (nat %i)) nat { PUSH nat 100 ; PUSH string "timestamp-error" ; + PUSH string "wrong-index" ; PUSH string "value-not-natural" ; - DIG 2 ; LAMBDA - (pair nat (pair (map nat (pair nat nat nat)) nat)) + (pair (pair string string nat) + (pair (pair (pair nat nat) (map nat nat) nat) + nat + timestamp + nat + timestamp + (map nat (pair nat nat nat)) + (pair nat nat nat) + (pair (option address) (map nat (pair nat nat nat nat bool bool))) + (pair (map nat nat) (map nat nat) nat) + nat)) nat { UNPAIR ; - SWAP ; + UNPAIR 3 ; + DIG 3 ; UNPAIR ; - MAP { CDR ; - PUSH nat 1000000000000000000 ; - SWAP ; - DUP ; - DUG 2 ; - GET 4 ; - DIG 2 ; - CAR ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR } ; - PUSH nat 0 ; - SWAP ; - DUP ; - DUG 2 ; - ITER { CDR ; ADD } ; - SWAP ; - DUP ; - DUG 2 ; + UNPAIR ; + UNPAIR ; + DIG 2 ; + UNPAIR ; + DUP 5 ; + GET 9 ; SIZE ; DUP ; + DUP 6 ; + COMPARE ; + LT ; + IF { DIG 7 ; DROP } { DIG 7 ; FAILWITH } ; + DUP ; DIG 4 ; MUL ; PUSH nat 0 ; - DUP 4 ; + PUSH nat 1 ; + DUP 6 ; PAIR ; - LEFT (pair nat nat) ; - LOOP_LEFT - { PUSH nat 1 ; - SWAP ; - DUP ; - DUG 2 ; + PAIR ; + DIG 3 ; + ITER { SWAP ; + DUP 6 ; + DUP 3 ; + CAR ; + COMPARE ; + NEQ ; + IF { SWAP ; + CDR ; + DUP 2 ; + DUP 2 ; + DIG 3 ; + CDR ; + ADD ; + SWAP ; + CAR ; + PAIR ; + SWAP ; + DUP 2 ; + CDR ; + DUP 3 ; + CAR ; + CDR ; + DUP 7 ; + DIG 4 ; + CAR ; + CAR ; + MUL ; + PAIR ; + PAIR ; + SWAP ; + DUP 2 ; + CDR ; + DUP 3 ; + CAR ; + DUP 6 ; + DIG 3 ; + MUL ; + DIG 3 ; + CAR ; + CDR ; + MUL ; + SWAP ; + CAR ; + PAIR ; + PAIR } + { SWAP ; DROP } } ; + DIG 2 ; + DIG 4 ; + DROP 2 ; + DUP ; + CAR ; + CDR ; + DUP 2 ; + CAR ; + CAR ; + EDIV ; + IF_NONE + { PUSH string "ediv-error" ; FAILWITH } + { PUSH nat 0 ; + DUP 2 ; CDR ; - DUP 3 ; - CAR ; - SUB ; - ABS ; COMPARE ; GT ; - IF { PUSH nat 1 ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - PAIR ; - DUP 6 ; - ITER { SWAP ; - DUP 5 ; - DIG 2 ; - CDR ; - MUL ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - MUL ; - DUP 3 ; - CAR ; - DIG 2 ; - CAR ; - MUL ; - PAIR } ; - UNPAIR ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - SWAP ; - DUP ; - CAR ; - UPDATE 2 ; - DUP ; - DUP 3 ; - PUSH nat 1 ; - DUP 7 ; - ADD ; - MUL ; - DUP 9 ; - DUP 4 ; - CAR ; - PUSH string "wrong-precision" ; - DUP 12 ; - DUP 9 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - ADD ; - DIG 2 ; - CAR ; - DUP 6 ; - DIG 4 ; - MUL ; - DUP 9 ; - DUP 8 ; - DUP 7 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - ADD ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - UPDATE 1 ; - LEFT (pair nat nat) } - { RIGHT (pair nat nat) } } ; - SWAP ; - DIG 2 ; - DIG 3 ; + IF { PUSH nat 1 ; SWAP ; CAR ; ADD } { CAR } } ; DIG 4 ; + GET 9 ; + SIZE ; + DUP 4 ; + MUL ; + DUP 7 ; + DUP 6 ; + DIG 3 ; + MUL ; + MUL ; + EDIV ; + IF_NONE + { PUSH string "ediv-error" ; FAILWITH } + { PUSH nat 0 ; + DUP 2 ; + CDR ; + COMPARE ; + GT ; + IF { PUSH nat 1 ; SWAP ; CAR ; ADD } { CAR } } ; + DIG 2 ; DIG 5 ; - DROP 5 ; - CAR } ; - SWAP ; - APPLY ; - DIG 3 ; - UNPAIR ; - PUSH string "not-launched" ; - DIG 2 ; - CAR ; - GET 13 ; - DUP 3 ; - CAR ; + DUP 5 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DIG 2 ; + CDR ; + ADD ; + DUP 3 ; + PUSH nat 0 ; + PAIR ; + PUSH bool True ; + LOOP { PUSH nat 1 ; + DUP 2 ; + CAR ; + DUP 3 ; + CDR ; + SUB ; + ABS ; + COMPARE ; + GT ; + DUP ; + IF { DUP 2 ; + CDR ; + DIG 2 ; + CDR ; + PAIR ; + SWAP ; + DUP 2 ; + DUP 7 ; + DUP 7 ; + DUP 6 ; + DUP 6 ; + CDR ; + PUSH int 2 ; + MUL ; + ADD ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 6 ; + DUP 5 ; + CDR ; + DIG 5 ; + CDR ; + MUL ; + ADD ; + EDIV ; + IF_NONE + { PUSH string "ediv-error" ; FAILWITH } + { PUSH nat 0 ; + DUP 2 ; + CDR ; + COMPARE ; + GT ; + IF { PUSH nat 1 ; SWAP ; CAR ; ADD } { CAR } } ; + SWAP ; + CAR ; + PAIR ; + SWAP } + {} } ; + SWAP ; + DIG 2 ; + DIG 3 ; + DIG 4 ; + DROP 4 ; + CDR } ; + DUP 5 ; + DUP 4 ; + DUP 4 ; + PAIR 3 ; + APPLY ; + DIG 5 ; + UNPAIR ; + DUP 2 ; + CAR ; + GET 13 ; + DUP 2 ; + CAR ; GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP ; - GET 5 ; - SWAP ; - DUP ; - DUG 2 ; - GET 7 ; - PAIR ; - SWAP ; + IF_NONE { PUSH string "not-launched" ; FAILWITH } {} ; DUP ; - DUG 2 ; CAR ; - DUP 3 ; + DUP 2 ; GET 3 ; - DIG 2 ; - UNPAIR ; - DUP ; + DUP 3 ; + GET 5 ; + DUP 4 ; + GET 7 ; + DUP 2 ; + DUP 2 ; NOW ; COMPARE ; LT ; - IF { DUP 9 ; + IF { DROP ; + DUP 11 ; DUP 4 ; NOW ; SUB ; ISNAT ; IF_NONE { FAILWITH } { SWAP ; DROP } ; - DIG 9 ; + DIG 11 ; DIG 4 ; DIG 3 ; SUB ; @@ -1053,226 +1194,324 @@ COMPARE ; GT ; IF { ADD } { SWAP ; SUB ; ABS } } - { DIG 2 ; DIG 3 ; DIG 8 ; DROP 4 } ; - DUP ; - DUP 3 ; - GET 9 ; - PAIR ; - DUP 5 ; - SWAP ; - EXEC ; - DUP 3 ; - GET 9 ; - MAP { UNPAIR ; - PUSH nat 0 ; - DUP 7 ; - GET 3 ; - DIG 2 ; - GET ; - IF_NONE {} { SWAP ; DROP } ; - DUP 6 ; - GET 4 ; - IF { SWAP ; DUP ; DUG 2 ; GET 4 ; ADD } - { DUP 8 ; - SWAP ; - DUP 3 ; - GET 4 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } } ; - UPDATE 4 } ; - DIG 2 ; + { SWAP ; DIG 2 ; DIG 3 ; DIG 4 ; DIG 11 ; DROP 5 } ; SWAP ; - PAIR ; + PUSH string "no-fee-view" ; DIG 4 ; - SWAP ; - EXEC ; - DIG 3 ; + CAR ; + GET 29 ; + UNIT ; + VIEW "dev_fee" nat ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 4 ; GET 4 ; - IF { DIG 3 ; - DUP 3 ; - DIG 2 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } } - { DIG 3 ; - SWAP ; - DUP 3 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } } ; - SWAP ; - DIG 2 ; - GET 16 ; + PAIR ; + DIG 3 ; + GET 3 ; + DIG 3 ; DIG 2 ; + UNPAIR ; + DUP 5 ; + GET 9 ; + SIZE ; + DUP 6 ; + GET 9 ; + MAP { CDR ; + PUSH nat 1000000000000000000 ; + DUP 2 ; + GET 4 ; + DIG 2 ; + CAR ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } ; + PUSH nat 0 ; + DUP 2 ; + ITER { CDR ; ADD } ; + DUP 2 ; + SIZE ; + DUP ; + DUP 8 ; MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR } ; - view "get_referral_rewards" - (list (pair (address %user) - (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) - (list (pair (pair %request - (address %user) - (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - (nat %reward))) - { UNPAIR ; - NIL (pair (pair address (or address (pair address nat))) nat) ; - SWAP ; - NIL (pair address (or address (pair address nat))) ; - SWAP ; - ITER { CONS } ; - ITER { SWAP ; - PUSH nat 0 ; - DUP 4 ; - CAR ; - GET 23 ; - DUP 4 ; + PUSH nat 0 ; + DUP 4 ; + PAIR ; + PUSH bool True ; + LOOP { PUSH nat 1 ; + DUP 2 ; CDR ; - DUP 5 ; + DUP 3 ; CAR ; - PAIR ; - GET ; - IF_NONE {} { SWAP ; DROP } ; - DIG 2 ; - PAIR ; - CONS } ; - SWAP ; - DROP } ; - view "get_staker_info" - (list (pair (address %user) (nat %pool_id))) - (list (pair (pair %request (address %user) (nat %pool_id)) - (pair %info (nat %balance) (map %rewards nat nat)))) - { UNPAIR ; - MAP { PUSH string "not-launched" ; - DUP 3 ; - CAR ; - GET 13 ; - DUP 3 ; - CDR ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - EMPTY_MAP nat (pair nat nat) ; - PUSH nat 0 ; - PAIR ; - DUP 4 ; - CAR ; - GET 25 ; - DUP 4 ; - CDR ; - DUP 5 ; - CAR ; - PAIR ; - GET ; - IF_NONE {} { SWAP ; DROP } ; - SWAP ; - GET 15 ; - CAR ; - MAP { UNPAIR ; - PUSH nat 0 ; - PUSH nat 0 ; - PAIR ; + SUB ; + ABS ; + COMPARE ; + GT ; + DUP ; + IF { DUP 2 ; + CAR ; + PUSH nat 1 ; DUP 4 ; - CDR ; - DIG 2 ; - GET ; - IF_NONE {} { SWAP ; DROP } ; + CAR ; + PAIR ; + DUP 8 ; + LAMBDA + (pair (pair nat nat) (pair (pair nat nat) nat nat)) + (pair nat nat) + { UNPAIR ; + UNPAIR ; + DIG 2 ; + UNPAIR ; + DIG 3 ; + DIG 2 ; + CDR ; + MUL ; + DUP 2 ; + CDR ; + MUL ; + DUG 2 ; + CAR ; + MUL ; + PAIR } ; + DUP 8 ; + DUP 5 ; + PAIR ; + APPLY ; + DIG 3 ; + DROP ; + DUG 2 ; + ITER { SWAP ; PAIR ; DUP 2 ; SWAP ; EXEC } ; SWAP ; + DROP ; + UNPAIR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; DUP 3 ; + DIG 3 ; CAR ; - MUL ; - PUSH nat 10000000000 ; + UPDATE 2 ; + DUG 2 ; DUP 3 ; - CDR ; - DIG 2 ; + DUP 2 ; + PUSH nat 1 ; + DUP 8 ; + ADD ; + MUL ; + DUP 19 ; + DUP 6 ; + CAR ; + PUSH string "wrong-precision" ; + DUP 22 ; + DUP 10 ; SUB ; - ABS ; - DIG 2 ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; CAR ; ADD ; + DIG 4 ; + CAR ; + DUP 7 ; + DIG 4 ; + MUL ; + DUP 19 ; + DUP 9 ; + DUP 8 ; + MUL ; EDIV ; IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR } ; - SWAP ; - CAR ; - PAIR ; - SWAP ; - PAIR } ; - SWAP ; - DROP } ; - view "get_fees" - nat - (pair (nat %lp_f) (nat %stakers_f) (nat %ref_f)) - { UNPAIR ; - PUSH string "not-launched" ; - DIG 2 ; - CAR ; - GET 13 ; - DIG 2 ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - GET 11 } ; - view "view_A" - nat - nat - { PUSH string "timestamp-error" ; + CAR ; + ADD ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + UPDATE 1 ; + SWAP } + {} } ; SWAP ; - UNPAIR ; - PUSH string "not-launched" ; DIG 2 ; + DIG 3 ; + DIG 14 ; + DROP 4 ; CAR ; - GET 13 ; - DIG 2 ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - PUSH nat 100 ; + DUP 8 ; + GET 16 ; + DUP 11 ; SWAP ; - DUP ; - DUG 2 ; - GET 5 ; DUP 3 ; - GET 7 ; + DUP 10 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DUP 3 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 2 ; + DUP 2 ; + COMPARE ; + LT ; + IF {} { PUSH string "zero-amount-in" ; FAILWITH } ; + DUP 9 ; + DUP 2 ; + DUP 5 ; + PAIR ; + DUP 7 ; + DUP 10 ; + PAIR ; PAIR ; + PAIR ; + DUP 11 ; + SWAP ; + EXEC ; + DUP 10 ; + GET 11 ; + DIG 7 ; + DUP 2 ; + GET 4 ; DUP 3 ; - CAR ; - DIG 3 ; GET 3 ; - DIG 2 ; - UNPAIR ; + DIG 3 ; + CAR ; + ADD ; + ADD ; + ADD ; + DUP 5 ; + MAP { UNPAIR ; + DUP 9 ; + SWAP ; + COMPARE ; + EQ ; + IF { DUP 13 ; + DUP 4 ; + DUP 7 ; + DUP 7 ; + DUP 5 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } } + { DUP 13 ; + DUP 6 ; + DUP 6 ; + DUP 4 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DUP 3 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } } ; + DUP 14 ; + PUSH nat 10000000000 ; + PUSH string "wrong-tokens-count" ; + PUSH nat 1 ; + DUP 12 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + PUSH nat 4 ; + MUL ; + DUP 11 ; + DUP 7 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DIG 3 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DIG 2 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } } ; + SWAP ; + DIG 4 ; + DIG 6 ; + DROP 3 ; DUP ; - NOW ; + DUP 6 ; + GET ; + IF_NONE { DUP 11 ; FAILWITH } {} ; + DUP 11 ; + DUP 10 ; + DIG 5 ; + DIG 4 ; + PAIR ; + DUP 7 ; + DIG 8 ; + PAIR ; + PAIR ; + PAIR ; + DIG 8 ; + SWAP ; + EXEC ; + DIG 2 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 6 ; + GET 9 ; + DUP 5 ; + GET ; + IF_NONE { DUP 8 ; FAILWITH } {} ; + PUSH string "low-reserves" ; + DUP 2 ; + GET 4 ; + DUP 4 ; COMPARE ; LT ; - IF { DUP 6 ; - DUP 4 ; - NOW ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DIG 6 ; - DIG 4 ; - DIG 3 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP 4 ; - DUP 4 ; - SUB ; - ABS ; - SWAP ; - DUG 2 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DUP 3 ; - DIG 2 ; - COMPARE ; - GT ; - IF { ADD } { SWAP ; SUB ; ABS } } - { DIG 2 ; DIG 3 ; DIG 5 ; DROP 4 } ; + IF { DROP } { FAILWITH } ; + GET 3 ; + DIG 3 ; + DIG 4 ; + GET ; + IF_NONE { DIG 6 ; FAILWITH } { DIG 7 ; DROP } ; + DUP 2 ; + DIG 3 ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DUG 2 ; + SWAP ; + DUP 7 ; + DIG 4 ; + DIG 3 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; EDIV ; IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + PUSH string "low-total-supply" ; + DIG 3 ; + DIG 4 ; + GET 16 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUG 2 ; + DIG 3 ; + DUP 3 ; + DIG 2 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DIG 2 ; + SWAP ; + DIG 2 ; + PAIR 3 ; CAR } ; view "get_dy" (pair (nat %pool_id) (nat %i) (nat %j) (nat %dx)) @@ -1282,36 +1521,24 @@ PUSH string "timestamp-error" ; PUSH string "wrong-index" ; PUSH string "value-not-natural" ; - PUSH string "ediv-error" ; - DIG 6 ; + DIG 5 ; UNPAIR ; - PUSH string "not-launched" ; - DUP 3 ; + DUP 2 ; CAR ; GET 13 ; - DUP 3 ; + DUP 2 ; CAR ; GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP ; - DUP 3 ; - GET 6 ; - PAIR ; - DUP 3 ; + IF_NONE { PUSH string "not-launched" ; FAILWITH } {} ; + DUP 2 ; GET 5 ; - DIG 3 ; + DUP 3 ; GET 3 ; - DIG 2 ; - UNPAIR ; - SWAP ; - DUP ; - DUG 2 ; + DUP 3 ; GET 9 ; MAP { CDR ; - DUP 13 ; - SWAP ; - DUP ; - DUG 2 ; + DUP 11 ; + DUP 2 ; GET 4 ; DIG 2 ; CAR ; @@ -1319,88 +1546,74 @@ EDIV ; IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; CAR } ; - DUP 10 ; - SWAP ; DUP ; - DUG 2 ; - DUP 6 ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP 11 ; DUP 3 ; - DUP 8 ; GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP 12 ; + IF_NONE { DUP 8 ; FAILWITH } {} ; + DUP 2 ; + DUP 5 ; + GET ; + IF_NONE { DUP 9 ; FAILWITH } {} ; DUP 6 ; GET 9 ; - DUP 8 ; + DUP 5 ; GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DIG 12 ; + IF_NONE { DUP 10 ; FAILWITH } {} ; DUP 7 ; GET 9 ; - DUP 10 ; + DUP 7 ; GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP 16 ; + IF_NONE { DIG 10 ; FAILWITH } { DIG 11 ; DROP } ; + DUP 14 ; DIG 2 ; CAR ; - DIG 6 ; + DIG 9 ; + GET 6 ; MUL ; EDIV ; IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; CAR ; DIG 3 ; ADD ; - DIG 4 ; - DIG 4 ; - DIG 2 ; - PAIR ; - DIG 5 ; - DIG 5 ; - DIG 2 ; - UNPAIR ; - DUP 5 ; + DUP 7 ; GET 9 ; SIZE ; - DUP 5 ; - DUP 5 ; + DUP 7 ; + DUP 7 ; COMPARE ; NEQ ; IF {} { PUSH string "failed assertion" ; FAILWITH } ; DUP ; - DUP 6 ; + DUP 8 ; COMPARE ; LT ; IF {} { PUSH string "failed assertion" ; FAILWITH } ; DUP ; - DUP 5 ; + DUP 7 ; COMPARE ; LT ; IF {} { PUSH string "failed assertion" ; FAILWITH } ; - DUP 6 ; - GET 5 ; - DUP 7 ; - GET 7 ; - PAIR ; - DUP 7 ; - CAR ; DUP 8 ; + CAR ; + DUP 9 ; GET 3 ; - DIG 2 ; - UNPAIR ; - DUP ; + DUP 10 ; + GET 5 ; + DUP 11 ; + GET 7 ; + DUP 2 ; + DUP 2 ; NOW ; COMPARE ; LT ; - IF { DUP 17 ; + IF { DROP ; + DUP 15 ; DUP 4 ; NOW ; SUB ; ISNAT ; IF_NONE { FAILWITH } { SWAP ; DROP } ; - DIG 17 ; + DIG 15 ; DIG 4 ; DIG 3 ; SUB ; @@ -1421,24 +1634,14 @@ COMPARE ; GT ; IF { ADD } { SWAP ; SUB ; ABS } } - { DIG 2 ; DIG 3 ; DIG 16 ; DROP 4 } ; - SWAP ; - DUP ; - DUG 2 ; - SWAP ; - DUP ; - DUG 2 ; + { SWAP ; DIG 2 ; DIG 3 ; DIG 4 ; DIG 15 ; DROP 5 } ; + DUP 2 ; + DUP 2 ; MUL ; - SWAP ; - DUP 5 ; PUSH nat 0 ; - SWAP ; - DUP ; - DUG 2 ; + DUP 8 ; ITER { CDR ; ADD } ; - SWAP ; - DUP ; - DUG 2 ; + DUP 8 ; SIZE ; DUP ; DIG 4 ; @@ -1446,278 +1649,268 @@ PUSH nat 0 ; DUP 4 ; PAIR ; - LEFT (pair nat nat) ; - LOOP_LEFT - { PUSH nat 1 ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - DUP 3 ; - CAR ; - SUB ; - ABS ; - COMPARE ; - GT ; - IF { PUSH nat 1 ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - PAIR ; - DUP 6 ; - ITER { SWAP ; - DUP 5 ; + PUSH bool True ; + LOOP { PUSH nat 1 ; + DUP 2 ; + CDR ; + DUP 3 ; + CAR ; + SUB ; + ABS ; + COMPARE ; + GT ; + DUP ; + IF { DUP 2 ; + CAR ; + PUSH nat 1 ; + DUP 4 ; + CAR ; + PAIR ; + DUP 13 ; + LAMBDA + (pair (pair nat nat) (pair (pair nat nat) nat nat)) + (pair nat nat) + { UNPAIR ; + UNPAIR ; + DIG 2 ; + UNPAIR ; + DIG 3 ; DIG 2 ; CDR ; MUL ; - SWAP ; - DUP ; - DUG 2 ; + DUP 2 ; CDR ; MUL ; - DUP 3 ; - CAR ; - DIG 2 ; + DUG 2 ; CAR ; MUL ; PAIR } ; - UNPAIR ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - SWAP ; - DUP ; - CAR ; - UPDATE 2 ; - DUP ; - DUP 3 ; - PUSH nat 1 ; - DUP 7 ; - ADD ; - MUL ; - DUP 22 ; - DUP 4 ; - CAR ; - PUSH string "wrong-precision" ; - DUP 25 ; - DUP 9 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - ADD ; - DIG 2 ; - CAR ; - DUP 6 ; - DIG 4 ; - MUL ; - DUP 22 ; - DUP 8 ; - DUP 7 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - ADD ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - UPDATE 1 ; - LEFT (pair nat nat) } - { RIGHT (pair nat nat) } } ; + DUP 8 ; + DUP 5 ; + PAIR ; + APPLY ; + DIG 3 ; + DROP ; + DUG 2 ; + ITER { SWAP ; PAIR ; DUP 2 ; SWAP ; EXEC } ; + SWAP ; + DROP ; + UNPAIR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DUP 3 ; + DIG 3 ; + CAR ; + UPDATE 2 ; + DUG 2 ; + DUP 3 ; + DUP 2 ; + PUSH nat 1 ; + DUP 8 ; + ADD ; + MUL ; + DUP 20 ; + DUP 6 ; + CAR ; + PUSH string "wrong-precision" ; + DUP 23 ; + DUP 10 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + ADD ; + DIG 4 ; + CAR ; + DUP 7 ; + DIG 4 ; + MUL ; + DUP 20 ; + DUP 9 ; + DUP 8 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + ADD ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + UPDATE 1 ; + SWAP } + {} } ; SWAP ; DIG 2 ; DIG 3 ; - DIG 4 ; - DROP 4 ; + DROP 3 ; CAR ; PUSH nat 0 ; PUSH nat 1 ; DUP 3 ; PAIR ; PAIR ; - DIG 5 ; - ITER { DUP ; - DUG 2 ; + DIG 7 ; + ITER { SWAP ; + DUP 2 ; CAR ; - DUP 9 ; - SWAP ; - DUP ; - DUG 2 ; + DUP 11 ; + DUP 2 ; COMPARE ; NEQ ; - IF { DUP 8 ; + IF { DUP 10 ; SWAP ; COMPARE ; EQ ; IF { SWAP ; DROP ; DUP 5 } { SWAP ; CDR } ; - DUP ; - DUP 3 ; + DUP 2 ; + DUP 2 ; + DIG 3 ; CDR ; ADD ; - DIG 2 ; + SWAP ; CAR ; PAIR ; - DUP ; - CDR ; SWAP ; - DUP ; - DUG 2 ; + DUP 2 ; + CDR ; + DUP 3 ; CAR ; CDR ; DUP 5 ; - DIG 3 ; + DIG 4 ; CAR ; CAR ; MUL ; PAIR ; PAIR ; - DUP ; + SWAP ; + DUP 2 ; CDR ; - DUP 6 ; - DUP 4 ; - MUL ; DUP 3 ; CAR ; - CDR ; + DUP 7 ; + DIG 3 ; MUL ; - DIG 2 ; + DIG 3 ; CAR ; + CDR ; + MUL ; + SWAP ; CAR ; PAIR ; - PAIR ; - SWAP ; PAIR } - { DIG 2 ; DROP 2 ; PUSH nat 0 ; PAIR } ; - CDR } ; + { DIG 2 ; DROP 2 } } ; DIG 3 ; DIG 4 ; - DIG 5 ; - DIG 6 ; + DIG 7 ; + DIG 8 ; DROP 4 ; DUP ; CAR ; CDR ; - SWAP ; - DUP ; - DUG 2 ; + DUP 2 ; CAR ; CAR ; EDIV ; IF_NONE - { DUP 9 ; FAILWITH } + { PUSH string "ediv-error" ; FAILWITH } { PUSH nat 0 ; - SWAP ; - DUP ; - DUG 2 ; + DUP 2 ; CDR ; COMPARE ; GT ; IF { PUSH nat 1 ; SWAP ; CAR ; ADD } { CAR } } ; - DIG 4 ; - DIG 3 ; - DIG 3 ; - CDR ; - PAIR ; - DIG 3 ; - DIG 3 ; - DIG 2 ; - UNPAIR ; - DIG 4 ; + DUP 7 ; GET 9 ; SIZE ; DUP 5 ; MUL ; - DUP 12 ; - DUP 4 ; - DIG 5 ; + DUP 11 ; + DUP 5 ; + DIG 3 ; MUL ; MUL ; EDIV ; IF_NONE - { DUP 8 ; FAILWITH } + { PUSH string "ediv-error" ; FAILWITH } { PUSH nat 0 ; - SWAP ; - DUP ; - DUG 2 ; + DUP 2 ; CDR ; COMPARE ; GT ; IF { PUSH nat 1 ; SWAP ; CAR ; ADD } { CAR } } ; DIG 3 ; - DIG 10 ; + DIG 9 ; DUP 5 ; MUL ; EDIV ; IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; CAR ; DIG 2 ; + CDR ; ADD ; DUP 3 ; PUSH nat 0 ; PAIR ; - LEFT (pair nat nat) ; - LOOP_LEFT - { PUSH nat 1 ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - DUP 3 ; - CDR ; - SUB ; - ABS ; - COMPARE ; - GT ; - IF { DUP ; - CDR ; - SWAP ; - CDR ; - PAIR ; - DUP 10 ; - DUP 5 ; - DUP 4 ; - DUP 4 ; - CDR ; - PUSH int 2 ; - MUL ; - ADD ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP 4 ; - DUP 3 ; - CDR ; - DUP 4 ; - CDR ; - MUL ; - ADD ; - EDIV ; - IF_NONE - { DUP 9 ; FAILWITH } - { PUSH nat 0 ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - COMPARE ; - GT ; - IF { PUSH nat 1 ; SWAP ; CAR ; ADD } { CAR } } ; - SWAP ; - CAR ; - PAIR ; - LEFT (pair nat nat) } - { RIGHT (pair nat nat) } } ; + PUSH bool True ; + LOOP { PUSH nat 1 ; + DUP 2 ; + CAR ; + DUP 3 ; + CDR ; + SUB ; + ABS ; + COMPARE ; + GT ; + DUP ; + IF { DUP 2 ; + CDR ; + DIG 2 ; + CDR ; + PAIR ; + SWAP ; + DUP 2 ; + DUP 11 ; + DUP 7 ; + DUP 6 ; + DUP 6 ; + CDR ; + PUSH int 2 ; + MUL ; + ADD ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 6 ; + DUP 5 ; + CDR ; + DIG 5 ; + CDR ; + MUL ; + ADD ; + EDIV ; + IF_NONE + { PUSH string "ediv-error" ; FAILWITH } + { PUSH nat 0 ; + DUP 2 ; + CDR ; + COMPARE ; + GT ; + IF { PUSH nat 1 ; SWAP ; CAR ; ADD } { CAR } } ; + SWAP ; + CAR ; + PAIR ; + SWAP } + {} } ; SWAP ; DIG 2 ; DIG 3 ; - DIG 8 ; - DROP 4 ; + DROP 3 ; CDR ; DIG 5 ; SWAP ; @@ -1725,9 +1918,7 @@ SUB ; ISNAT ; IF_NONE { FAILWITH } { SWAP ; DROP } ; - SWAP ; - DUP ; - DUG 2 ; + DUP 2 ; CAR ; DIG 5 ; DIG 2 ; @@ -1743,9 +1934,7 @@ LT ; IF { DROP } { FAILWITH } ; PUSH nat 10000000000 ; - SWAP ; - DUP ; - DUG 2 ; + DUP 2 ; PUSH string "no-fee-view" ; DIG 5 ; CAR ; @@ -1755,8 +1944,8 @@ IF_NONE { FAILWITH } { SWAP ; DROP } ; DIG 4 ; GET 11 ; - DUP ; - DUG 2 ; + SWAP ; + DUP 2 ; GET 4 ; DUP 3 ; GET 3 ; @@ -1775,268 +1964,40 @@ SUB ; ISNAT ; IF_NONE { FAILWITH } { SWAP ; DROP } } ; - view "calc_divest_one_coin" - (pair (nat %pool_id) (nat %token_amount) (nat %i)) + view "view_A" nat - { PUSH nat 100 ; - PUSH string "timestamp-error" ; - PUSH string "wrong-index" ; - PUSH string "value-not-natural" ; - PUSH string "ediv-error" ; - DUP 5 ; - DUP 4 ; + nat + { PUSH string "timestamp-error" ; + SWAP ; + UNPAIR ; + SWAP ; + CAR ; + GET 13 ; + SWAP ; + GET ; + IF_NONE { PUSH string "not-launched" ; FAILWITH } {} ; + PUSH nat 100 ; + DUP 2 ; + CAR ; + DUP 3 ; + GET 3 ; DUP 4 ; - DIG 3 ; - PAIR 4 ; - LAMBDA - (pair (pair string (pair string (pair string nat))) - (pair (pair (pair nat nat) (pair (map nat nat) nat)) - (pair nat - timestamp - nat - timestamp - (map nat (pair nat nat nat)) - (pair nat nat nat) - (pair (option address) (map nat (pair nat nat nat nat bool bool))) - (pair (map nat nat) (map nat nat) nat) - nat))) - nat - { UNPAIR ; - UNPAIR 4 ; - DIG 4 ; - UNPAIR ; - UNPAIR ; - UNPAIR ; - DIG 2 ; - UNPAIR ; - DUP 5 ; - GET 9 ; - SIZE ; - DIG 8 ; - SWAP ; - DUP ; - DUG 2 ; - DUP 7 ; - COMPARE ; - LT ; - IF { DROP } { FAILWITH } ; - DUP ; - DIG 4 ; - MUL ; - PUSH nat 0 ; - PUSH nat 1 ; - DUP 6 ; - PAIR ; - PAIR ; - DIG 3 ; - ITER { SWAP ; - DUP 6 ; - DUP 3 ; - CAR ; - COMPARE ; - NEQ ; - IF { SWAP ; - CDR ; - DUP ; - DUP 3 ; - CDR ; - ADD ; - DIG 2 ; - CAR ; - PAIR ; - DUP ; - CDR ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - CDR ; - DUP 7 ; - DIG 3 ; - CAR ; - CAR ; - MUL ; - PAIR ; - PAIR ; - DUP ; - CDR ; - DUP 5 ; - DUP 4 ; - MUL ; - DUP 3 ; - CAR ; - CDR ; - MUL ; - DIG 2 ; - CAR ; - CAR ; - PAIR ; - PAIR ; - SWAP ; - PAIR } - { SWAP ; DROP ; PUSH nat 0 ; PAIR } ; - CDR } ; - DIG 2 ; - DIG 4 ; - DROP 2 ; - DUP ; - CAR ; - CDR ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - CAR ; - EDIV ; - IF_NONE - { DUP 5 ; FAILWITH } - { PUSH nat 0 ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - COMPARE ; - GT ; - IF { PUSH nat 1 ; SWAP ; CAR ; ADD } { CAR } } ; - DIG 4 ; - DIG 4 ; - DIG 3 ; - CDR ; - PAIR ; - DIG 3 ; - DIG 3 ; - DIG 2 ; - UNPAIR ; - DIG 4 ; - GET 9 ; - SIZE ; - DUP 5 ; - MUL ; - DUP 8 ; - DUP 4 ; - DIG 5 ; - MUL ; - MUL ; - EDIV ; - IF_NONE - { DUP 4 ; FAILWITH } - { PUSH nat 0 ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - COMPARE ; - GT ; - IF { PUSH nat 1 ; SWAP ; CAR ; ADD } { CAR } } ; - DIG 3 ; - DIG 6 ; - DUP 5 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DIG 2 ; - ADD ; - DUP 3 ; - PUSH nat 0 ; - PAIR ; - LEFT (pair nat nat) ; - LOOP_LEFT - { PUSH nat 1 ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - DUP 3 ; - CDR ; - SUB ; - ABS ; - COMPARE ; - GT ; - IF { DUP ; - CDR ; - SWAP ; - CDR ; - PAIR ; - DUP 6 ; - DUP 5 ; - DUP 4 ; - DUP 4 ; - CDR ; - PUSH int 2 ; - MUL ; - ADD ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP 4 ; - DUP 3 ; - CDR ; - DUP 4 ; - CDR ; - MUL ; - ADD ; - EDIV ; - IF_NONE - { DUP 5 ; FAILWITH } - { PUSH nat 0 ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - COMPARE ; - GT ; - IF { PUSH nat 1 ; SWAP ; CAR ; ADD } { CAR } } ; - SWAP ; - CAR ; - PAIR ; - LEFT (pair nat nat) } - { RIGHT (pair nat nat) } } ; - SWAP ; - DIG 2 ; - DIG 3 ; - DIG 4 ; - DIG 5 ; - DROP 5 ; - CDR } ; - SWAP ; - APPLY ; - DIG 5 ; - UNPAIR ; - PUSH string "not-launched" ; - DUP 3 ; - CAR ; - GET 13 ; - DUP 3 ; - CAR ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP ; GET 5 ; - SWAP ; - DUP ; - DUG 2 ; + DIG 4 ; GET 7 ; - PAIR ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - DUP 3 ; - GET 3 ; - DIG 2 ; - UNPAIR ; - DUP ; + DUP 2 ; + DUP 2 ; NOW ; COMPARE ; LT ; - IF { DUP 11 ; + IF { DROP ; + DUP 6 ; DUP 4 ; NOW ; SUB ; ISNAT ; IF_NONE { FAILWITH } { SWAP ; DROP } ; - DIG 11 ; + DIG 6 ; DIG 4 ; DIG 3 ; SUB ; @@ -2057,421 +2018,346 @@ COMPARE ; GT ; IF { ADD } { SWAP ; SUB ; ABS } } - { DIG 2 ; DIG 3 ; DIG 10 ; DROP 4 } ; + { SWAP ; DIG 2 ; DIG 3 ; DIG 4 ; DIG 6 ; DROP 5 } ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } ; + view "get_fees" + nat + (pair (nat %lp_f) (nat %stakers_f) (nat %ref_f)) + { UNPAIR ; SWAP ; - PUSH string "no-fee-view" ; - DIG 4 ; CAR ; - GET 29 ; - UNIT ; - VIEW "dev_fee" nat ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP 4 ; - GET 4 ; - PAIR ; - DIG 3 ; - GET 3 ; - DIG 3 ; - DIG 2 ; - UNPAIR ; - DUP 5 ; - GET 9 ; - MAP { CDR ; - PUSH nat 1000000000000000000 ; + GET 13 ; + SWAP ; + GET ; + IF_NONE { PUSH string "not-launched" ; FAILWITH } {} ; + GET 11 } ; + view "get_staker_info" + (list (pair (address %user) (nat %pool_id))) + (list (pair (pair %request (address %user) (nat %pool_id)) + (pair %info (nat %balance) (map %rewards nat nat)))) + { UNPAIR ; + MAP { DUP 2 ; + CAR ; + GET 13 ; + DUP 2 ; + CDR ; + GET ; + IF_NONE { PUSH string "not-launched" ; FAILWITH } {} ; + DUP 3 ; + CAR ; + GET 25 ; + DUP 3 ; + CDR ; + DUP 4 ; + CAR ; + PAIR ; + GET ; + IF_NONE { EMPTY_MAP nat (pair nat nat) ; PUSH nat 0 ; PAIR } {} ; SWAP ; - DUP ; - DUG 2 ; - GET 4 ; - DIG 2 ; + GET 15 ; CAR ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR } ; - DUP 4 ; + MAP { UNPAIR ; + DUP 3 ; + CDR ; + SWAP ; + GET ; + IF_NONE { PUSH nat 0 ; PUSH nat 0 ; PAIR } {} ; + SWAP ; + DUP 3 ; + CAR ; + MUL ; + PUSH nat 10000000000 ; + DUP 3 ; + CDR ; + DIG 2 ; + SUB ; + ABS ; + DIG 2 ; + CAR ; + ADD ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } ; + SWAP ; + CAR ; + PAIR ; + SWAP ; + PAIR } ; SWAP ; - DUP ; - DUG 2 ; - PUSH nat 0 ; + DROP } ; + view "get_referral_rewards" + (list (pair (address %user) + (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id))))) + (list (pair (pair %request + (address %user) + (or %token (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) + (nat %reward))) + { UNPAIR ; + NIL (pair (pair address (or address (pair address nat))) nat) ; SWAP ; - DUP ; - DUG 2 ; - ITER { CDR ; ADD } ; + NIL (pair address (or address (pair address nat))) ; SWAP ; - DUP ; - DUG 2 ; - SIZE ; - DUP ; - DIG 4 ; - MUL ; - PUSH nat 0 ; - DUP 4 ; - PAIR ; - LEFT (pair nat nat) ; - LOOP_LEFT - { PUSH nat 1 ; - SWAP ; - DUP ; - DUG 2 ; - CDR ; - DUP 3 ; - CAR ; - SUB ; - ABS ; - COMPARE ; - GT ; - IF { PUSH nat 1 ; - SWAP ; - DUP ; - DUG 2 ; - CAR ; - PAIR ; - DUP 6 ; - ITER { SWAP ; + ITER { CONS } ; + ITER { SWAP ; + DUP 3 ; + CAR ; + GET 23 ; + DUP 3 ; + CDR ; + DUP 4 ; + CAR ; + PAIR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + DIG 2 ; + PAIR ; + CONS } ; + SWAP ; + DROP } ; + view "calc_token_amount" + (pair (nat %pool_id) (map %amounts nat nat) (bool %is_deposit)) + nat + { PUSH nat 100 ; + PUSH string "timestamp-error" ; + PUSH string "value-not-natural" ; + LAMBDA + (pair nat (pair (map nat (pair nat nat nat)) nat)) + nat + { UNPAIR ; + SWAP ; + UNPAIR ; + MAP { CDR ; + PUSH nat 1000000000000000000 ; + DUP 2 ; + GET 4 ; + DIG 2 ; + CAR ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } ; + PUSH nat 0 ; + DUP 2 ; + ITER { CDR ; ADD } ; + DUP 2 ; + SIZE ; + DUP ; + DIG 4 ; + MUL ; + PUSH nat 0 ; + DUP 4 ; + PAIR ; + PUSH bool True ; + LOOP { PUSH nat 1 ; + DUP 2 ; + CDR ; + DUP 3 ; + CAR ; + SUB ; + ABS ; + COMPARE ; + GT ; + DUP ; + IF { DUP 2 ; + CAR ; + PUSH nat 1 ; + DUP 4 ; + CAR ; + PAIR ; + DUP 8 ; + LAMBDA + (pair (pair nat nat) (pair (pair nat nat) nat nat)) + (pair nat nat) + { UNPAIR ; + UNPAIR ; + DIG 2 ; + UNPAIR ; + DIG 3 ; + DIG 2 ; + CDR ; + MUL ; + DUP 2 ; + CDR ; + MUL ; + DUG 2 ; + CAR ; + MUL ; + PAIR } ; + DUP 8 ; DUP 5 ; - DIG 2 ; - CDR ; - MUL ; + PAIR ; + APPLY ; + DIG 3 ; + DROP ; + DUG 2 ; + ITER { SWAP ; PAIR ; DUP 2 ; SWAP ; EXEC } ; SWAP ; - DUP ; + DROP ; + UNPAIR ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DUP 3 ; + DIG 3 ; + CAR ; + UPDATE 2 ; DUG 2 ; - CDR ; - MUL ; DUP 3 ; + DUP 2 ; + PUSH nat 1 ; + DUP 8 ; + ADD ; + MUL ; + DUP 10 ; + DUP 6 ; CAR ; - DIG 2 ; + PUSH string "wrong-precision" ; + DUP 13 ; + DUP 10 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; CAR ; + ADD ; + DIG 4 ; + CAR ; + DUP 7 ; + DIG 4 ; MUL ; - PAIR } ; - UNPAIR ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - SWAP ; - DUP ; - CAR ; - UPDATE 2 ; - DUP ; - DUP 3 ; - PUSH nat 1 ; - DUP 7 ; - ADD ; - MUL ; - DUP 18 ; - DUP 4 ; - CAR ; - PUSH string "wrong-precision" ; - DUP 21 ; - DUP 9 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - ADD ; - DIG 2 ; - CAR ; - DUP 6 ; - DIG 4 ; - MUL ; - DUP 18 ; - DUP 8 ; - DUP 7 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - ADD ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - UPDATE 1 ; - LEFT (pair nat nat) } - { RIGHT (pair nat nat) } } ; - SWAP ; - DIG 2 ; + DUP 10 ; + DUP 9 ; + DUP 8 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + ADD ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + UPDATE 1 ; + SWAP } + {} } ; + SWAP ; + DIG 2 ; + DIG 3 ; + DIG 4 ; + DIG 5 ; + DROP 5 ; + CAR } ; + DUP 4 ; + APPLY ; DIG 3 ; - DIG 4 ; - DIG 14 ; - DROP 5 ; + DROP ; + DIG 3 ; + UNPAIR ; + SWAP ; CAR ; - DUP 9 ; - DUP 8 ; - GET 16 ; - DUP 3 ; - DUP 9 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + GET 13 ; + DUP 2 ; CAR ; + GET ; + IF_NONE { PUSH string "not-launched" ; FAILWITH } {} ; + DUP ; + CAR ; + DUP 2 ; + GET 3 ; DUP 3 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - PUSH string "zero-amount-in" ; - DUP 3 ; - DUP 3 ; + GET 5 ; + DUP 4 ; + GET 7 ; + DUP 2 ; + DUP 2 ; + NOW ; COMPARE ; LT ; - IF { DROP } { FAILWITH } ; - DUP 8 ; - SWAP ; + IF { DROP ; + DUP 9 ; + DUP 4 ; + NOW ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DIG 9 ; + DIG 4 ; + DIG 3 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } ; + DUP 4 ; + DUP 4 ; + SUB ; + ABS ; + SWAP ; + DUG 2 ; + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR ; + DUP 3 ; + DIG 2 ; + COMPARE ; + GT ; + IF { ADD } { SWAP ; SUB ; ABS } } + { SWAP ; DIG 2 ; DIG 3 ; DIG 4 ; DIG 9 ; DROP 5 } ; DUP ; - DUG 2 ; - DUP 5 ; - PAIR ; - DUP 6 ; - DUP 9 ; - PAIR ; - PAIR ; + DUP 3 ; + GET 9 ; PAIR ; - DUP 10 ; + DUP 5 ; SWAP ; EXEC ; - DIG 5 ; - DUP 9 ; - GET 11 ; - DUP ; - DUG 2 ; - GET 4 ; DUP 3 ; - GET 3 ; - DIG 3 ; - CAR ; - ADD ; - ADD ; - ADD ; - DUP 5 ; + GET 9 ; MAP { UNPAIR ; - DUP 8 ; + DUP 6 ; + GET 3 ; SWAP ; - COMPARE ; - EQ ; - IF { DUP 12 ; - DUP 4 ; - DUP 7 ; - DUP 7 ; - DUP 5 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } } - { DUP 12 ; - DUP 6 ; - DUP 6 ; - DUP 4 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; + GET ; + IF_NONE { PUSH nat 0 } {} ; + DUP 6 ; + GET 4 ; + IF { DUP 2 ; GET 4 ; ADD } + { DUP 8 ; + SWAP ; DUP 3 ; + GET 4 ; SUB ; ISNAT ; IF_NONE { FAILWITH } { SWAP ; DROP } } ; - DUP 13 ; - PUSH nat 10000000000 ; - DUP 13 ; - GET 9 ; - SIZE ; - DUP 6 ; - PUSH string "wrong-tokens-count" ; - PUSH nat 1 ; - DUP 4 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - PUSH nat 4 ; - MUL ; - DUG 2 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DIG 3 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - DIG 2 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } } ; - SWAP ; - DIG 4 ; - DROP 2 ; - DUP 11 ; + UPDATE 4 } ; + DIG 2 ; SWAP ; - DUP ; - DUG 2 ; - DUP 7 ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP 11 ; - DUP 10 ; - DIG 5 ; - DIG 4 ; PAIR ; - DUP 7 ; - DIG 8 ; - PAIR ; - PAIR ; - PAIR ; - DIG 8 ; + DIG 4 ; SWAP ; EXEC ; - DIG 2 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP 8 ; - DUP 7 ; - GET 9 ; - DUP 6 ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - PUSH string "low-reserves" ; - SWAP ; - DUP ; - DUG 2 ; + DIG 3 ; GET 4 ; - DUP 4 ; - COMPARE ; - LT ; - IF { DROP } { FAILWITH } ; - GET 3 ; - DIG 8 ; - DIG 4 ; - DIG 5 ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; + IF { DIG 3 ; + DUP 3 ; + DIG 2 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } } + { DIG 3 ; + SWAP ; + DUP 3 ; + SUB ; + ISNAT ; + IF_NONE { FAILWITH } { SWAP ; DROP } } ; SWAP ; - DUP ; - DUG 2 ; - DIG 3 ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; DIG 2 ; - DUP 7 ; - DIG 4 ; - DIG 4 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR ; - PUSH string "low-total-supply" ; - DIG 3 ; - DIG 4 ; GET 16 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DIG 3 ; - DUP 4 ; - DIG 3 ; - SUB ; - ISNAT ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DIG 2 ; - PAIR 3 ; - CAR } ; - view "get_tok_per_share" - nat - (map nat nat) - { UNPAIR ; - PUSH string "not-launched" ; - DIG 2 ; - CAR ; - GET 13 ; - DIG 2 ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - DUP ; - GET 9 ; - MAP { CDR ; - SWAP ; - DUP ; - DUG 2 ; - GET 16 ; - PUSH nat 1000000000000000000 ; - DIG 2 ; - GET 4 ; - MUL ; - EDIV ; - IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; - CAR } ; - SWAP ; - DROP } ; - view "get_token_map" - nat - (map nat (or (address %fa12) (pair %fa2 (address %token_address) (nat %token_id)))) - { UNPAIR ; - PUSH string "not-launched" ; - DIG 2 ; - CAR ; - GET 9 ; - DIG 2 ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } } ; - view "get_reserves" - nat - (map nat nat) - { UNPAIR ; - PUSH string "not-launched" ; DIG 2 ; - CAR ; - GET 13 ; - DIG 2 ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - GET 9 ; - MAP { CDR ; GET 4 } } ; - view "get_total_supply" - nat - nat - { UNPAIR ; - PUSH string "not-launched" ; - DIG 2 ; - CAR ; - GET 13 ; - DIG 2 ; - GET ; - IF_NONE { FAILWITH } { SWAP ; DROP } ; - GET 16 } ; - view "get_balance" - (list (pair (address %owner) (nat %token_id))) - (list (pair (pair %request (address %owner) (nat %token_id)) (nat %balance))) - { UNPAIR ; - MAP { PUSH string "FA2_TOKEN_UNDEFINED" ; - DUP 3 ; - CAR ; - GET 7 ; - DUP 3 ; - CDR ; - COMPARE ; - LT ; - IF { DROP } { FAILWITH } ; - PUSH nat 0 ; - DUP 3 ; - CAR ; - GET 15 ; - DUP 3 ; - CDR ; - DUP 4 ; - CAR ; - PAIR ; - GET ; - IF_NONE {} { SWAP ; DROP } ; - SWAP ; - PAIR } ; - SWAP ; - DROP } } + MUL ; + EDIV ; + IF_NONE { PUSH string "DIV by 0" ; FAILWITH } {} ; + CAR } } diff --git a/contracts/partials/admin/lambdas.ligo b/contracts/partials/admin/lambdas.ligo index 5a0feca..01d5594 100644 --- a/contracts/partials/admin/lambdas.ligo +++ b/contracts/partials/admin/lambdas.ligo @@ -42,10 +42,10 @@ function ramp_A( case p of [ | Ramp_A(params) -> { require((params.future_A > 0n) and (params.future_A <= Constants.max_a), Errors.Dex.a_limit); - require(params.future_time >= Tezos.now + Constants.min_ramp_time, Errors.Dex.timestamp_error); // dev: insufficient time + require(params.future_time >= Tezos.get_now() + Constants.min_ramp_time, Errors.Dex.timestamp_error); // dev: insufficient time var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); - require(Tezos.now >= pool.initial_A_time + Constants.min_ramp_time, Errors.Dex.timestamp_error); + require(Tezos.get_now() >= pool.initial_A_time + Constants.min_ramp_time, Errors.Dex.timestamp_error); const initial_A_f: nat = get_A( pool.initial_A_time, @@ -62,7 +62,7 @@ function ramp_A( s.pools[params.pool_id] := pool with record [ initial_A_f = initial_A_f; future_A_f = future_A_f; - initial_A_time = Tezos.now; + initial_A_time = Tezos.get_now(); future_A_time = params.future_time; ]; } @@ -88,8 +88,8 @@ function stop_ramp_A( s.pools[pool_id] := pool with record [ initial_A_f = current_A_f; future_A_f = current_A_f; - initial_A_time = Tezos.now; - future_A_time = Tezos.now; + initial_A_time = Tezos.get_now(); + future_A_time = Tezos.get_now(); ]; } | _ -> unreachable(Unit) @@ -125,7 +125,7 @@ function claim_dev( | Claim_developer(params) -> { require(params.amount > 0n, Errors.Dex.zero_in); const dev_address = get_dev_address(s); - require(Tezos.sender = dev_address, Errors.Dex.not_developer); + require(Tezos.get_sender() = dev_address, Errors.Dex.not_developer); const bal = unwrap_or(s.dev_rewards[params.token], 0n); @@ -133,7 +133,7 @@ function claim_dev( operations := typed_transfer( - Tezos.self_address, + Tezos.get_self_address(), dev_address, params.amount, params.token diff --git a/contracts/partials/admin/methods.ligo b/contracts/partials/admin/methods.ligo index 3a44e29..7e8310f 100644 --- a/contracts/partials/admin/methods.ligo +++ b/contracts/partials/admin/methods.ligo @@ -13,7 +13,7 @@ #if !FACTORY | Set_strategy_factory(_)-> skip #endif - | _ -> require(Tezos.sender = s.storage.admin, Errors.Dex.not_contract_admin) + | _ -> require(Tezos.get_sender() = s.storage.admin, Errors.Dex.not_contract_admin) ]; const idx : nat = case p of [ diff --git a/contracts/partials/admin/standalone/lambdas.ligo b/contracts/partials/admin/standalone/lambdas.ligo index 1c94bdd..3de04d6 100644 --- a/contracts/partials/admin/standalone/lambdas.ligo +++ b/contracts/partials/admin/standalone/lambdas.ligo @@ -60,8 +60,8 @@ function add_pool( const pool = pool_i with record [ initial_A_f = params.a_constant * Constants.a_precision; future_A_f = params.a_constant * Constants.a_precision; - initial_A_time = Tezos.now; - future_A_time = Tezos.now; + initial_A_time = Tezos.get_now(); + future_A_time = Tezos.get_now(); tokens_info = tokens_info; fee = params.fees; ]; @@ -72,7 +72,7 @@ function add_pool( pool = pool; inputs = inputs; min_mint_amount = 1n; - receiver = Some(Tezos.sender) + receiver = Some(Tezos.get_sender()) ], s); operations := res.op; s := res.s; @@ -90,7 +90,7 @@ function set_strategy_factory( case p of [ | Set_strategy_factory(params) -> { const dev_address = get_dev_address(s); - require(Tezos.sender = dev_address, Errors.Dex.not_developer); + require(Tezos.get_sender() = dev_address, Errors.Dex.not_developer); s.strategy_factory := add_rem_candidate(params, s.strategy_factory); } | _ -> unreachable(Unit) diff --git a/contracts/partials/dev/methods.ligo b/contracts/partials/dev/methods.ligo index f883b98..f988a81 100644 --- a/contracts/partials/dev/methods.ligo +++ b/contracts/partials/dev/methods.ligo @@ -5,7 +5,7 @@ : dev_storage_t is block { - require(Tezos.sender = s.dev_address, Errors.Dex.not_developer); + require(Tezos.get_sender() = s.dev_address, Errors.Dex.not_developer); const idx : nat = case p of [ | Set_dev_address(_) -> 0n diff --git a/contracts/partials/dex_core/helpers.ligo b/contracts/partials/dex_core/helpers.ligo index 43435f5..1d6db40 100644 --- a/contracts/partials/dex_core/helpers.ligo +++ b/contracts/partials/dex_core/helpers.ligo @@ -73,8 +73,8 @@ function harvest_staker_rewards( Constants.accum_precision); if reward_amt > 0n then accum.op := typed_transfer( - Tezos.self_address, - Tezos.sender, + Tezos.get_self_address(), + Tezos.get_sender(), reward_amt, get_token_by_id(i, tokens) ) # accum.op @@ -110,15 +110,15 @@ function update_former_and_transfer( ) = case param of [ | Add(p) -> ( staker_accum.balance + p.amount, - Tezos.sender, - Tezos.self_address, + Tezos.get_sender(), + Tezos.get_self_address(), pool_stake_accum.total_staked + p.amount, p.amount ) | Remove(p) -> ( nat_or_error(staker_accum.balance - p.amount, Errors.Dex.wrong_shares_out), - Tezos.self_address, - Tezos.sender, + Tezos.get_self_address(), + Tezos.get_sender(), nat_or_error(pool_stake_accum.total_staked - p.amount, Errors.Dex.wrong_shares_out), p.amount ) @@ -165,7 +165,7 @@ function update_stake( | Remove(p) -> (p.pool_id, p.amount) ]; var operations: list(operation) := Constants.no_operations; - const staker_key = (Tezos.sender, pool_id); + const staker_key = (Tezos.get_sender(), pool_id); var staker_accum := unwrap_or( s.stakers_balance[staker_key], default_staker_info @@ -208,8 +208,8 @@ function get_pool_info( const pool : pool_t = unwrap_or(pools[token_id], record [ initial_A_f = 0n; future_A_f = 0n; - initial_A_time = Tezos.now; - future_A_time = Tezos.now; + initial_A_time = Tezos.get_now(); + future_A_time = Tezos.get_now(); tokens_info = (map []: map(token_pool_idx_t, token_info_t)); fee = record [ lp_f = 0n; diff --git a/contracts/partials/dex_core/lambdas.ligo b/contracts/partials/dex_core/lambdas.ligo index 92786d8..f5a9dbe 100644 --- a/contracts/partials/dex_core/lambdas.ligo +++ b/contracts/partials/dex_core/lambdas.ligo @@ -18,7 +18,7 @@ function swap( const i = params.idx_from; const j = params.idx_to; require(i < tokens_count and j < tokens_count, Errors.Dex.wrong_index); - const receiver = unwrap_or(params.receiver, Tezos.sender); + const receiver = unwrap_or(params.receiver, Tezos.get_sender()); var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); const dy = perform_swap(i, j, dx, pool); const pool_total_staked = pool.staker_accumulator.total_staked; @@ -53,7 +53,7 @@ function swap( pool.tokens_info[i] := token_info_i; pool.tokens_info[j] := token_info_j; operations := typed_transfer( - Tezos.self_address, + Tezos.get_self_address(), receiver, after_fees.dy, token_j @@ -69,8 +69,8 @@ function swap( ); operations := concat_lists(rebalance.0, operations); operations := typed_transfer( - Tezos.sender, - Tezos.self_address, + Tezos.get_sender(), + Tezos.get_self_address(), dx, unwrap(tokens[i], Errors.Dex.no_token) ) # operations; @@ -125,7 +125,7 @@ function divest_liquidity( require(params.shares =/= 0n, Errors.Dex.zero_in); var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); - const receiver = unwrap_or(params.receiver, Tezos.sender); + const receiver = unwrap_or(params.receiver, Tezos.get_sender()); const total_supply : nat = pool.total_supply; function divest_reserves( @@ -140,7 +140,7 @@ function divest_liquidity( require(value >= min_amount_out, Errors.Dex.high_min_out); require(value =/= 0n, Errors.Dex.dust_out); accum.op := typed_transfer( - Tezos.self_address, + Tezos.get_self_address(), receiver, value, entry.1 @@ -163,7 +163,7 @@ function divest_liquidity( pool.strategy := rebalance.1; pool.total_supply := nat_or_error(pool.total_supply - params.shares, Errors.Dex.low_total_supply); - const key = (Tezos.sender, params.pool_id); + const key = (Tezos.get_sender(), params.pool_id); const share = unwrap_or(s.ledger[key], 0n); s.ledger[key] := nat_or_error(share - params.shares, Errors.Dex.insufficient_lp); @@ -188,8 +188,8 @@ function divest_imbalanced( check_deadline(params.deadline); require(params.max_shares > 0n, Errors.Dex.zero_in); - const receiver = unwrap_or(params.receiver, Tezos.sender); - const key = (Tezos.sender, params.pool_id); + const receiver = unwrap_or(params.receiver, Tezos.get_sender()); + const key = (Tezos.get_sender(), params.pool_id); const share = unwrap_or(s.ledger[key], 0n); @@ -223,7 +223,7 @@ function divest_imbalanced( accum.tokens_info[value.0] := t_i; if value.1 > 0n then accum.operations := typed_transfer( - Tezos.self_address, + Tezos.get_self_address(), receiver, value.1, unwrap(tokens[value.0], Errors.Dex.wrong_index) @@ -292,7 +292,7 @@ function divest_imbalanced( operations := concat_lists(rebalance.0, operations); pool.strategy := rebalance.1; s.pools[params.pool_id] := pool; - s.ledger[(Tezos.sender, params.pool_id)] := new_shares; + s.ledger[(Tezos.get_sender(), params.pool_id)] := new_shares; } | _ -> unreachable(Unit) ]; @@ -313,7 +313,7 @@ function divest_one_coin( var pool := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); require(params.token_index < Map.size(pool.tokens_info), Errors.Dex.wrong_index); - const sender_key = (Tezos.sender, params.pool_id); + const sender_key = (Tezos.get_sender(), params.pool_id); const token = get_token_by_id(params.token_index, s.tokens[params.pool_id]); @@ -355,10 +355,10 @@ function divest_one_coin( pool.tokens_info[params.token_index] := info; pool.total_supply := result.ts; check_shares_and_reserves(pool); - const receiver = unwrap_or(params.receiver, Tezos.sender); + const receiver = unwrap_or(params.receiver, Tezos.get_sender()); operations := typed_transfer( - Tezos.self_address, + Tezos.get_self_address(), receiver, result.dy, token @@ -396,15 +396,15 @@ function claim_ref( | Claim_referral(params) -> { require(params.amount > 0n, Errors.Dex.zero_in); - const key = (Tezos.sender, params.token); + const key = (Tezos.get_sender(), params.token); const bal = unwrap_or(s.referral_rewards[key], 0n); s.referral_rewards[key] := nat_or_error(bal - params.amount, Errors.Dex.balance_overflow); operations := typed_transfer( - Tezos.self_address, - Tezos.sender, + Tezos.get_self_address(), + Tezos.get_sender(), params.amount, params.token ) # operations; diff --git a/contracts/partials/dex_core/math.ligo b/contracts/partials/dex_core/math.ligo index dc98a86..2f29b89 100644 --- a/contracts/partials/dex_core/math.ligo +++ b/contracts/partials/dex_core/math.ligo @@ -23,9 +23,9 @@ function get_A( : nat is block { var a := a1; - if Tezos.now < t1 + if Tezos.get_now() < t1 then { - const t_num = nat_or_error(Tezos.now - t0, Errors.Dex.timestamp_error); + const t_num = nat_or_error(Tezos.get_now() - t0, Errors.Dex.timestamp_error); const t_den = nat_or_error(t1 - t0, Errors.Dex.timestamp_error); const diff = abs(a1 - a0); const value = diff * t_num / t_den; @@ -404,8 +404,8 @@ function add_liq( : list(operation) is if input.1 > 0n then typed_transfer( - Tezos.sender, - Tezos.self_address, + Tezos.get_sender(), + Tezos.get_self_address(), input.1, get_token_by_id(input.0, tokens[params.pool_id]) ) # operations @@ -421,7 +421,7 @@ function add_liq( pool.strategy := strategy_store; s.pools[params.pool_id] := pool; - const receiver = unwrap_or(params.receiver, Tezos.sender); + const receiver = unwrap_or(params.receiver, Tezos.get_sender()); const user_key = (receiver, params.pool_id); const share = unwrap_or(s.ledger[user_key], 0n); const new_shares = share + mint_amount; diff --git a/contracts/partials/dex_core/methods.ligo b/contracts/partials/dex_core/methods.ligo index 9c4d417..c127afe 100644 --- a/contracts/partials/dex_core/methods.ligo +++ b/contracts/partials/dex_core/methods.ligo @@ -47,7 +47,7 @@ based on the argument type. var s : full_storage_t) : full_storage_t is block { - assert(Tezos.sender = s.storage.factory_address); + assert(Tezos.get_sender() = s.storage.factory_address); case p of [ | Copy_dex_function(lambda) -> s.dex_lambdas := lambda | Freeze -> s.storage.started := not s.storage.started diff --git a/contracts/partials/fa2/helpers.ligo b/contracts/partials/fa2/helpers.ligo index 1b0fdcb..25359ce 100644 --- a/contracts/partials/fa2/helpers.ligo +++ b/contracts/partials/fa2/helpers.ligo @@ -3,7 +3,7 @@ const from_account : address; const allowances : set(address)) : unit is - require(from_account = Tezos.sender or (allowances contains Tezos.sender), Errors.FA2.not_operator); + require(from_account = Tezos.get_sender() or (allowances contains Tezos.get_sender()), Errors.FA2.not_operator); [@inline] function get_allowances( const key : address * pool_id_t; @@ -48,7 +48,7 @@ | Remove_operator(param) -> (param, False) ]; require(param.operator =/= param.owner, Errors.FA2.owner_as_operator); - require(Tezos.sender = param.owner, Errors.FA2.not_owner); + require(Tezos.get_sender() = param.owner, Errors.FA2.not_owner); require(param.token_id < s.storage.pools_count, Errors.Dex.pool_not_listed); const owner_key = (param.owner, param.token_id); diff --git a/contracts/partials/fa2/lambdas.ligo b/contracts/partials/fa2/lambdas.ligo index 76cc042..43627b1 100644 --- a/contracts/partials/fa2/lambdas.ligo +++ b/contracts/partials/fa2/lambdas.ligo @@ -27,7 +27,7 @@ function update_token_metadata( var operations := Constants.no_operations; case p of [ | Update_metadata(params) -> { - require(s.storage.managers contains Tezos.sender, Errors.Dex.not_manager); + require(s.storage.managers contains Tezos.get_sender(), Errors.Dex.not_manager); s.storage.token_metadata[params.token_id] := params } | _ -> unreachable(Unit) diff --git a/contracts/partials/factory/helpers.ligo b/contracts/partials/factory/helpers.ligo index a7e53ed..36d3bed 100644 --- a/contracts/partials/factory/helpers.ligo +++ b/contracts/partials/factory/helpers.ligo @@ -51,7 +51,7 @@ var s : full_storage_t) : option(bytes) is block { - require(Tezos.sender = s.storage.dev_store.dev_address, Errors.Dex.not_developer); + require(Tezos.get_sender() = s.storage.dev_store.dev_address, Errors.Dex.not_developer); case s.init_func of [ | Some(_) -> failwith(Errors.Dex.func_set) | None -> skip @@ -84,18 +84,18 @@ function manage_startup_charges( var quipu_rewards : nat) : record [ ops: list(operation); rewards: nat ] is block { - if not (wl contains Tezos.sender) + if not (wl contains Tezos.get_sender()) then { const to_burn = price * burn_rate_f / Constants.burn_rate_precision; const to_factory = abs(price - to_burn); operations := typed_transfer( - Tezos.sender, - Tezos.self_address, + Tezos.get_sender(), + Tezos.get_self_address(), to_factory, Fa2(quipu_token) ) # operations; operations := typed_transfer( - Tezos.sender, + Tezos.get_sender(), Constants.burn_address, to_burn, Fa2(quipu_token) @@ -123,11 +123,11 @@ function form_pool_storage( : pool_f_storage_t is block { const default_token_id = 0n; - const pool = record [ + const pool: pool_t = (record [ initial_A_f = a_constant * Constants.a_precision; future_A_f = a_constant * Constants.a_precision; - initial_A_time = Tezos.now; - future_A_time = Tezos.now; + initial_A_time = Tezos.get_now(); + future_A_time = Tezos.get_now(); tokens_info = tokens_info; fee = fees; strategy = record[ @@ -140,10 +140,10 @@ function form_pool_storage( total_staked = 0n; ]; total_supply = 0n; - ]; + ]: pool_t); - const pool_storage: storage_t = record[ - admin = Tezos.sender; + const pool_storage: storage_t = (record[ + admin = Tezos.get_sender(); default_referral = default_referral; managers = managers; pools_count = 1n; @@ -162,10 +162,10 @@ function form_pool_storage( referral_rewards = (big_map[]: big_map((address * token_t), nat)); stakers_balance = (big_map[]: big_map((address * pool_id_t), staker_info_t)); quipu_token = quipu_token; - factory_address = Tezos.self_address; + factory_address = Tezos.get_self_address(); started = False; - ]; - } with record [ + ]: storage_t); + } with (record [ storage = pool_storage; metadata = big_map[ "" -> 0x74657a6f732d73746f726167653a646578; @@ -175,4 +175,4 @@ function form_pool_storage( dex_lambdas = (big_map[]: big_map(nat, bytes)); // too large for injection in one operation token_lambdas = t_lambdas; strat_lambdas = s_lambdas; - ] \ No newline at end of file + ]: pool_f_storage_t) \ No newline at end of file diff --git a/contracts/partials/factory/lambdas.ligo b/contracts/partials/factory/lambdas.ligo index bbfe5db..6dcd769 100644 --- a/contracts/partials/factory/lambdas.ligo +++ b/contracts/partials/factory/lambdas.ligo @@ -22,7 +22,7 @@ function add_pool( const result: tmp_tokens_map_t = Set.fold(get_tokens_from_param, params.input_tokens, default_tmp_tokens); const tokens : tokens_map_t = result.tokens; - const pool_key : bytes = pack_pool_key(Tezos.sender, tokens); + const pool_key : bytes = pack_pool_key(Tezos.get_sender(), tokens); check_pool(pool_key, s.storage.pool_to_address); function set_reserves( diff --git a/contracts/partials/factory/methods.ligo b/contracts/partials/factory/methods.ligo index bfcfc77..9549f4a 100644 --- a/contracts/partials/factory/methods.ligo +++ b/contracts/partials/factory/methods.ligo @@ -20,17 +20,17 @@ function start_dex_func( ) ); const pool_address = unwrap( - s.storage.pool_to_address[pack_pool_key(Tezos.sender, tokens)], + s.storage.pool_to_address[pack_pool_key(Tezos.get_sender(), tokens)], Errors.Factory.pool_not_listed ); - const param = record [ + const param: invest_param_t = (record [ pool_id = 0n; shares = 1n; in_amounts = amounts; - deadline = Tezos.now + 300; - receiver = Some(Tezos.sender); + deadline = Tezos.get_now() + 300; + receiver = Some(Tezos.get_sender()); referral = (None: option(address)); - ]; + ]: invest_param_t); var operations: list(operation) := list[ set_lambd_dex(s.dex_lambdas, pool_address); unfreeze_dex(pool_address); @@ -41,11 +41,11 @@ function start_dex_func( const input : nat * nat) : list(operation) is block { - const token = unwrap(tokens[input.0], Errors.Dex.wrong_index); + const token: token_t = unwrap(tokens[input.0], Errors.Dex.wrong_index); case token of [ | Fa2(_) -> operations := concat_lists(operations, list[ typed_approve( - Tezos.self_address, + Tezos.get_self_address(), pool_address, 0n, token @@ -56,14 +56,14 @@ function start_dex_func( if input.1 > 0n then { operations := typed_approve( - Tezos.self_address, + Tezos.get_self_address(), pool_address, input.1, token ) # operations; operations := typed_transfer( - Tezos.sender, - Tezos.self_address, + Tezos.get_sender(), + Tezos.get_self_address(), input.1, token ) # operations; @@ -79,7 +79,7 @@ function claim_quipu( block { const operations = list[ typed_transfer( - Tezos.self_address, + Tezos.get_self_address(), s.storage.dev_store.dev_address, s.storage.quipu_rewards, Fa2(s.storage.quipu_token) @@ -93,7 +93,7 @@ function use_factory( var s : full_storage_t) : fact_return_t is block { - require(Tezos.sender = s.storage.dev_store.dev_address, Errors.Dex.not_developer); + require(Tezos.get_sender() = s.storage.dev_store.dev_address, Errors.Dex.not_developer); case params of [ | Set_burn_rate(rate) -> if rate <= Constants.burn_rate_precision then s.storage.burn_rate_f := rate diff --git a/contracts/partials/factory/views.ligo b/contracts/partials/factory/views.ligo index 05bd7a6..bcec021 100644 --- a/contracts/partials/factory/views.ligo +++ b/contracts/partials/factory/views.ligo @@ -19,7 +19,7 @@ [@view] function get_pool( - const params : record [ tokens:set(token_t); deployer:address ]; + const params : record[ tokens: set(token_t); deployer:address ]; const s : full_storage_t) : option(address) is block { diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index de34f57..bb40476 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -53,7 +53,7 @@ function check_strategy_pool_params( const strategy: address): bool is block { const expected: strat_pool_data_t = record[ - pool_contract = Tezos.self_address; + pool_contract = Tezos.get_self_address(); pool_id = pool_id ]; const response: strat_pool_data_t = unwrap( @@ -100,7 +100,7 @@ function operate_with_strategy( // send additional reserves to Yupana through Strategy if value > 0n then send_ops := typed_transfer( - Tezos.self_address, + Tezos.get_self_address(), contract, value, get_token_by_id(token_id, tokens_map_entry) diff --git a/contracts/partials/strategy/methods.ligo b/contracts/partials/strategy/methods.ligo index 2622f7a..366944e 100644 --- a/contracts/partials/strategy/methods.ligo +++ b/contracts/partials/strategy/methods.ligo @@ -5,7 +5,7 @@ : full_return_t is block { const dev_address = get_dev_address(s.storage); - require(Tezos.sender = dev_address, Errors.Dex.not_developer); + require(Tezos.get_sender() = dev_address, Errors.Dex.not_developer); const idx : nat = case p of [ | Connect_strategy(_) -> 0n | Connect_token_strategy(_) -> 1n diff --git a/contracts/partials/utils.ligo b/contracts/partials/utils.ligo index 5cc6add..cfb36cb 100644 --- a/contracts/partials/utils.ligo +++ b/contracts/partials/utils.ligo @@ -170,7 +170,7 @@ [@inline] function check_deadline( const exp : timestamp) : unit is - require(exp >= Tezos.now, Errors.Dex.time_expired); + require(exp >= Tezos.get_now(), Errors.Dex.time_expired); function set_func_or_fail( const params : set_lambda_func_t; @@ -221,10 +221,10 @@ function get_token_by_id( #if FACTORY #if !INSIDE_DEX - require(Tezos.sender = s.storage.dev_store.dev_address, Errors.Dex.not_developer); + require(Tezos.get_sender() = s.storage.dev_store.dev_address, Errors.Dex.not_developer); #endif #else - require(Tezos.sender = s.storage.admin, Errors.Dex.not_contract_admin); + require(Tezos.get_sender() = s.storage.admin, Errors.Dex.not_contract_admin); #endif case f_type of [ | FAdmin -> s.admin_lambdas := set_func_or_fail(params, Constants.admin_func_count, s.admin_lambdas) diff --git a/package.json b/package.json index 1521d09..c027393 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "bugs": "https://github.com/madfish-solutions/quipuswap-stable-core/issues", "description": "Token2Token DEX for equal-price tokens based on StableSwap algos on top of Tezos. This package installs dependencies for testing and deployment purposes", "author": "Illia Likhoshva (https://www.madfish.solutions/)", + "license": "MIT", "private": true, "dependencies": { "@taquito/signer": "^14.0.0", diff --git a/scripts/commands/compile/utils.ts b/scripts/commands/compile/utils.ts index 5eaa27b..60f2625 100644 --- a/scripts/commands/compile/utils.ts +++ b/scripts/commands/compile/utils.ts @@ -96,11 +96,12 @@ const _compileFile = async ( "-e", "main", "--protocol", - "ithaca" + "lima" ); if (format === "json") args.push("--michelson-format", "json"); console.debug(`\t🔥 Compiling with LIGO (${ligoVersion})...`); + console.debug(args.reduce((p, c) => p + " " + c, "")); const ligo = spawn(ligo_executable, args, {}); ligo.on("close", async () => { @@ -231,7 +232,7 @@ export const compileLambdas = async ( lambda.index }n; func=Bytes.pack(${lambda.name})])`; } - const params = `'${func}' --michelson-format json --init-file ${init_file} --protocol ithaca`; + const params = `'${func}' --michelson-format json --init-file ${init_file} --protocol lima`; const command = `${ligo} ${ligo_command} ${config.preferredLigoFlavor} ${params}`; const michelson = execSync(command, { maxBuffer: 1024 * 500 }).toString(); @@ -297,7 +298,7 @@ export const compileFactoryLambda = ( const init_file = `$PWD/${config.contractsDirectory}/factory.ligo`; try { const func = `Bytes.pack(${lambda})`; - const params = `'${func}' --michelson-format json --init-file ${init_file} --protocol ithaca`; + const params = `'${func}' --michelson-format json --init-file ${init_file} --protocol lima`; const command = `${ligo} ${ligo_command} ${config.preferredLigoFlavor} ${params}`; const michelson = execSync(command, { maxBuffer: 1024 * 1000 }).toString(); console.log(lambda + " successfully compiled."); From 57dbf1744908bc0c9ec3a110693875519769b35c Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 1 Dec 2022 16:56:20 +0200 Subject: [PATCH 48/67] fix division --- test/Dex/cases/strategy/auto_rebalance.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Dex/cases/strategy/auto_rebalance.ts b/test/Dex/cases/strategy/auto_rebalance.ts index 3d7ce20..57c3156 100644 --- a/test/Dex/cases/strategy/auto_rebalance.ts +++ b/test/Dex/cases/strategy/auto_rebalance.ts @@ -121,7 +121,7 @@ export async function investRebalanceSuccessCase( const reserves = pool.tokens_info.get(k).reserves; const amount_to_slash = reserves .multipliedBy(v.des_reserves_rate_f.plus(v.delta_rate_f)) - .div("1e18") + .idiv("1e18") .plus(1_500_000); in_amounts = in_amounts.set(k, amount_to_slash); console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) @@ -162,7 +162,7 @@ export async function divestRebalanceSuccessCase( const reserves = pool.tokens_info.get(k).reserves; const amount_to_slash = reserves .multipliedBy(v.des_reserves_rate_f.minus(v.delta_rate_f)) - .div("1e18") + .idiv("1e18") .minus(1_500_000); min_amounts = min_amounts.set(k, amount_to_slash); console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) @@ -197,7 +197,7 @@ export async function divestOneRebalanceSuccessCase( const reserves = pool.tokens_info.get(k).reserves; const amount_to_slash = reserves .multipliedBy(v.des_reserves_rate_f.minus(v.delta_rate_f)) - .div("1e18") + .idiv("1e18") .minus(1_500_000); min_amounts = min_amounts.set(k, amount_to_slash); console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) @@ -237,7 +237,7 @@ export async function divestImbalanceRebalanceSuccessCase( const reserves = pool.tokens_info.get(k).reserves; const amount_to_slash = reserves .multipliedBy(v.des_reserves_rate_f.minus(v.delta_rate_f)) - .div("1e18") + .idiv("1e18") .minus(1_500_000); min_amounts = min_amounts.set(k, amount_to_slash); console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) From e69644c695c7fff47e063d1fb0fa7a31c731f3ea Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Thu, 1 Dec 2022 17:12:46 +0200 Subject: [PATCH 49/67] fix delta in excpection --- test/Dex/cases/strategy/auto_rebalance.ts | 31 +++++++++++++---------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/test/Dex/cases/strategy/auto_rebalance.ts b/test/Dex/cases/strategy/auto_rebalance.ts index 57c3156..9cee46e 100644 --- a/test/Dex/cases/strategy/auto_rebalance.ts +++ b/test/Dex/cases/strategy/auto_rebalance.ts @@ -48,8 +48,14 @@ async function autoRebalanceCheck( const on_strat = value.strategy_reserves; const full_res = pool.tokens_info.get(key).reserves; const expected_rate = value.des_reserves_rate_f.div("1e18"); + const delta = value.delta_rate_f.div("1e18"); const real_rate = on_strat.div(full_res); - expect(real_rate.toNumber()).toBeCloseTo(expected_rate.toNumber(), 9); + expect(real_rate.toNumber()).toBeLessThanOrEqual( + expected_rate.plus(delta).toNumber() + ); + expect(real_rate.toNumber()).toBeGreaterThanOrEqual( + expected_rate.minus(delta).toNumber() + ); console.debug( `[STRATEGY] Auto Rebalance [${key.toString()}] - full: ${full_res}, on strategy: ${on_strat} (${on_strat .div(full_res) @@ -81,9 +87,9 @@ export async function swapRebalanceSuccessCase( .multipliedBy(conf_i.des_reserves_rate_f.plus(conf_i.delta_rate_f)) .idiv("1e18") .plus(1_500_000); - console.debug( - `[STRATEGY] Auto Rebalance Swap [${route.i.toNumber()} - ${route.j.toNumber()}] - amt: ${amount_to_swap_to_slash.toNumber()}` - ); + console.debug( + `[STRATEGY] Auto Rebalance Swap [${route.i.toNumber()} - ${route.j.toNumber()}] - amt: ${amount_to_swap_to_slash.toNumber()}` + ); const operation = await dex.swap( pool_id, route.i, @@ -115,7 +121,7 @@ export async function investRebalanceSuccessCase( ); let in_amounts = new Map(); - console.debug(`[STRATEGY] Auto Rebalance invest`) + console.debug(`[STRATEGY] Auto Rebalance invest`); strategyStore.configuration.forEach((v, k) => { const reserves = pool.tokens_info.get(k).reserves; @@ -124,7 +130,7 @@ export async function investRebalanceSuccessCase( .idiv("1e18") .plus(1_500_000); in_amounts = in_amounts.set(k, amount_to_slash); - console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) + console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`); }); const operation = await dex.investLiquidity( @@ -156,7 +162,7 @@ export async function divestRebalanceSuccessCase( ); let min_amounts = new Map(); - console.debug(`[STRATEGY] Auto Rebalance divest`) + console.debug(`[STRATEGY] Auto Rebalance divest`); strategyStore.configuration.forEach((v, k) => { const reserves = pool.tokens_info.get(k).reserves; @@ -165,8 +171,7 @@ export async function divestRebalanceSuccessCase( .idiv("1e18") .minus(1_500_000); min_amounts = min_amounts.set(k, amount_to_slash); - console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) - + console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`); }); const operation = await dex.divestLiquidity( @@ -191,7 +196,7 @@ export async function divestOneRebalanceSuccessCase( const strategyStore = pool.strategy; expect(strategyStore.strat_contract).toBeDefined(); await dex.rebalance(pool_id, new Set([i])); - console.debug(`[STRATEGY] Auto Rebalance divest one`) + console.debug(`[STRATEGY] Auto Rebalance divest one`); let min_amounts = new Map(); strategyStore.configuration.forEach((v, k) => { const reserves = pool.tokens_info.get(k).reserves; @@ -200,7 +205,7 @@ export async function divestOneRebalanceSuccessCase( .idiv("1e18") .minus(1_500_000); min_amounts = min_amounts.set(k, amount_to_slash); - console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) + console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`); }); const operation = await dex.divestOneCoin( @@ -231,7 +236,7 @@ export async function divestImbalanceRebalanceSuccessCase( pool_id, new Set(dex.storage.storage.tokens[pool_id.toString()].keys()) ); - console.debug(`[STRATEGY] Auto Rebalance divest imb`) + console.debug(`[STRATEGY] Auto Rebalance divest imb`); let min_amounts = new Map(); strategyStore.configuration.forEach((v, k) => { const reserves = pool.tokens_info.get(k).reserves; @@ -240,7 +245,7 @@ export async function divestImbalanceRebalanceSuccessCase( .idiv("1e18") .minus(1_500_000); min_amounts = min_amounts.set(k, amount_to_slash); - console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`) + console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`); }); const operation = await dex.divestImbalanced( From 3053087d44f7f7b07fef908e81fb1515e7a8bb65 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 2 Dec 2022 09:57:52 +0200 Subject: [PATCH 50/67] Update logic for divesting tests --- test/00_Dex.test.ts | 31 ++++++++++++ test/Dex/cases/strategy/auto_rebalance.ts | 59 +++++++++-------------- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/test/00_Dex.test.ts b/test/00_Dex.test.ts index 8e86b8a..597da72 100644 --- a/test/00_Dex.test.ts +++ b/test/00_Dex.test.ts @@ -962,6 +962,7 @@ describe("00. Standalone Dex", () => { let strategy: Contract; let yup_ordering: IndexMap; let pool_ordering: IndexMap; + beforeAll(async () => { pool_id = dex.storage.storage.pools_count.minus(new BigNumber(1)); @@ -989,7 +990,37 @@ describe("00. Standalone Dex", () => { }); describe("as a developer", () => { + let min_amounts: Map; + let imb_amounts: Map; + const normalized: BigNumber = new BigNumber(10).pow(3); // 3K + const min_out_amount: BigNumber = decimals.kUSD + .multipliedBy(normalized) + .multipliedBy(3) + .minus( + decimals.kUSD + .multipliedBy(normalized) + .multipliedBy(3) + .multipliedBy(3) + .dividedBy(100) + ); // 3K kUSD tokens - 3% (slippage) + const outputs: AmountsMap = { + kUSD: decimals.kUSD.multipliedBy(normalized), + uUSD: decimals.uUSD.multipliedBy(normalized), + USDtz: decimals.USDtz.multipliedBy(normalized), + }; + const amount_in = new BigNumber(10) + .pow(18) + .multipliedBy(normalized) + .multipliedBy(3); // 3K LP tokens + let idx_map: IndexMap; + beforeAll(async () => { + ({ pool_id, min_amounts, idx_map } = + await TPool.PoolDivest.setupMinTokenMapping(dex, tokens, outputs)); + imb_amounts = new Map(); + imb_amounts.set(idx_map.USDtz, new BigNumber(0)); + imb_amounts.set(idx_map.kUSD, outputs.kUSD); + imb_amounts.set(idx_map.uUSD, outputs.uUSD); const config = await prepareProviderOptions("bob"); Tezos.setProvider(config); }); diff --git a/test/Dex/cases/strategy/auto_rebalance.ts b/test/Dex/cases/strategy/auto_rebalance.ts index 9cee46e..59ae248 100644 --- a/test/Dex/cases/strategy/auto_rebalance.ts +++ b/test/Dex/cases/strategy/auto_rebalance.ts @@ -6,6 +6,7 @@ import { } from "@taquito/rpc"; import Dex from "../../API"; import { PairInfo } from "../../API/types"; +import { setupTokenAmounts } from "../../../utils/tokensSetups"; async function autoRebalanceCheck( dex: Dex, @@ -146,7 +147,9 @@ export async function divestRebalanceSuccessCase( dex: Dex, yupana: Contract, strategy: Contract, - pool_id: BigNumber + pool_id: BigNumber, + min_amounts: Map, + shares: BigNumber ) { await dex.updateStorage({ pools: [pool_id.toString()], @@ -161,23 +164,16 @@ export async function divestRebalanceSuccessCase( new Set(dex.storage.storage.tokens[pool_id.toString()].keys()) ); - let min_amounts = new Map(); console.debug(`[STRATEGY] Auto Rebalance divest`); - strategyStore.configuration.forEach((v, k) => { - const reserves = pool.tokens_info.get(k).reserves; - const amount_to_slash = reserves - .multipliedBy(v.des_reserves_rate_f.minus(v.delta_rate_f)) - .idiv("1e18") - .minus(1_500_000); - min_amounts = min_amounts.set(k, amount_to_slash); - console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`); + min_amounts.forEach((v, k) => { + console.debug(`[${k.toString()}] ${v.toString()}`); }); const operation = await dex.divestLiquidity( pool_id, min_amounts, - new BigNumber(1_000_000_000), + shares, new Date(Date.now() + 1000 * 60 * 60 * 24) ); await autoRebalanceCheck(dex, yupana, strategy, pool_id, operation); @@ -188,7 +184,9 @@ export async function divestOneRebalanceSuccessCase( yupana: Contract, strategy: Contract, pool_id: BigNumber, - i: BigNumber + i: BigNumber, + output: BigNumber, + shares: BigNumber ) { await dex.updateStorage({ pools: [pool_id.toString()] }); const pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; @@ -197,22 +195,15 @@ export async function divestOneRebalanceSuccessCase( expect(strategyStore.strat_contract).toBeDefined(); await dex.rebalance(pool_id, new Set([i])); console.debug(`[STRATEGY] Auto Rebalance divest one`); - let min_amounts = new Map(); - strategyStore.configuration.forEach((v, k) => { - const reserves = pool.tokens_info.get(k).reserves; - const amount_to_slash = reserves - .multipliedBy(v.des_reserves_rate_f.minus(v.delta_rate_f)) - .idiv("1e18") - .minus(1_500_000); - min_amounts = min_amounts.set(k, amount_to_slash); - console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`); - }); + console.debug( + `[${i.toString()}] burn ${shares.toString()} LPs to min ${output.toString()}}` + ); const operation = await dex.divestOneCoin( pool_id, - new BigNumber(100_000_000), + shares, i, - new BigNumber(1), + output, new Date(Date.now() + 1000 * 60 * 60 * 24) ); await autoRebalanceCheck(dex, yupana, strategy, pool_id, operation); @@ -222,7 +213,9 @@ export async function divestImbalanceRebalanceSuccessCase( dex: Dex, yupana: Contract, strategy: Contract, - pool_id: BigNumber + pool_id: BigNumber, + outputs: Map, + shares: BigNumber ) { await dex.updateStorage({ pools: [pool_id.toString()], @@ -237,21 +230,13 @@ export async function divestImbalanceRebalanceSuccessCase( new Set(dex.storage.storage.tokens[pool_id.toString()].keys()) ); console.debug(`[STRATEGY] Auto Rebalance divest imb`); - let min_amounts = new Map(); - strategyStore.configuration.forEach((v, k) => { - const reserves = pool.tokens_info.get(k).reserves; - const amount_to_slash = reserves - .multipliedBy(v.des_reserves_rate_f.minus(v.delta_rate_f)) - .idiv("1e18") - .minus(1_500_000); - min_amounts = min_amounts.set(k, amount_to_slash); - console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`); + outputs.forEach((v, k) => { + console.debug(`[${k.toString()}] ${v.toString()}`); }); - const operation = await dex.divestImbalanced( pool_id, - new Map().set("0", 1_000_000).set("1", 1_000_000).set("2", 1_000_000), - new BigNumber(100_000_000), + outputs, + shares, new Date(Date.now() + 1000 * 60 * 60 * 24) ); await autoRebalanceCheck(dex, yupana, strategy, pool_id, operation); From e3c5bdbe4ed09696968df8a9eb334f95bb432c13 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 2 Dec 2022 10:17:45 +0200 Subject: [PATCH 51/67] update tests methods --- test/00_Dex.test.ts | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/test/00_Dex.test.ts b/test/00_Dex.test.ts index 597da72..24a99db 100644 --- a/test/00_Dex.test.ts +++ b/test/00_Dex.test.ts @@ -962,7 +962,6 @@ describe("00. Standalone Dex", () => { let strategy: Contract; let yup_ordering: IndexMap; let pool_ordering: IndexMap; - beforeAll(async () => { pool_id = dex.storage.storage.pools_count.minus(new BigNumber(1)); @@ -1017,12 +1016,22 @@ describe("00. Standalone Dex", () => { beforeAll(async () => { ({ pool_id, min_amounts, idx_map } = await TPool.PoolDivest.setupMinTokenMapping(dex, tokens, outputs)); - imb_amounts = new Map(); - imb_amounts.set(idx_map.USDtz, new BigNumber(0)); - imb_amounts.set(idx_map.kUSD, outputs.kUSD); - imb_amounts.set(idx_map.uUSD, outputs.uUSD); + imb_amounts = new Map() + .set(idx_map.USDtz, outputs.USDtz) + .set(idx_map.kUSD, new BigNumber(0)) + .set(idx_map.uUSD, outputs.uUSD); + const invest_amt = new Map() + .set(idx_map.USDtz, outputs.USDtz.multipliedBy("1e6")) + .set(idx_map.kUSD, outputs.kUSD.multipliedBy("1e6")) + .set(idx_map.uUSD, outputs.uUSD.multipliedBy("1e6")); const config = await prepareProviderOptions("bob"); Tezos.setProvider(config); + await dex.investLiquidity( + pool_id, + invest_amt, + new BigNumber(1), + new Date(Date.now() + 1000 * 60 * 60 * 24) + ); }); const test_factory = "tz1ZZZZZZZZZZZZZZZZZZZZZZZZZZZZNkiRg"; @@ -1130,8 +1139,8 @@ describe("00. Standalone Dex", () => { j: new BigNumber(pool_ordering.uUSD), } )); - - it("should auto-rebalance when invest", async () => + + it("should auto-rebalance when invest", async () => TStrategy.autoRebalance.investRebalanceSuccessCase( dex, yupana, @@ -1144,7 +1153,9 @@ describe("00. Standalone Dex", () => { dex, yupana, strategy, - pool_id + pool_id, + imb_amounts, + amount_in )); it("should auto-rebalance when divest one", async () => @@ -1153,7 +1164,9 @@ describe("00. Standalone Dex", () => { yupana, strategy, pool_id, - new BigNumber(pool_ordering.kUSD) + new BigNumber(pool_ordering.kUSD), + outputs.kUSD, + amount_in.idiv(3) )); it("should set is rebalance flag for token", async () => @@ -1162,14 +1175,16 @@ describe("00. Standalone Dex", () => { pool_id, new BigNumber(pool_ordering.kUSD), false - )) + )); it("should auto-rebalance when divest", async () => TStrategy.autoRebalance.divestRebalanceSuccessCase( dex, yupana, strategy, - pool_id + pool_id, + min_amounts, + amount_in )); it("should configure strategy for token to zero", async () => From f2a17ec602d6096f2790d585b6dbd1ecb14dc685 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 2 Dec 2022 19:25:49 +0200 Subject: [PATCH 52/67] Rebalance tests --- contracts/partials/dex_core/lambdas.ligo | 2 +- test/00_Dex.test.ts | 56 +++++++++++++++-------- test/Dex/cases/strategy/auto_rebalance.ts | 29 ++++++------ test/Token/storage/USDtz_storage.ts | 8 ++-- test/Token/storage/kUSD_storage.ts | 6 +-- test/Token/storage/uUSD_storage.ts | 6 +-- 6 files changed, 64 insertions(+), 43 deletions(-) diff --git a/contracts/partials/dex_core/lambdas.ligo b/contracts/partials/dex_core/lambdas.ligo index f5a9dbe..c269a9c 100644 --- a/contracts/partials/dex_core/lambdas.ligo +++ b/contracts/partials/dex_core/lambdas.ligo @@ -374,7 +374,7 @@ function divest_one_coin( s.pools[params.pool_id] := pool; const account_bal = unwrap_or(s.ledger[sender_key], 0n); - s.ledger[sender_key] := unwrap(is_nat(account_bal - params.shares), Errors.FA2.insufficient_balance); + s.ledger[sender_key] := unwrap(is_nat(account_bal - params.shares), Errors.Dex.insufficient_lp); s.dev_rewards[token] := unwrap_or(s.dev_rewards[token], 0n) + dev_fee; const referral: address = unwrap_or(params.referral, s.default_referral); diff --git a/test/00_Dex.test.ts b/test/00_Dex.test.ts index 24a99db..2983348 100644 --- a/test/00_Dex.test.ts +++ b/test/00_Dex.test.ts @@ -990,18 +990,20 @@ describe("00. Standalone Dex", () => { describe("as a developer", () => { let min_amounts: Map; + let invest_amounts: Map; let imb_amounts: Map; const normalized: BigNumber = new BigNumber(10).pow(3); // 3K const min_out_amount: BigNumber = decimals.kUSD .multipliedBy(normalized) + .multipliedBy("1e6") .multipliedBy(3) .minus( decimals.kUSD .multipliedBy(normalized) - .multipliedBy(3) + .multipliedBy("1e6") .multipliedBy(3) .dividedBy(100) - ); // 3K kUSD tokens - 3% (slippage) + ); const outputs: AmountsMap = { kUSD: decimals.kUSD.multipliedBy(normalized), uUSD: decimals.uUSD.multipliedBy(normalized), @@ -1010,25 +1012,30 @@ describe("00. Standalone Dex", () => { const amount_in = new BigNumber(10) .pow(18) .multipliedBy(normalized) - .multipliedBy(3); // 3K LP tokens + .multipliedBy(2) + .multipliedBy("1e6"); let idx_map: IndexMap; beforeAll(async () => { ({ pool_id, min_amounts, idx_map } = await TPool.PoolDivest.setupMinTokenMapping(dex, tokens, outputs)); imb_amounts = new Map() - .set(idx_map.USDtz, outputs.USDtz) + .set(idx_map.USDtz, outputs.USDtz.multipliedBy("1e5").multipliedBy(5)) .set(idx_map.kUSD, new BigNumber(0)) - .set(idx_map.uUSD, outputs.uUSD); - const invest_amt = new Map() + .set(idx_map.uUSD, outputs.uUSD.multipliedBy("1e5").multipliedBy(5)); + invest_amounts = new Map() .set(idx_map.USDtz, outputs.USDtz.multipliedBy("1e6")) .set(idx_map.kUSD, outputs.kUSD.multipliedBy("1e6")) .set(idx_map.uUSD, outputs.uUSD.multipliedBy("1e6")); + min_amounts = new Map() + .set(idx_map.USDtz, new BigNumber(1)) + .set(idx_map.kUSD, new BigNumber(1)) + .set(idx_map.uUSD, new BigNumber(1)); const config = await prepareProviderOptions("bob"); Tezos.setProvider(config); await dex.investLiquidity( pool_id, - invest_amt, + invest_amounts, new BigNumber(1), new Date(Date.now() + 1000 * 60 * 60 * 24) ); @@ -1062,8 +1069,8 @@ describe("00. Standalone Dex", () => { pool_id, new BigNumber(pool_ordering.kUSD), new BigNumber("0.3").multipliedBy("1e18"), - new BigNumber("0.05").multipliedBy("1e18"), - new BigNumber("300").multipliedBy("1e6") + new BigNumber("0.005").multipliedBy("1e18"), + new BigNumber("300").multipliedBy(decimals.kUSD) ) .then(() => TStrategy.token.configureTokenStrategy.setStrategyParamsSuccessCase( @@ -1071,8 +1078,8 @@ describe("00. Standalone Dex", () => { pool_id, new BigNumber(pool_ordering.uUSD), new BigNumber("0.15").multipliedBy("1e18"), - new BigNumber("0.03").multipliedBy("1e18"), - new BigNumber("1500").multipliedBy("1e6") + new BigNumber("0.003").multipliedBy("1e18"), + new BigNumber("1500").multipliedBy(decimals.uUSD) ) )); @@ -1145,7 +1152,8 @@ describe("00. Standalone Dex", () => { dex, yupana, strategy, - pool_id + pool_id, + invest_amounts )); it("should auto-rebalance when divest imbalance", async () => @@ -1165,8 +1173,8 @@ describe("00. Standalone Dex", () => { strategy, pool_id, new BigNumber(pool_ordering.kUSD), - outputs.kUSD, - amount_in.idiv(3) + outputs.kUSD.multipliedBy("1e5").multipliedBy(5), + min_out_amount )); it("should set is rebalance flag for token", async () => @@ -1177,15 +1185,27 @@ describe("00. Standalone Dex", () => { false )); - it("should auto-rebalance when divest", async () => - TStrategy.autoRebalance.divestRebalanceSuccessCase( + it("should auto-rebalance when divest", async () => { + const sender = await Tezos.signer.publicKeyHash(); + const request: { owner: TezosAddress; token_id: number } = { + owner: sender, + token_id: pool_id.toNumber(), + }; + const lp_balance_response: { + request: typeof request; + balance: BigNumber; + }[] = await dex.contract.contractViews + .get_balance([request]) + .executeView({ viewCaller: sender }); + await TStrategy.autoRebalance.divestRebalanceSuccessCase( dex, yupana, strategy, pool_id, min_amounts, - amount_in - )); + new BigNumber(lp_balance_response[0].balance).minus("1000000") + ); + }); it("should configure strategy for token to zero", async () => TStrategy.token.configureTokenStrategy diff --git a/test/Dex/cases/strategy/auto_rebalance.ts b/test/Dex/cases/strategy/auto_rebalance.ts index 59ae248..d7a4251 100644 --- a/test/Dex/cases/strategy/auto_rebalance.ts +++ b/test/Dex/cases/strategy/auto_rebalance.ts @@ -106,7 +106,8 @@ export async function investRebalanceSuccessCase( dex: Dex, yupana: Contract, strategy: Contract, - pool_id: BigNumber + pool_id: BigNumber, + amounts: Map ) { await dex.updateStorage({ pools: [pool_id.toString()], @@ -121,22 +122,15 @@ export async function investRebalanceSuccessCase( new Set(dex.storage.storage.tokens[pool_id.toString()].keys()) ); - let in_amounts = new Map(); console.debug(`[STRATEGY] Auto Rebalance invest`); - strategyStore.configuration.forEach((v, k) => { - const reserves = pool.tokens_info.get(k).reserves; - const amount_to_slash = reserves - .multipliedBy(v.des_reserves_rate_f.plus(v.delta_rate_f)) - .idiv("1e18") - .plus(1_500_000); - in_amounts = in_amounts.set(k, amount_to_slash); - console.debug(`[${k.toString()}] ${amount_to_slash.toString()}`); + amounts.forEach((v, k) => { + console.debug(`[${k.toString()}] ${v.toString()}`); }); const operation = await dex.investLiquidity( pool_id, - in_amounts, + amounts, new BigNumber(1), new Date(Date.now() + 1000 * 60 * 60 * 24) ); @@ -166,8 +160,15 @@ export async function divestRebalanceSuccessCase( console.debug(`[STRATEGY] Auto Rebalance divest`); - min_amounts.forEach((v, k) => { - console.debug(`[${k.toString()}] ${v.toString()}`); + console.debug(`to burn ${shares.div("1e18").toString()} LPs`); + pool.tokens_info.forEach((info, key) => { + const rate = new BigNumber(10).pow(18).dividedBy(info.rate_f); + console.debug( + `Reserves\n\t\t${key}:\t${info.reserves + .dividedBy(rate) + .div(new BigNumber(10).pow(18)) + .toFormat(10)}` + ); }); const operation = await dex.divestLiquidity( @@ -196,7 +197,7 @@ export async function divestOneRebalanceSuccessCase( await dex.rebalance(pool_id, new Set([i])); console.debug(`[STRATEGY] Auto Rebalance divest one`); console.debug( - `[${i.toString()}] burn ${shares.toString()} LPs to min ${output.toString()}}` + `[${i.toString()}] burn ${shares.toString()} LPs to min ${output.toString()}` ); const operation = await dex.divestOneCoin( diff --git a/test/Token/storage/USDtz_storage.ts b/test/Token/storage/USDtz_storage.ts index 895a5d5..81198e5 100644 --- a/test/Token/storage/USDtz_storage.ts +++ b/test/Token/storage/USDtz_storage.ts @@ -8,20 +8,20 @@ const USDtzstorage = { admin: aliceAddress, ledger: MichelsonMap.fromLiteral({ [aliceAddress]: { - balance: "10000000000000", + balance: "10000000000000000", approvals: MichelsonMap.fromLiteral({}), }, [bobAddress]: { - balance: "10000000000000", + balance: "10000000000000000", approvals: MichelsonMap.fromLiteral({}), }, [eveAddress]: { - balance: "10000000000000", + balance: "10000000000000000", approvals: MichelsonMap.fromLiteral({}), }, }), paused: false, - totalSupply: "3000000000000", + totalSupply: "3000000000000000", }; export default USDtzstorage; diff --git a/test/Token/storage/kUSD_storage.ts b/test/Token/storage/kUSD_storage.ts index c4c62e3..8703e54 100644 --- a/test/Token/storage/kUSD_storage.ts +++ b/test/Token/storage/kUSD_storage.ts @@ -8,15 +8,15 @@ const kUSDstorage = { administrator: aliceAddress, balances: MichelsonMap.fromLiteral({ [aliceAddress]: { - balance: "1000000000000000000000000000000", + balance: "1000000000000000000000000000000000", approvals: MichelsonMap.fromLiteral({}), }, [bobAddress]: { - balance: "1000000000000000000000000000000", + balance: "1000000000000000000000000000000000", approvals: MichelsonMap.fromLiteral({}), }, [eveAddress]: { - balance: "1000000000000000000000000000000", + balance: "1000000000000000000000000000000000", approvals: MichelsonMap.fromLiteral({}), }, }), diff --git a/test/Token/storage/uUSD_storage.ts b/test/Token/storage/uUSD_storage.ts index bf4c70e..2cbd15a 100644 --- a/test/Token/storage/uUSD_storage.ts +++ b/test/Token/storage/uUSD_storage.ts @@ -12,7 +12,7 @@ ledger.set( token_id: defaultTokenId, owner: aliceAddress, }, - "1000000000000000000000000" + "1000000000000000000000000000" ); // eslint-disable-next-line jest/require-hook ledger.set( @@ -20,7 +20,7 @@ ledger.set( token_id: defaultTokenId, owner: bobAddress, }, - "1000000000000000000000000" + "1000000000000000000000000000" ); // eslint-disable-next-line jest/require-hook ledger.set( @@ -28,7 +28,7 @@ ledger.set( token_id: defaultTokenId, owner: eveAddress, }, - "1000000000000000000000000" + "1000000000000000000000000000" ); const admins = new MichelsonMap(); // eslint-disable-next-line jest/require-hook From dc6c2c2b113dfa345cac70baad86a02abdb07673 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 2 Dec 2022 21:07:00 +0200 Subject: [PATCH 53/67] [DEBUGGING] comment transfers --- contracts/partials/dex_core/lambdas.ligo | 12 ++++++------ test/Dex/cases/strategy/auto_rebalance.ts | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/contracts/partials/dex_core/lambdas.ligo b/contracts/partials/dex_core/lambdas.ligo index c269a9c..be9d28a 100644 --- a/contracts/partials/dex_core/lambdas.ligo +++ b/contracts/partials/dex_core/lambdas.ligo @@ -139,12 +139,12 @@ function divest_liquidity( const value = token_info.reserves * params.shares / total_supply; require(value >= min_amount_out, Errors.Dex.high_min_out); require(value =/= 0n, Errors.Dex.dust_out); - accum.op := typed_transfer( - Tezos.get_self_address(), - receiver, - value, - entry.1 - ) # accum.op; + // accum.op := typed_transfer( + // Tezos.get_self_address(), + // receiver, + // value, + // entry.1 + // ) # accum.op; token_info.reserves := nat_or_error(token_info.reserves - value, Errors.Dex.low_reserves); accum.tok_inf[entry.0] := token_info; } with accum; diff --git a/test/Dex/cases/strategy/auto_rebalance.ts b/test/Dex/cases/strategy/auto_rebalance.ts index d7a4251..dbcb601 100644 --- a/test/Dex/cases/strategy/auto_rebalance.ts +++ b/test/Dex/cases/strategy/auto_rebalance.ts @@ -20,6 +20,7 @@ async function autoRebalanceCheck( const internals = ( operation.results[0] as OperationContentsAndResultTransaction ).metadata.internal_operation_results; + console.debug(internals); expect( internals.find( (x) => From 73e70bc16c073b7d3c69ede0cf9d223e2fd8b2a9 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 2 Dec 2022 21:08:53 +0200 Subject: [PATCH 54/67] experiment with caching wf --- .github/workflows/main.yml | 79 ++++++++++++++++++++++++++++---------- scenario/requirements.txt | 2 + 2 files changed, 61 insertions(+), 20 deletions(-) create mode 100644 scenario/requirements.txt diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ade838b..12b51cd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,14 +6,21 @@ on: - main - develop pull_request: - + jobs: - jest: - name: Jest tests + compile: + name: Compile contracts for tests runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v3 + - uses: actions/cache@v3 + id: contracts-build + with: + path: | + build + contracts/compiled + key: compiled-contracts-${{ runner.os }}-jest-${{ hashFiles('contracts/**/*.ligo') }} - name: Setup dependencies uses: actions/setup-node@v3 with: @@ -21,7 +28,17 @@ jobs: cache: 'yarn' cache-dependency-path: './yarn.lock' - name: Install modules + if: steps.contracts-build.outputs.cache-hit != 'true' run: yarn install --immutable --immutable-cache --check-cache + - name: Compile contracts and test + if: steps.contracts-build.outputs.cache-hit != 'true' + run: yarn compile + compile-test: + name: Compile contracts for tests + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 - uses: actions/cache@v3 id: contracts-build with: @@ -29,9 +46,40 @@ jobs: build contracts/compiled key: compiled-test-contracts-${{ runner.os }}-jest-${{ hashFiles('contracts/**/*.ligo') }} + - name: Setup dependencies + uses: actions/setup-node@v3 + with: + node-version: "18" + cache: 'yarn' + cache-dependency-path: './yarn.lock' + - name: Install modules + if: steps.contracts-build.outputs.cache-hit != 'true' + run: yarn install --immutable --immutable-cache --check-cache - name: Compile contracts and test if: steps.contracts-build.outputs.cache-hit != 'true' run: yarn compile-for-test + jest: + needs: compile-test + name: Jest tests + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Setup dependencies + uses: actions/setup-node@v3 + with: + node-version: "18" + cache: 'yarn' + cache-dependency-path: './yarn.lock' + - name: Install modules + run: yarn install --immutable --immutable-cache --check-cache + - uses: actions/cache@v3 + id: contracts-build + with: + path: | + build + contracts/compiled + key: compiled-test-contracts-${{ runner.os }}-jest-${{ hashFiles('contracts/**/*.ligo') }} - name: Start sandbox run: yarn start-sandbox - name: Wait for Sandbox endpoint @@ -45,27 +93,14 @@ jobs: - name: Stop sandbox run: yarn stop-sandbox pytest: + needs: compile name: Pytest tests runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Node - uses: actions/setup-node@v3 - with: - node-version: "18" - cache: 'yarn' - cache-dependency-path: './yarn.lock' - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.9' - name: Install crypto libs run: sudo apt install libsodium-dev libsecp256k1-dev libgmp-dev - - name: Install pytezos and pytest - run: pip install pytezos pytest - - name: Install node modules - run: yarn install --immutable --immutable-cache --check-cache - uses: actions/cache@v3 id: contracts-build with: @@ -73,9 +108,13 @@ jobs: build contracts/compiled key: compiled-contracts-${{ runner.os }}-${{ hashFiles('contracts/**/*.ligo') }} - - name: Compile contracts - if: steps.contracts-build.outputs.cache-hit != 'true' - run: yarn compile + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.9' + cache: 'pip' + - name: Install pytezos and pytest + run: pip install -r scenario/requirements.txt - name: Run scenario tests run: pytest -s -v diff --git a/scenario/requirements.txt b/scenario/requirements.txt new file mode 100644 index 0000000..35a49a2 --- /dev/null +++ b/scenario/requirements.txt @@ -0,0 +1,2 @@ +pytezos==3.7.2 +pytest==7.2.0 \ No newline at end of file From 402cc86bdc6d71e8542d946b747ef58f974ea46d Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 2 Dec 2022 21:12:49 +0200 Subject: [PATCH 55/67] Upd naming --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 12b51cd..de4e10f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,7 +9,7 @@ on: jobs: compile: - name: Compile contracts for tests + name: Compile contracts runs-on: ubuntu-latest steps: - name: Checkout repository From 6ecc93b960c1961ba39aee69add3eab85b91a804 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 2 Dec 2022 21:27:09 +0200 Subject: [PATCH 56/67] comment unused var --- contracts/partials/dex_core/lambdas.ligo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/partials/dex_core/lambdas.ligo b/contracts/partials/dex_core/lambdas.ligo index be9d28a..0040694 100644 --- a/contracts/partials/dex_core/lambdas.ligo +++ b/contracts/partials/dex_core/lambdas.ligo @@ -125,7 +125,7 @@ function divest_liquidity( require(params.shares =/= 0n, Errors.Dex.zero_in); var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); - const receiver = unwrap_or(params.receiver, Tezos.get_sender()); + // const receiver = unwrap_or(params.receiver, Tezos.get_sender()); const total_supply : nat = pool.total_supply; function divest_reserves( From 3cff290b80b744068c3af8c8fb09d4b6453df512 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 2 Dec 2022 21:33:52 +0200 Subject: [PATCH 57/67] fix operations --- contracts/partials/dex_core/lambdas.ligo | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/contracts/partials/dex_core/lambdas.ligo b/contracts/partials/dex_core/lambdas.ligo index 0040694..36bb2bb 100644 --- a/contracts/partials/dex_core/lambdas.ligo +++ b/contracts/partials/dex_core/lambdas.ligo @@ -125,7 +125,7 @@ function divest_liquidity( require(params.shares =/= 0n, Errors.Dex.zero_in); var pool : pool_t := unwrap(s.pools[params.pool_id], Errors.Dex.pool_not_listed); - // const receiver = unwrap_or(params.receiver, Tezos.get_sender()); + const receiver = unwrap_or(params.receiver, Tezos.get_sender()); const total_supply : nat = pool.total_supply; function divest_reserves( @@ -139,12 +139,12 @@ function divest_liquidity( const value = token_info.reserves * params.shares / total_supply; require(value >= min_amount_out, Errors.Dex.high_min_out); require(value =/= 0n, Errors.Dex.dust_out); - // accum.op := typed_transfer( - // Tezos.get_self_address(), - // receiver, - // value, - // entry.1 - // ) # accum.op; + accum.op := typed_transfer( + Tezos.get_self_address(), + receiver, + value, + entry.1 + ) # accum.op; token_info.reserves := nat_or_error(token_info.reserves - value, Errors.Dex.low_reserves); accum.tok_inf[entry.0] := token_info; } with accum; @@ -159,7 +159,7 @@ function divest_liquidity( pool.strategy, False ); - operations := concat_lists(rebalance.0, operations); + operations := concat_lists(rebalance.0, res.op); pool.strategy := rebalance.1; pool.total_supply := nat_or_error(pool.total_supply - params.shares, Errors.Dex.low_total_supply); @@ -168,7 +168,6 @@ function divest_liquidity( s.ledger[key] := nat_or_error(share - params.shares, Errors.Dex.insufficient_lp); s.pools[params.pool_id] := pool; - operations := res.op; } | _ -> unreachable(Unit) ] From 2d3de8d4618c55d8d9755c42d1e3bbf0619812e1 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Fri, 2 Dec 2022 21:36:54 +0200 Subject: [PATCH 58/67] fix cache naming --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index de4e10f..75df35f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,7 +20,7 @@ jobs: path: | build contracts/compiled - key: compiled-contracts-${{ runner.os }}-jest-${{ hashFiles('contracts/**/*.ligo') }} + key: compiled-contracts-${{ runner.os }}-${{ hashFiles('contracts/**/*.ligo') }} - name: Setup dependencies uses: actions/setup-node@v3 with: From 1f66f0cd0f800f233e6e7353744572c3936b9f7a Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Sun, 4 Dec 2022 17:49:47 +0200 Subject: [PATCH 59/67] Update tests --- test/00_Dex.test.ts | 2 +- test/Dex/cases/strategy/auto_rebalance.ts | 53 ++++++----------------- 2 files changed, 14 insertions(+), 41 deletions(-) diff --git a/test/00_Dex.test.ts b/test/00_Dex.test.ts index 2983348..8fbf405 100644 --- a/test/00_Dex.test.ts +++ b/test/00_Dex.test.ts @@ -1203,7 +1203,7 @@ describe("00. Standalone Dex", () => { strategy, pool_id, min_amounts, - new BigNumber(lp_balance_response[0].balance).minus("1000000") + lp_balance_response[0].balance ); }); diff --git a/test/Dex/cases/strategy/auto_rebalance.ts b/test/Dex/cases/strategy/auto_rebalance.ts index dbcb601..3fa4bf7 100644 --- a/test/Dex/cases/strategy/auto_rebalance.ts +++ b/test/Dex/cases/strategy/auto_rebalance.ts @@ -1,12 +1,8 @@ import BigNumber from "bignumber.js"; -import { TezosToolkit, Contract, TransactionOperation } from "@taquito/taquito"; -import { - OperationContentsAndResultTransaction, - InternalOperationResult, -} from "@taquito/rpc"; +import { Contract, TransactionOperation } from "@taquito/taquito"; +import { OperationContentsAndResultTransaction } from "@taquito/rpc"; import Dex from "../../API"; import { PairInfo } from "../../API/types"; -import { setupTokenAmounts } from "../../../utils/tokensSetups"; async function autoRebalanceCheck( dex: Dex, @@ -16,11 +12,10 @@ async function autoRebalanceCheck( operation: TransactionOperation ) { await dex.updateStorage({ pools: [pool_id.toString()] }); - const pool = dex.storage.storage.pools[pool_id.toString()]; + const pool: PairInfo = dex.storage.storage.pools[pool_id.toString()]; const internals = ( operation.results[0] as OperationContentsAndResultTransaction ).metadata.internal_operation_results; - console.debug(internals); expect( internals.find( (x) => @@ -52,16 +47,18 @@ async function autoRebalanceCheck( const expected_rate = value.des_reserves_rate_f.div("1e18"); const delta = value.delta_rate_f.div("1e18"); const real_rate = on_strat.div(full_res); - expect(real_rate.toNumber()).toBeLessThanOrEqual( - expected_rate.plus(delta).toNumber() - ); - expect(real_rate.toNumber()).toBeGreaterThanOrEqual( - expected_rate.minus(delta).toNumber() - ); + if (value.is_rebalance) { + expect(real_rate.toNumber()).toBeLessThanOrEqual( + expected_rate.plus(delta).toNumber() + ); + expect(real_rate.toNumber()).toBeGreaterThanOrEqual( + expected_rate.minus(delta).toNumber() + ); + } console.debug( `[STRATEGY] Auto Rebalance [${key.toString()}] - full: ${full_res}, on strategy: ${on_strat} (${on_strat .div(full_res) - .multipliedBy(100)}%)` + .multipliedBy(100)}%). Auto rebalance enabled: ${value.is_rebalance}` ); }); } @@ -89,9 +86,7 @@ export async function swapRebalanceSuccessCase( .multipliedBy(conf_i.des_reserves_rate_f.plus(conf_i.delta_rate_f)) .idiv("1e18") .plus(1_500_000); - console.debug( - `[STRATEGY] Auto Rebalance Swap [${route.i.toNumber()} - ${route.j.toNumber()}] - amt: ${amount_to_swap_to_slash.toNumber()}` - ); + console.debug(`[STRATEGY] Auto Rebalance Swap`); const operation = await dex.swap( pool_id, route.i, @@ -125,10 +120,6 @@ export async function investRebalanceSuccessCase( console.debug(`[STRATEGY] Auto Rebalance invest`); - amounts.forEach((v, k) => { - console.debug(`[${k.toString()}] ${v.toString()}`); - }); - const operation = await dex.investLiquidity( pool_id, amounts, @@ -161,17 +152,6 @@ export async function divestRebalanceSuccessCase( console.debug(`[STRATEGY] Auto Rebalance divest`); - console.debug(`to burn ${shares.div("1e18").toString()} LPs`); - pool.tokens_info.forEach((info, key) => { - const rate = new BigNumber(10).pow(18).dividedBy(info.rate_f); - console.debug( - `Reserves\n\t\t${key}:\t${info.reserves - .dividedBy(rate) - .div(new BigNumber(10).pow(18)) - .toFormat(10)}` - ); - }); - const operation = await dex.divestLiquidity( pool_id, min_amounts, @@ -197,10 +177,6 @@ export async function divestOneRebalanceSuccessCase( expect(strategyStore.strat_contract).toBeDefined(); await dex.rebalance(pool_id, new Set([i])); console.debug(`[STRATEGY] Auto Rebalance divest one`); - console.debug( - `[${i.toString()}] burn ${shares.toString()} LPs to min ${output.toString()}` - ); - const operation = await dex.divestOneCoin( pool_id, shares, @@ -232,9 +208,6 @@ export async function divestImbalanceRebalanceSuccessCase( new Set(dex.storage.storage.tokens[pool_id.toString()].keys()) ); console.debug(`[STRATEGY] Auto Rebalance divest imb`); - outputs.forEach((v, k) => { - console.debug(`[${k.toString()}] ${v.toString()}`); - }); const operation = await dex.divestImbalanced( pool_id, outputs, From 942ab45ae21e66ec6a2efe4c46d8eb9620391973 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 5 Dec 2022 12:24:12 +0200 Subject: [PATCH 60/67] [CQS-99] Add events --- contracts/main/dex.ligo | 1 + contracts/partials/dex_core/events.ligo | 81 ++++++++++++++++++++++++ contracts/partials/dex_core/lambdas.ligo | 55 ++++++++++++++-- contracts/partials/dex_core/math.ligo | 14 +++- contracts/partials/fa2/helpers.ligo | 36 +++++++---- contracts/partials/fa2/lambdas.ligo | 2 +- contracts/partials/strategy/helpers.ligo | 9 ++- contracts/partials/strategy/lambdas.ligo | 1 + 8 files changed, 176 insertions(+), 23 deletions(-) create mode 100644 contracts/partials/dex_core/events.ligo diff --git a/contracts/main/dex.ligo b/contracts/main/dex.ligo index 10ebeaa..05f8753 100644 --- a/contracts/main/dex.ligo +++ b/contracts/main/dex.ligo @@ -17,6 +17,7 @@ #include "../partials/dex_core/storage.ligo" #include "../partials/admin/types.ligo" #include "../partials/dex_core/types.ligo" +#include "../partials/dex_core/events.ligo" (* Helpers and functions *) #include "../partials/utils.ligo" #if FACTORY diff --git a/contracts/partials/dex_core/events.ligo b/contracts/partials/dex_core/events.ligo new file mode 100644 index 0000000..07d89bb --- /dev/null +++ b/contracts/partials/dex_core/events.ligo @@ -0,0 +1,81 @@ +type swap_event_t is [@layout:comb] record [ + pool_id : pool_id_t; + i : token_pool_idx_t; + j : token_pool_idx_t; + amount_in : nat; + amount_out : nat; + receiver : address; + referral : address; +] + +type invest_event_t is [@layout:comb] record [ + pool_id : pool_id_t; + inputs : map(token_pool_idx_t, nat); + shares_minted : nat; + receiver : address; + referral : address; +] + +type divest_event_t is [@layout:comb] record [ + pool_id : pool_id_t; + shares_burned : nat; + outputs : map(token_pool_idx_t, nat); + receiver : address; +] + +type divest_one_event_t is [@layout:comb] record [ + pool_id : pool_id_t; + i : token_pool_idx_t; + shares_burned : nat; + amount_out : nat; + receiver : address; + referral : address; +] + +type divest_imb_event_t is [@layout:comb] record [ + pool_id : pool_id_t; + shares_burned : nat; + outputs : map(token_pool_idx_t, nat); + receiver : address; + referral : address; +] + +type txs_event_t is [@layout:comb] record [ + token_id : pool_id_t; + amount : nat; + receiver : address; +] + +type transfer_event_t is [@layout:comb] record [ + owner : address; + caller : address; + txs : list(txs_event_t) +] + +type rebalance_event_t is [@layout:comb] record [ + pool_id : pool_id_t; + rebalanced_tokens : list(token_pool_idx_t); + token_infos : map(token_pool_idx_t, strategy_storage_t) +] + +type event_t is +| TransferEvent of transfer_event_t +| InvestEvent of invest_event_t +| SwapEvent of swap_event_t +| DivestEvent of divest_event_t +| DivestOneEvent of divest_one_event_t +| DivestImbalanceEvent of divest_imb_event_t +| RebalanceEvent of rebalance_event_t + +[@inline] function emit_event( + const p : event_t) + : operation is + case p of [ + TransferEvent(params) -> Tezos.emit("%transfer", params) + | InvestEvent(params) -> Tezos.emit("%invest", params) + | SwapEvent(params) -> Tezos.emit("%swap", params) + | DivestEvent(params) -> Tezos.emit("%divest", params) + | DivestOneEvent(params) -> Tezos.emit("%divest_one", params) + | DivestImbalanceEvent(params) -> Tezos.emit("%divest_imbalance", params) + | RebalanceEvent(params) -> Tezos.emit("%rebalance", params) + ]; \ No newline at end of file diff --git a/contracts/partials/dex_core/lambdas.ligo b/contracts/partials/dex_core/lambdas.ligo index 36bb2bb..51b1ef3 100644 --- a/contracts/partials/dex_core/lambdas.ligo +++ b/contracts/partials/dex_core/lambdas.ligo @@ -59,6 +59,7 @@ function swap( token_j ) # operations; const rebalance = operate_with_strategy( + params.pool_id, map[ i -> token_info_i; j -> token_info_j @@ -76,6 +77,16 @@ function swap( ) # operations; pool.strategy := rebalance.1; s.pools[params.pool_id] := pool; + const event_params: swap_event_t = record[ + pool_id = params.pool_id; + i = i; + j = j; + amount_in = dx; + amount_out = after_fees.dy; + receiver = receiver; + referral = referral; + ]; + operations := emit_event(SwapEvent(event_params)) # operations; } | _ -> unreachable(Unit) ] @@ -129,9 +140,9 @@ function divest_liquidity( const total_supply : nat = pool.total_supply; function divest_reserves( - var accum : record [ tok_inf: map(token_pool_idx_t, token_info_t); op: list(operation) ]; + var accum : record [ tok_inf: map(token_pool_idx_t, token_info_t); op: list(operation); outs: map(token_pool_idx_t, nat); ]; const entry : (token_pool_idx_t * token_t)) - : record [ tok_inf: map(token_pool_idx_t, token_info_t); op: list(operation) ] is + : record [ tok_inf: map(token_pool_idx_t, token_info_t); op: list(operation); outs: map(token_pool_idx_t, nat) ] is block { var token_info := unwrap(accum.tok_inf[entry.0], Errors.Dex.no_token_info); const min_amount_out = unwrap_or(params.min_amounts_out[entry.0], 1n); @@ -145,21 +156,25 @@ function divest_liquidity( value, entry.1 ) # accum.op; + accum.outs[entry.0] := value; token_info.reserves := nat_or_error(token_info.reserves - value, Errors.Dex.low_reserves); accum.tok_inf[entry.0] := token_info; } with accum; const tokens : tokens_map_t = unwrap(s.tokens[params.pool_id], Errors.Dex.pool_not_listed); - const res = Map.fold(divest_reserves, tokens, record [ tok_inf = pool.tokens_info; op = operations ]); - + const res = Map.fold(divest_reserves, tokens, record [ tok_inf = pool.tokens_info; op = operations; outs = (map[]: map(token_pool_idx_t, nat)) ]); pool.tokens_info := res.tok_inf; const rebalance = operate_with_strategy( + params.pool_id, pool.tokens_info, s.tokens[params.pool_id], pool.strategy, False ); - operations := concat_lists(rebalance.0, res.op); + operations := concat_lists( + rebalance.0, + res.op + ); pool.strategy := rebalance.1; pool.total_supply := nat_or_error(pool.total_supply - params.shares, Errors.Dex.low_total_supply); @@ -168,6 +183,13 @@ function divest_liquidity( s.ledger[key] := nat_or_error(share - params.shares, Errors.Dex.insufficient_lp); s.pools[params.pool_id] := pool; + const event_params: divest_event_t = record[ + pool_id = params.pool_id; + shares_burned = params.shares; + outputs = res.outs; + receiver = receiver; + ]; + operations := emit_event(DivestEvent(event_params)) # operations; } | _ -> unreachable(Unit) ] @@ -188,6 +210,7 @@ function divest_imbalanced( require(params.max_shares > 0n, Errors.Dex.zero_in); const receiver = unwrap_or(params.receiver, Tezos.get_sender()); + const referral = unwrap_or(params.referral, s.default_referral); const key = (Tezos.get_sender(), params.pool_id); const share = unwrap_or(s.ledger[key], 0n); @@ -252,7 +275,7 @@ function divest_imbalanced( tokens, pool.fee, get_dev_fee(s), - unwrap_or(params.referral, s.default_referral), + referral, record[ dev_rewards = s.dev_rewards; referral_rewards = s.referral_rewards; @@ -283,6 +306,7 @@ function divest_imbalanced( ]; check_shares_and_reserves(pool); const rebalance = operate_with_strategy( + params.pool_id, balanced.tokens_info, s.tokens[params.pool_id], pool.strategy, @@ -292,6 +316,14 @@ function divest_imbalanced( pool.strategy := rebalance.1; s.pools[params.pool_id] := pool; s.ledger[(Tezos.get_sender(), params.pool_id)] := new_shares; + const event_params: divest_imb_event_t = record[ + pool_id = params.pool_id; + shares_burned = burn_amount; + outputs = params.amounts_out; + receiver = receiver; + referral = referral; + ]; + operations := emit_event(DivestImbalanceEvent(event_params)) # operations; } | _ -> unreachable(Unit) ]; @@ -356,6 +388,7 @@ function divest_one_coin( check_shares_and_reserves(pool); const receiver = unwrap_or(params.receiver, Tezos.get_sender()); + operations := typed_transfer( Tezos.get_self_address(), receiver, @@ -363,6 +396,7 @@ function divest_one_coin( token ) # operations; const rebalance = operate_with_strategy( + params.pool_id, map[ params.token_index -> info ], s.tokens[params.pool_id], pool.strategy, @@ -379,6 +413,15 @@ function divest_one_coin( const referral: address = unwrap_or(params.referral, s.default_referral); s.referral_rewards[(referral, token)] := unwrap_or(s.referral_rewards[(referral, token)], 0n) + ref_fee; + const event_params: divest_one_event_t = record[ + pool_id = params.pool_id; + i = params.token_index; + shares_burned = params.shares; + amount_out = result.dy; + receiver = receiver; + referral = referral; + ]; + operations := emit_event(DivestOneEvent(event_params)) # operations; } | _ -> unreachable(Unit) ]; diff --git a/contracts/partials/dex_core/math.ligo b/contracts/partials/dex_core/math.ligo index 2f29b89..8ec46a9 100644 --- a/contracts/partials/dex_core/math.ligo +++ b/contracts/partials/dex_core/math.ligo @@ -342,7 +342,7 @@ function add_liq( const init_tokens_info = pool.tokens_info; const d0 = get_D_mem(init_tokens_info, amp_f); const token_supply = pool.total_supply; - + const referral = unwrap_or(params.referral, s.default_referral); function add_inputs( const key : token_pool_idx_t; var token_info : token_info_t) @@ -370,7 +370,7 @@ function add_liq( unwrap(s.tokens[params.pool_id], Errors.Dex.pool_not_listed), pool.fee, get_dev_fee(s), - unwrap_or(params.referral, s.default_referral), + referral, record [ dev_rewards = s.dev_rewards; referral_rewards = s.referral_rewards; @@ -413,6 +413,7 @@ function add_liq( pool.total_supply := pool.total_supply + mint_amount; const (rebalance_ops, strategy_store) = operate_with_strategy( + params.pool_id, pool.tokens_info, tokens[params.pool_id], pool.strategy, @@ -426,4 +427,11 @@ function add_liq( const share = unwrap_or(s.ledger[user_key], 0n); const new_shares = share + mint_amount; s.ledger[user_key] := new_shares; - } with record[ op = Map.fold(transfer_to_pool, params.inputs, rebalance_ops); s = s ] + const event_params: invest_event_t = record[ + pool_id = params.pool_id; + inputs = params.inputs; + shares_minted = mint_amount; + receiver = receiver; + referral = referral; + ]; + } with record[ op = emit_event(InvestEvent(event_params)) # Map.fold(transfer_to_pool, params.inputs, rebalance_ops); s = s ] diff --git a/contracts/partials/fa2/helpers.ligo b/contracts/partials/fa2/helpers.ligo index 25359ce..151cd8b 100644 --- a/contracts/partials/fa2/helpers.ligo +++ b/contracts/partials/fa2/helpers.ligo @@ -13,29 +13,41 @@ (* Perform transfers from one owner *) [@inline] function iterate_transfer( - var s : full_storage_t; + var accum : list(operation) * full_storage_t; const user_trx_params : transfer_fa2_param_t) - : full_storage_t is + : list(operation) * full_storage_t is block { function make_transfer( - var s : full_storage_t; + var acc : list(txs_event_t) * full_storage_t; const transfer : transfer_fa2_dst_t) - : full_storage_t is + : list(txs_event_t) * full_storage_t is block { - require(transfer.token_id < s.storage.pools_count, Errors.FA2.undefined); + require(transfer.token_id < acc.1.storage.pools_count, Errors.FA2.undefined); const sender_key = (user_trx_params.from_, transfer.token_id); - var sender_balance := unwrap_or(s.storage.ledger[sender_key], 0n); - var sender_allowance := get_allowances(sender_key, s.storage.allowances); + var sender_balance := unwrap_or(acc.1.storage.ledger[sender_key], 0n); + var sender_allowance := get_allowances(sender_key, acc.1.storage.allowances); check_permissions(user_trx_params.from_, sender_allowance); sender_balance := nat_or_error(sender_balance - transfer.amount, Errors.FA2.insufficient_balance); - s.storage.ledger[sender_key] := sender_balance; + acc.1.storage.ledger[sender_key] := sender_balance; const dest_key = (transfer.to_, transfer.token_id); - var dest_account := unwrap_or(s.storage.ledger[dest_key], 0n); + var dest_account := unwrap_or(acc.1.storage.ledger[dest_key], 0n); dest_account := dest_account + transfer.amount; - s.storage.ledger[dest_key] := dest_account; - } with s; -} with List.fold(make_transfer, user_trx_params.txs, s) + acc.1.storage.ledger[dest_key] := dest_account; + acc.0 := (record[ + token_id = transfer.token_id; + amount = transfer.amount; + receiver = transfer.to_; + ]: txs_event_t) # acc.0; + } with acc; + const result = List.fold(make_transfer, user_trx_params.txs, ((list[]:list(txs_event_t)), accum.1)); + accum.1 := result.1; + accum.0 := emit_event(TransferEvent(record[ + owner = user_trx_params.from_; + caller = Tezos.get_sender(); + txs = result.0; + ])) # accum.0; +} with accum (* Perform single operator update *) [@inline] function iterate_update_operator( diff --git a/contracts/partials/fa2/lambdas.ligo b/contracts/partials/fa2/lambdas.ligo index 43627b1..a03d863 100644 --- a/contracts/partials/fa2/lambdas.ligo +++ b/contracts/partials/fa2/lambdas.ligo @@ -4,7 +4,7 @@ function transfer_ep( var s : full_storage_t) : full_return_t is case p of [ - | Transfer(params) -> (Constants.no_operations, List.fold(iterate_transfer, params, s)) + | Transfer(params) -> List.fold(iterate_transfer, params, (Constants.no_operations, s)) | _ -> unreachable(Unit) ] diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index bb40476..192b314 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -65,6 +65,7 @@ function check_strategy_pool_params( function operate_with_strategy( + const pool_id : pool_id_t; const token_infos : map(token_pool_idx_t, token_info_t); const tokens_map_entry: option(tokens_map_t); var strategy : strategy_full_storage_t; @@ -118,15 +119,21 @@ function operate_with_strategy( }; if List.size(rebalance_params) > 0n then { + const event_params: rebalance_event_t = record[ + pool_id = pool_id; + rebalanced_tokens = prepare_params; + token_infos = strategy.configuration + ]; ops := list [ Tezos.transaction(prepare_params, 0mutez, get_prepare_entrypoint(contract)); - Tezos.transaction(rebalance_params, 0mutez, get_update_state_entrypoint(contract)) + Tezos.transaction(rebalance_params, 0mutez, get_update_state_entrypoint(contract)); ]; if List.size(send_ops) > 0n then ops := concat_lists( send_ops, ops ); + ops := emit_event(RebalanceEvent(event_params)) # ops; } } | None -> skip diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo index 42bde0f..697d8fe 100644 --- a/contracts/partials/strategy/lambdas.ligo +++ b/contracts/partials/strategy/lambdas.ligo @@ -133,6 +133,7 @@ function set_rebalance( Map.add(i, get_token_info(i, pool.tokens_info), acc); const infos = Set.fold(map_ids, params.pool_token_ids, (map[]: map(token_pool_idx_t, token_info_t))); const (rebalance_ops, strategy_store) = operate_with_strategy( + params.pool_id, infos, s.tokens[params.pool_id], pool.strategy, From 26360008a2f42d4e30f9240bf09ebad1b6c7c9b8 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 5 Dec 2022 13:23:45 +0200 Subject: [PATCH 61/67] Optimize batches --- test/Dex/API/dexAPI.ts | 6 +++--- test/Factory/API/factoryAPI.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/Dex/API/dexAPI.ts b/test/Dex/API/dexAPI.ts index b6953f2..53634b1 100644 --- a/test/Dex/API/dexAPI.ts +++ b/test/Dex/API/dexAPI.ts @@ -60,21 +60,21 @@ export class Dex tezos, dexAddress, "Token", - 5, + 3, token_lambdas_comp ); await setFunctionBatchCompilled( tezos, dexAddress, "Dex", - 5, + 3, dex_lambdas_comp ); await setFunctionBatchCompilled( tezos, dexAddress, "Strategy", - 5, + 3, strat_lambdas_comp ); } diff --git a/test/Factory/API/factoryAPI.ts b/test/Factory/API/factoryAPI.ts index 46dd7c7..216fc8e 100644 --- a/test/Factory/API/factoryAPI.ts +++ b/test/Factory/API/factoryAPI.ts @@ -62,21 +62,21 @@ export class DexFactory implements DevEnabledContract, StrategyFactorySetter { tezos, factoryAddress, "Token", - 5, + 3, token_lambdas_comp ); await setFunctionBatchCompilled( tezos, factoryAddress, "Dex", - 5, + 3, dex_lambdas_comp ); await setFunctionBatchCompilled( tezos, factoryAddress, "Strategy", - 5, + 3, strat_lambdas_comp ); await factory.updateStorage(); From ce359bc69524965a29b41fad8baf0144e960898d Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 5 Dec 2022 14:22:36 +0200 Subject: [PATCH 62/67] fix internal ops check after events --- test/Dex/cases/strategy/auto_rebalance.ts | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/test/Dex/cases/strategy/auto_rebalance.ts b/test/Dex/cases/strategy/auto_rebalance.ts index 3fa4bf7..02d6872 100644 --- a/test/Dex/cases/strategy/auto_rebalance.ts +++ b/test/Dex/cases/strategy/auto_rebalance.ts @@ -1,6 +1,9 @@ import BigNumber from "bignumber.js"; -import { Contract, TransactionOperation } from "@taquito/taquito"; -import { OperationContentsAndResultTransaction } from "@taquito/rpc"; +import { Contract, OpKind, TransactionOperation } from "@taquito/taquito"; +import { + OperationContentsAndResultTransaction, + InternalOperationResult, +} from "@taquito/rpc"; import Dex from "../../API"; import { PairInfo } from "../../API/types"; @@ -16,10 +19,12 @@ async function autoRebalanceCheck( const internals = ( operation.results[0] as OperationContentsAndResultTransaction ).metadata.internal_operation_results; + console.debug(internals); expect( internals.find( - (x) => - x.parameters.entrypoint === "prepare" && + (x: InternalOperationResult) => + x.kind === OpKind.TRANSACTION && + x.parameters?.entrypoint === "prepare" && x.destination == strategy.address && x.source === dex.contract.address ) @@ -27,7 +32,8 @@ async function autoRebalanceCheck( expect( internals.find( (x) => - x.parameters.entrypoint === "update_token_state" && + x.kind === OpKind.TRANSACTION && + x.parameters?.entrypoint === "update_token_state" && x.destination == strategy.address && x.source === dex.contract.address ) @@ -35,8 +41,9 @@ async function autoRebalanceCheck( internals .filter( (x) => - (x.parameters.entrypoint === "redeem" || - x.parameters.entrypoint === "mint") && + x.kind === OpKind.TRANSACTION && + (x.parameters?.entrypoint === "redeem" || + x.parameters?.entrypoint === "mint") && x.destination === yupana.address && x.source === strategy.address ) From a552cbc44c9c40ade678a857c4de16cdaf4b4d8a Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 5 Dec 2022 14:34:41 +0200 Subject: [PATCH 63/67] Op checks fix --- test/Dex/cases/strategy/cofigure-token/rebalance.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/Dex/cases/strategy/cofigure-token/rebalance.ts b/test/Dex/cases/strategy/cofigure-token/rebalance.ts index 7ddacbf..ba163f4 100644 --- a/test/Dex/cases/strategy/cofigure-token/rebalance.ts +++ b/test/Dex/cases/strategy/cofigure-token/rebalance.ts @@ -1,5 +1,5 @@ import BigNumber from "bignumber.js"; -import { TezosToolkit, Contract } from "@taquito/taquito"; +import { TezosToolkit, Contract, OpKind } from "@taquito/taquito"; import { OperationContentsAndResultTransaction, InternalOperationResult, @@ -29,7 +29,8 @@ export async function manualRebalanceSuccessCase( expect( internals.find( (x) => - x.parameters.entrypoint === "prepare" && + x.kind === OpKind.TRANSACTION && + x.parameters?.entrypoint === "prepare" && x.destination == strategy.address && x.source === dex.contract.address ) @@ -37,7 +38,8 @@ export async function manualRebalanceSuccessCase( expect( internals.find( (x) => - x.parameters.entrypoint === "update_token_state" && + x.kind === OpKind.TRANSACTION && + x.parameters?.entrypoint === "update_token_state" && x.destination == strategy.address && x.source === dex.contract.address ) @@ -45,8 +47,9 @@ export async function manualRebalanceSuccessCase( internals .filter( (x) => - (x.parameters.entrypoint === "redeem" || - x.parameters.entrypoint === "mint") && + x.kind === OpKind.TRANSACTION && + (x.parameters?.entrypoint === "redeem" || + x.parameters?.entrypoint === "mint") && x.destination === yupana.address && x.source === strategy.address ) From 0c646f9e5d07b5fa7e2d4ab858b8181d3afa18f0 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Mon, 5 Dec 2022 15:43:53 +0200 Subject: [PATCH 64/67] move rebalance event to strategy --- contracts/partials/dex_core/events.ligo | 8 -------- contracts/partials/strategy/helpers.ligo | 6 ------ 2 files changed, 14 deletions(-) diff --git a/contracts/partials/dex_core/events.ligo b/contracts/partials/dex_core/events.ligo index 07d89bb..94b02f4 100644 --- a/contracts/partials/dex_core/events.ligo +++ b/contracts/partials/dex_core/events.ligo @@ -52,12 +52,6 @@ type transfer_event_t is [@layout:comb] record [ txs : list(txs_event_t) ] -type rebalance_event_t is [@layout:comb] record [ - pool_id : pool_id_t; - rebalanced_tokens : list(token_pool_idx_t); - token_infos : map(token_pool_idx_t, strategy_storage_t) -] - type event_t is | TransferEvent of transfer_event_t | InvestEvent of invest_event_t @@ -65,7 +59,6 @@ type event_t is | DivestEvent of divest_event_t | DivestOneEvent of divest_one_event_t | DivestImbalanceEvent of divest_imb_event_t -| RebalanceEvent of rebalance_event_t [@inline] function emit_event( const p : event_t) @@ -77,5 +70,4 @@ type event_t is | DivestEvent(params) -> Tezos.emit("%divest", params) | DivestOneEvent(params) -> Tezos.emit("%divest_one", params) | DivestImbalanceEvent(params) -> Tezos.emit("%divest_imbalance", params) - | RebalanceEvent(params) -> Tezos.emit("%rebalance", params) ]; \ No newline at end of file diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index 192b314..c587b90 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -119,11 +119,6 @@ function operate_with_strategy( }; if List.size(rebalance_params) > 0n then { - const event_params: rebalance_event_t = record[ - pool_id = pool_id; - rebalanced_tokens = prepare_params; - token_infos = strategy.configuration - ]; ops := list [ Tezos.transaction(prepare_params, 0mutez, get_prepare_entrypoint(contract)); Tezos.transaction(rebalance_params, 0mutez, get_update_state_entrypoint(contract)); @@ -133,7 +128,6 @@ function operate_with_strategy( send_ops, ops ); - ops := emit_event(RebalanceEvent(event_params)) # ops; } } | None -> skip From 4cf48de3bfda609f1e31f2b57d88f72f0c948baf Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Tue, 6 Dec 2022 16:17:32 +0200 Subject: [PATCH 65/67] remove unused pool_id param --- contracts/partials/dex_core/lambdas.ligo | 4 ---- contracts/partials/dex_core/math.ligo | 1 - contracts/partials/strategy/helpers.ligo | 1 - contracts/partials/strategy/lambdas.ligo | 1 - 4 files changed, 7 deletions(-) diff --git a/contracts/partials/dex_core/lambdas.ligo b/contracts/partials/dex_core/lambdas.ligo index 51b1ef3..538e716 100644 --- a/contracts/partials/dex_core/lambdas.ligo +++ b/contracts/partials/dex_core/lambdas.ligo @@ -59,7 +59,6 @@ function swap( token_j ) # operations; const rebalance = operate_with_strategy( - params.pool_id, map[ i -> token_info_i; j -> token_info_j @@ -165,7 +164,6 @@ function divest_liquidity( const res = Map.fold(divest_reserves, tokens, record [ tok_inf = pool.tokens_info; op = operations; outs = (map[]: map(token_pool_idx_t, nat)) ]); pool.tokens_info := res.tok_inf; const rebalance = operate_with_strategy( - params.pool_id, pool.tokens_info, s.tokens[params.pool_id], pool.strategy, @@ -306,7 +304,6 @@ function divest_imbalanced( ]; check_shares_and_reserves(pool); const rebalance = operate_with_strategy( - params.pool_id, balanced.tokens_info, s.tokens[params.pool_id], pool.strategy, @@ -396,7 +393,6 @@ function divest_one_coin( token ) # operations; const rebalance = operate_with_strategy( - params.pool_id, map[ params.token_index -> info ], s.tokens[params.pool_id], pool.strategy, diff --git a/contracts/partials/dex_core/math.ligo b/contracts/partials/dex_core/math.ligo index 8ec46a9..a2c042a 100644 --- a/contracts/partials/dex_core/math.ligo +++ b/contracts/partials/dex_core/math.ligo @@ -413,7 +413,6 @@ function add_liq( pool.total_supply := pool.total_supply + mint_amount; const (rebalance_ops, strategy_store) = operate_with_strategy( - params.pool_id, pool.tokens_info, tokens[params.pool_id], pool.strategy, diff --git a/contracts/partials/strategy/helpers.ligo b/contracts/partials/strategy/helpers.ligo index c587b90..9ef5fc8 100644 --- a/contracts/partials/strategy/helpers.ligo +++ b/contracts/partials/strategy/helpers.ligo @@ -65,7 +65,6 @@ function check_strategy_pool_params( function operate_with_strategy( - const pool_id : pool_id_t; const token_infos : map(token_pool_idx_t, token_info_t); const tokens_map_entry: option(tokens_map_t); var strategy : strategy_full_storage_t; diff --git a/contracts/partials/strategy/lambdas.ligo b/contracts/partials/strategy/lambdas.ligo index 697d8fe..42bde0f 100644 --- a/contracts/partials/strategy/lambdas.ligo +++ b/contracts/partials/strategy/lambdas.ligo @@ -133,7 +133,6 @@ function set_rebalance( Map.add(i, get_token_info(i, pool.tokens_info), acc); const infos = Set.fold(map_ids, params.pool_token_ids, (map[]: map(token_pool_idx_t, token_info_t))); const (rebalance_ops, strategy_store) = operate_with_strategy( - params.pool_id, infos, s.tokens[params.pool_id], pool.strategy, From c59600514d036d884b1e3e03892cc9cf3fee95b5 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Wed, 15 Feb 2023 16:56:38 +0200 Subject: [PATCH 66/67] Compile all lambda types in one script execution --- config.ts | 3 +- .../Admin_lambdas.json | 0 .../Dev_lambdas.json | 0 .../Dex_lambdas.json | 0 .../Strategy_lambdas.json | 0 .../Token_lambdas.json | 0 package.json | 58 +++---- scripts/commands/compile/index.ts | 22 ++- scripts/commands/compile/utils.ts | 150 ++++++++++-------- utils/helpers.ts | 6 +- 10 files changed, 133 insertions(+), 106 deletions(-) rename {test/lambdas => contract_lambdas}/Admin_lambdas.json (100%) rename {test/lambdas => contract_lambdas}/Dev_lambdas.json (100%) rename {test/lambdas => contract_lambdas}/Dex_lambdas.json (100%) rename {test/lambdas => contract_lambdas}/Strategy_lambdas.json (100%) rename {test/lambdas => contract_lambdas}/Token_lambdas.json (100%) diff --git a/config.ts b/config.ts index 9a60759..52b61cd 100644 --- a/config.ts +++ b/config.ts @@ -49,8 +49,9 @@ export const config = { contractsDirectory: "contracts/main", outputDirectory: "build", migrationsDir: "migrations", + lambdasDir: "contract_lambdas", dockerizedLigo: true, - ligoLocalPath: "./ligo", + ligoLocalPath: "ligo", }; export default config; diff --git a/test/lambdas/Admin_lambdas.json b/contract_lambdas/Admin_lambdas.json similarity index 100% rename from test/lambdas/Admin_lambdas.json rename to contract_lambdas/Admin_lambdas.json diff --git a/test/lambdas/Dev_lambdas.json b/contract_lambdas/Dev_lambdas.json similarity index 100% rename from test/lambdas/Dev_lambdas.json rename to contract_lambdas/Dev_lambdas.json diff --git a/test/lambdas/Dex_lambdas.json b/contract_lambdas/Dex_lambdas.json similarity index 100% rename from test/lambdas/Dex_lambdas.json rename to contract_lambdas/Dex_lambdas.json diff --git a/test/lambdas/Strategy_lambdas.json b/contract_lambdas/Strategy_lambdas.json similarity index 100% rename from test/lambdas/Strategy_lambdas.json rename to contract_lambdas/Strategy_lambdas.json diff --git a/test/lambdas/Token_lambdas.json b/contract_lambdas/Token_lambdas.json similarity index 100% rename from test/lambdas/Token_lambdas.json rename to contract_lambdas/Token_lambdas.json diff --git a/package.json b/package.json index c027393..e397cae 100644 --- a/package.json +++ b/package.json @@ -27,57 +27,49 @@ }, "scripts": { "cli": "ts-node ./scripts/cli.ts", - "help": "yarn cli --help", "start-sandbox": "yarn cli sandbox --up", "stop-sandbox": "yarn cli sandbox --down", "compile-contract": "yarn cli compile -F json", - "compile-lambda": "yarn cli compile-lambda", - - "compile-lambda-standalone": "yarn -s compile-lambda -C ./contracts/main/dex.ligo", - "compile-dex-lambda-factory": "yarn -s compile-lambda -C ./contracts/main/dex4factory.ligo", - "compile-lambda-test": "yarn -s compile-lambda -C ./contracts/main/dex_test.ligo", - - "compile-lambda-all": "yarn compile-lambda-admin && yarn compile-lambda-dex && yarn compile-lambda-dev && yarn compile-lambda-token && yarn compile-lambda-strategy", - "compile-lambda-dex": "yarn -s compile-lambda-standalone -T Dex -J ./test/lambdas/Dex_lambdas.json", - "compile-lambda-dev": "yarn -s compile-lambda-standalone -T Dev -J ./test/lambdas/Dev_lambdas.json", - "compile-lambda-token": " yarn -s compile-lambda-standalone -T Token -J ./test/lambdas/Token_lambdas.json", - "compile-lambda-admin": "yarn -s compile-lambda-standalone -T Admin -J ./test/lambdas/Admin_lambdas.json", - "compile-lambda-strategy": " yarn -s compile-lambda-standalone -T Strategy -J ./test/lambdas/Strategy_lambdas.json", - "compile-lambda-all-factory": "yarn compile-lambda-admin-factory && yarn compile-lambda-dex-factory && yarn compile-lambda-token-factory && yarn compile-lambda-strategy-factory", - "compile-lambda-dex-factory": "yarn -s compile-dex-lambda-factory -T Dex -J ./test/lambdas/Dex_lambdas.json", - "compile-lambda-token-factory": "yarn -s compile-dex-lambda-factory -T Token -J ./test/lambdas/Token_lambdas.json", - "compile-lambda-admin-factory": "yarn -s compile-dex-lambda-factory -T Admin -J ./test/lambdas/Admin_lambdas.json", - "compile-lambda-strategy-factory": " yarn -s compile-dex-lambda-factory -T Strategy -J ./test/lambdas/Strategy_lambdas.json", + "compile-lambda-standalone": "yarn -s cli compile-lambda -C ./contracts/main/dex.ligo", + "compile-lambda-dex": "yarn -s compile-lambda-standalone -T Dex -J ./contract_lambdas/Dex_lambdas.json", + "compile-lambda-dev": "yarn -s compile-lambda-standalone -T Dev -J ./contract_lambdas/Dev_lambdas.json", + "compile-lambda-token": " yarn -s compile-lambda-standalone -T Token -J ./contract_lambdas/Token_lambdas.json", + "compile-lambda-admin": "yarn -s compile-lambda-standalone -T Admin -J ./contract_lambdas/Admin_lambdas.json", + "compile-lambda-strategy": " yarn -s compile-lambda-standalone -T Strategy -J ./contract_lambdas/Strategy_lambdas.json", - "compile-lambda-all-test": "yarn compile-lambda-admin-test && yarn compile-lambda-dex-test && yarn compile-lambda-dev-test && yarn compile-lambda-token-test && yarn compile-lambda-strategy-test", - "compile-lambda-dex-test": "yarn -s compile-lambda-test -T Dex -J ./test/lambdas/Dex_lambdas.json", - "compile-lambda-dev-test": "yarn -s compile-lambda-test -T Dev -J ./test/lambdas/Dev_lambdas.json", - "compile-lambda-token-test": "yarn -s compile-lambda-test -T Token -J ./test/lambdas/Token_lambdas.json", - "compile-lambda-admin-test": "yarn -s compile-lambda-test -T Admin -J ./test/lambdas/Admin_lambdas.json", - "compile-lambda-strategy-test": " yarn -s compile-lambda-test -T Strategy -J ./test/lambdas/Strategy_lambdas.json", + "compile-lambda-factory": "yarn -s cli compile-lambda -C ./contracts/main/dex4factory.ligo", + "compile-lambda-dex-factory": "yarn -s compile-lambda-factory -T Dex -J ./contract_lambdas/Dex_lambdas.json", + "compile-lambda-token-factory": "yarn -s compile-lambda-factory -T Token -J ./contract_lambdas/Token_lambdas.json", + "compile-lambda-admin-factory": "yarn -s compile-lambda-factory -T Admin -J ./contract_lambdas/Admin_lambdas.json", + "compile-lambda-strategy-factory": " yarn -s compile-lambda-factory -T Strategy -J ./contract_lambdas/Strategy_lambdas.json", - "precompile-dex": "yarn compile-lambda-all", - "compile-dex": "yarn compile-contract -c dex", + "compile-lambda-test": "yarn -s cli compile-lambda -C ./contracts/main/dex_test.ligo", + "compile-lambda-dex-test": "yarn -s compile-lambda-test -T Dex -J ./contract_lambdas/Dex_lambdas.json", + "compile-lambda-dev-test": "yarn -s compile-lambda-test -T Dev -J ./contract_lambdas/Dev_lambdas.json", + "compile-lambda-token-test": "yarn -s compile-lambda-test -T Token -J ./contract_lambdas/Token_lambdas.json", + "compile-lambda-admin-test": "yarn -s compile-lambda-test -T Admin -J ./contract_lambdas/Admin_lambdas.json", + "compile-lambda-strategy-test": " yarn -s compile-lambda-test -T Strategy -J ./contract_lambdas/Strategy_lambdas.json", - "compile": "yarn compile-dex && yarn compile-factory", - "recompile": "yarn clear-build && yarn compile-contract && yarn compile-lambda-all && yarn compile-factory", + "precompile-dex": "yarn compile-lambda-standalone", + "compile-dex": "yarn compile-contract -c dex", - "precompile-factory": "yarn cli compile -F tz -c dex4factory && yarn compile-lambda-all-factory && yarn cli compile-factory-lambda -F add_pool", + "precompile-factory": "yarn cli compile -F tz -c dex4factory && yarn compile-lambda-factory && yarn cli compile-factory-lambda -F add_pool", "compile-factory": "yarn compile-contract -c factory", - "precompile-for-test": "yarn compile-lambda-all-test", + "compile": "yarn compile-dex && yarn compile-factory", + "recompile": "yarn clear-build && yarn compile", + + "precompile-for-test": "yarn compile-lambda-test", "compile-for-test": "yarn compile-contract -c dex_test && yarn compile-factory", "migrate": "yarn cli migrate", - "test": "jest", - + "precompile-n-test": "yarn compile-for-test && yarn start-sandbox && sleep 10", "compile-n-test": "yarn test", "postcompile-n-test": "yarn stop-sandbox", - "clear-build": "rm -rf ./build", "lint": "eslint --ext .ts .", "fix": "eslint --ext .ts --fix ." diff --git a/scripts/commands/compile/index.ts b/scripts/commands/compile/index.ts index b01615d..ec42d23 100644 --- a/scripts/commands/compile/index.ts +++ b/scripts/commands/compile/index.ts @@ -1,6 +1,7 @@ import { Command } from "commander"; import { compile, compileFactoryLambda, compileLambdas } from "./utils"; import config from "../../../config"; +import { LambdaType } from "../../../utils/helpers"; export const addCompileCommand = (program: Command) => { program @@ -35,15 +36,15 @@ export const addCompileLambdaCommand = (program: Command) => { program .command("compile-lambda") .description("compile lambdas for the specified contract") - .requiredOption("-T, --type ", "Type of contracts lambdas") - .requiredOption( - "-J, --json ", - "input file relative path (with lambdas indexes and names)" - ) .requiredOption( "-C, --contract ", "input file realtive path (with lambdas Ligo code)" ) + .option("-T, --type ", "Type of contracts lambdas") + .option( + "-J, --json ", + "input file relative path (with lambdas indexes and names)" + ) .option("-d, --docker", "Run compiler in Docker", config.dockerizedLigo) .option( "--no-docker", @@ -51,9 +52,14 @@ export const addCompileLambdaCommand = (program: Command) => { !config.dockerizedLigo ) .showHelpAfterError(true) - .action(async (argv) => { - compileLambdas(argv.json, argv.contract, argv.docker, argv.type); - }); + .action( + async (argv: { + type?: LambdaType; + json?: string; + contract: string; + docker: boolean; + }) => compileLambdas(argv.contract, argv.docker, argv.type, argv.json) + ); }; export const addCompileFactoryLambda = (program: Command) => { diff --git a/scripts/commands/compile/utils.ts b/scripts/commands/compile/utils.ts index 60f2625..ebe462c 100644 --- a/scripts/commands/compile/utils.ts +++ b/scripts/commands/compile/utils.ts @@ -1,4 +1,4 @@ -import { getLigo } from "../../../utils/helpers"; +import { getLigo, LambdaType } from "../../../utils/helpers"; import config from "../../../config"; import fs from "fs"; import path from "path"; @@ -186,24 +186,25 @@ export const compile = async (options) => { } }; +function getLambdasFiles() { + return fs + .readdirSync(config.lambdasDir) + .filter((file) => file.endsWith(".json")) + .map((file) => path.join(config.lambdasDir, file)); +} + // Run LIGO compiler export const compileLambdas = async ( - json: string, contract: string, isDockerizedLigo = config.dockerizedLigo, - type: "Dex" | "Token" | "Permit" | "Admin" | "Dev" | "Strategy" + type?: LambdaType, + json?: string ) => { - console.log(`Compiling ${contract} contract lambdas of ${type} type...\n`); - const test_path = contract.toLowerCase().includes("test"); const factory_path = contract.toLowerCase().includes("factory"); const ligo = isDockerizedLigo ? `docker run -v $PWD:$PWD --rm -i -w $PWD ligolang/ligo:${config.ligoVersion}` : config.ligoLocalPath; - const pwd = execSync("echo $PWD").toString(); - const lambdas = JSON.parse( - fs.readFileSync(`${pwd.slice(0, pwd.length - 1)}/${json}`).toString() - ); const res = []; const version = !isDockerizedLigo ? execSync(`${ligo} version -version`).toString() @@ -216,65 +217,90 @@ export const compileLambdas = async ( ligo_command = "compile expression"; } const init_file = `$PWD/${contract}`; - try { - for (const lambda of lambdas) { - let func; - if (factory_path) { - if ( - (lambda.name == "add_pool" || - lambda.name == "set_strategy_factory") && - factory_path - ) - continue; - func = `Bytes.pack(${lambda.name})`; - } else { - func = `Set_${type.toLowerCase()}_function(record [index=${ - lambda.index - }n; func=Bytes.pack(${lambda.name})])`; - } - const params = `'${func}' --michelson-format json --init-file ${init_file} --protocol lima`; - const command = `${ligo} ${ligo_command} ${config.preferredLigoFlavor} ${params}`; - const michelson = execSync(command, { maxBuffer: 1024 * 500 }).toString(); - const bytes = factory_path - ? { - prim: "Pair", - args: [ - { bytes: JSON.parse(michelson).bytes }, - { int: lambda.index.toString() }, - ], - } - : JSON.parse(michelson).args[0].args[0].args[0].args[0]; - res.push(bytes); + const lambdaFiles = json ? [json] : getLambdasFiles(); + const queue: { file: string; func: string; index: number; type: string }[] = + []; + for (const file of lambdaFiles) { + const type = file + .slice(file.lastIndexOf("/") + 1, file.length) + .split("_")[0]; - console.log( - lambda.index + - 1 + - "." + - " ".repeat(4 - (lambda.index + 1).toString().length) + - lambda.name + - " ".repeat(40 - lambda.name.length) + - " successfully compiled." - ); - } - let out_path = "/lambdas"; - if (test_path) { - out_path += "/test"; - } - if (factory_path) { - out_path += "/factory"; - } - if (!fs.existsSync(`${config.outputDirectory + out_path}`)) { - fs.mkdirSync(`${config.outputDirectory + out_path}`, { recursive: true }); + const lambdas = JSON.parse(fs.readFileSync(file).toString()); + for (const lambda of lambdas) { + if ( + factory_path && + (lambda.name == "add_pool" || + lambda.name == "set_strategy_factory" || + type.toLowerCase() == "dev") + ) + continue; + + const func = `Bytes.pack(${lambda.name})`; + queue.push({ file, func, index: lambda.index, type }); } - const json_file_path = json.split("/"); - const file_name = json_file_path[json_file_path.length - 1]; - const save_path = `${config.outputDirectory + out_path}/${file_name}`; - fs.writeFileSync(save_path, JSON.stringify(res)); - console.log(`Saved to ${save_path}`); + } + const funcs = queue.map((q) => q.func).join(";"); + const types: string = [ + ...queue.reduce((set, q) => set.add(q.type), new Set()), + ].join(","); + console.log( + `Compiling ${contract} contract lambdas of ${types} type${types.includes(",") ? "s" : "" + }...\n` + ); + let michelson: string; + try { + const params = `--michelson-format json --init-file ${init_file} --protocol lima`; + + const command = `${ligo} ${ligo_command} ${config.preferredLigoFlavor} 'list [${funcs}]' ${params}`; + michelson = execSync(command, { + maxBuffer: 2048 * 2048, + }).toString(); } catch (e) { console.error(e); + throw e; + } + console.log("Compiled successfully"); + const compiledBytesMap = JSON.parse(michelson).map( + (comp_res: { bytes: string }, idx: number) => { + const file = queue[idx].file.slice( + queue[idx].file.lastIndexOf("/") + 1, + queue[idx].file.length + ); + return { ...queue[idx], file, bytes: comp_res.bytes }; + } + ); + const outputs = new Map(); + for (const entry of compiledBytesMap) { + const bytes = { + prim: "Pair", + args: [{ bytes: entry.bytes }, { int: entry.index.toString() }], + }; + if (outputs.has(entry.file)) + outputs.set(entry.file, [...outputs.get(entry.file), bytes]); + else outputs.set(entry.file, [bytes]); } + outputs.forEach((val, filename) => { + try { + let out_path = "/lambdas"; + if (test_path) { + out_path += "/test"; + } + if (factory_path) { + out_path += "/factory"; + } + if (!fs.existsSync(`${config.outputDirectory + out_path}`)) { + fs.mkdirSync(`${config.outputDirectory + out_path}`, { + recursive: true, + }); + } + const save_path = `${config.outputDirectory + out_path}/${filename}`; + fs.writeFileSync(save_path, JSON.stringify(val)); + console.log(`Saved to ${save_path}`); + } catch (e) { + console.error(e); + } + }); }; export const compileFactoryLambda = ( diff --git a/utils/helpers.ts b/utils/helpers.ts index 6627c3b..d129331 100644 --- a/utils/helpers.ts +++ b/utils/helpers.ts @@ -10,6 +10,8 @@ import BigNumber from "bignumber.js"; import chalk from "chalk"; export const tezPrecision = 1e6; +export declare type LambdaType = "Dex" | "Token" | "Admin" | "Dev" | "Strategy"; + function stringLiteralArray(a: T[]) { return a; } @@ -163,7 +165,7 @@ export async function setupLambdasToStorage( export async function setFunctionBatchCompilled( tezos: TezosToolkit, contract: TezosAddress, - type: "Dex" | "Token" | "Admin" | "Dev" | "Strategy", + type: LambdaType, batchBy: number, comp_funcs_map ) { @@ -197,7 +199,7 @@ export async function setFunctionBatchCompilled( export async function setFunctionCompilled( tezos: TezosToolkit, contract: TezosAddress, - type: "Dex" | "Token" | "Admin" | "Dev" | "Strategy", + type: LambdaType, comp_funcs_map ) { let idx = 0; From 618439679e3cee05c4c0333c1869c8a09f008a24 Mon Sep 17 00:00:00 2001 From: Illia Likhoshva Date: Wed, 15 Feb 2023 17:02:30 +0200 Subject: [PATCH 67/67] remove unused --- package.json | 30 +++++++++++++++--------------- scripts/commands/compile/index.ts | 9 ++------- scripts/commands/compile/utils.ts | 2 -- 3 files changed, 17 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index e397cae..e87854d 100644 --- a/package.json +++ b/package.json @@ -33,24 +33,24 @@ "compile-contract": "yarn cli compile -F json", "compile-lambda-standalone": "yarn -s cli compile-lambda -C ./contracts/main/dex.ligo", - "compile-lambda-dex": "yarn -s compile-lambda-standalone -T Dex -J ./contract_lambdas/Dex_lambdas.json", - "compile-lambda-dev": "yarn -s compile-lambda-standalone -T Dev -J ./contract_lambdas/Dev_lambdas.json", - "compile-lambda-token": " yarn -s compile-lambda-standalone -T Token -J ./contract_lambdas/Token_lambdas.json", - "compile-lambda-admin": "yarn -s compile-lambda-standalone -T Admin -J ./contract_lambdas/Admin_lambdas.json", - "compile-lambda-strategy": " yarn -s compile-lambda-standalone -T Strategy -J ./contract_lambdas/Strategy_lambdas.json", + "compile-lambda-dex": "yarn -s compile-lambda-standalone -J ./contract_lambdas/Dex_lambdas.json", + "compile-lambda-dev": "yarn -s compile-lambda-standalone -J ./contract_lambdas/Dev_lambdas.json", + "compile-lambda-token": " yarn -s compile-lambda-standalone -J ./contract_lambdas/Token_lambdas.json", + "compile-lambda-admin": "yarn -s compile-lambda-standalone -J ./contract_lambdas/Admin_lambdas.json", + "compile-lambda-strategy": " yarn -s compile-lambda-standalone -J ./contract_lambdas/Strategy_lambdas.json", "compile-lambda-factory": "yarn -s cli compile-lambda -C ./contracts/main/dex4factory.ligo", - "compile-lambda-dex-factory": "yarn -s compile-lambda-factory -T Dex -J ./contract_lambdas/Dex_lambdas.json", - "compile-lambda-token-factory": "yarn -s compile-lambda-factory -T Token -J ./contract_lambdas/Token_lambdas.json", - "compile-lambda-admin-factory": "yarn -s compile-lambda-factory -T Admin -J ./contract_lambdas/Admin_lambdas.json", - "compile-lambda-strategy-factory": " yarn -s compile-lambda-factory -T Strategy -J ./contract_lambdas/Strategy_lambdas.json", + "compile-lambda-dex-factory": "yarn -s compile-lambda-factory -J ./contract_lambdas/Dex_lambdas.json", + "compile-lambda-token-factory": "yarn -s compile-lambda-factory -J ./contract_lambdas/Token_lambdas.json", + "compile-lambda-admin-factory": "yarn -s compile-lambda-factory -J ./contract_lambdas/Admin_lambdas.json", + "compile-lambda-strategy-factory": " yarn -s compile-lambda-factory -J ./contract_lambdas/Strategy_lambdas.json", "compile-lambda-test": "yarn -s cli compile-lambda -C ./contracts/main/dex_test.ligo", - "compile-lambda-dex-test": "yarn -s compile-lambda-test -T Dex -J ./contract_lambdas/Dex_lambdas.json", - "compile-lambda-dev-test": "yarn -s compile-lambda-test -T Dev -J ./contract_lambdas/Dev_lambdas.json", - "compile-lambda-token-test": "yarn -s compile-lambda-test -T Token -J ./contract_lambdas/Token_lambdas.json", - "compile-lambda-admin-test": "yarn -s compile-lambda-test -T Admin -J ./contract_lambdas/Admin_lambdas.json", - "compile-lambda-strategy-test": " yarn -s compile-lambda-test -T Strategy -J ./contract_lambdas/Strategy_lambdas.json", + "compile-lambda-dex-test": "yarn -s compile-lambda-test -J ./contract_lambdas/Dex_lambdas.json", + "compile-lambda-dev-test": "yarn -s compile-lambda-test -J ./contract_lambdas/Dev_lambdas.json", + "compile-lambda-token-test": "yarn -s compile-lambda-test -J ./contract_lambdas/Token_lambdas.json", + "compile-lambda-admin-test": "yarn -s compile-lambda-test -J ./contract_lambdas/Admin_lambdas.json", + "compile-lambda-strategy-test": " yarn -s compile-lambda-test -J ./contract_lambdas/Strategy_lambdas.json", "precompile-dex": "yarn compile-lambda-standalone", "compile-dex": "yarn compile-contract -c dex", @@ -66,7 +66,7 @@ "migrate": "yarn cli migrate", "test": "jest", - + "precompile-n-test": "yarn compile-for-test && yarn start-sandbox && sleep 10", "compile-n-test": "yarn test", "postcompile-n-test": "yarn stop-sandbox", diff --git a/scripts/commands/compile/index.ts b/scripts/commands/compile/index.ts index ec42d23..a6d37b6 100644 --- a/scripts/commands/compile/index.ts +++ b/scripts/commands/compile/index.ts @@ -40,7 +40,6 @@ export const addCompileLambdaCommand = (program: Command) => { "-C, --contract ", "input file realtive path (with lambdas Ligo code)" ) - .option("-T, --type ", "Type of contracts lambdas") .option( "-J, --json ", "input file relative path (with lambdas indexes and names)" @@ -53,12 +52,8 @@ export const addCompileLambdaCommand = (program: Command) => { ) .showHelpAfterError(true) .action( - async (argv: { - type?: LambdaType; - json?: string; - contract: string; - docker: boolean; - }) => compileLambdas(argv.contract, argv.docker, argv.type, argv.json) + async (argv: { json?: string; contract: string; docker: boolean }) => + compileLambdas(argv.contract, argv.docker, argv.json) ); }; diff --git a/scripts/commands/compile/utils.ts b/scripts/commands/compile/utils.ts index ebe462c..f3af552 100644 --- a/scripts/commands/compile/utils.ts +++ b/scripts/commands/compile/utils.ts @@ -197,7 +197,6 @@ function getLambdasFiles() { export const compileLambdas = async ( contract: string, isDockerizedLigo = config.dockerizedLigo, - type?: LambdaType, json?: string ) => { const test_path = contract.toLowerCase().includes("test"); @@ -205,7 +204,6 @@ export const compileLambdas = async ( const ligo = isDockerizedLigo ? `docker run -v $PWD:$PWD --rm -i -w $PWD ligolang/ligo:${config.ligoVersion}` : config.ligoLocalPath; - const res = []; const version = !isDockerizedLigo ? execSync(`${ligo} version -version`).toString() : config.ligoVersion;