Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single party pol v2 #146

Merged
merged 23 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8392a5c
init
bekauz Jan 4, 2024
9a6de7b
started migration of V1 to V2
Art3miX Jan 6, 2024
fb7ae90
start interchaintest
bekauz Jan 5, 2024
77a3abf
interchaintest test utils add stride
bekauz Jan 5, 2024
420effb
instantiating liquid staker on ictests
bekauz Jan 6, 2024
8378771
started working on the withdraw functionlity on the LPer
Art3miX Jan 7, 2024
bc72622
Finished with astro lper withdraw change and isngle party holder
Art3miX Jan 8, 2024
c2ef5ab
fmt/clippy
Art3miX Jan 8, 2024
351c8ea
clippy
Art3miX Jan 8, 2024
cf7b77e
init holder on covenant single party
Art3miX Jan 9, 2024
ead3eda
instantiating covenant in ictest; renaming ibc forwarders in top leve…
bekauz Jan 16, 2024
006d7cc
native splitter creates ica
bekauz Jan 17, 2024
0f4977e
splitter actually splits
bekauz Jan 18, 2024
9536181
liquid pooler receives both assets
bekauz Jan 18, 2024
46eb6b0
ictest works for redeeming LP tokens
bekauz Jan 18, 2024
41c1067
moving native splitter & ibc forwarder sudo callback handlers to dedi…
bekauz Jan 18, 2024
75324ad
get_instantiate2_salt_and_address helper; clippy; fmt
bekauz Jan 18, 2024
d0411d5
enable missing migrations in sigle party covenant
bekauz Jan 18, 2024
c6f2a85
rebase fix; clippy; fmt
bekauz Jan 19, 2024
838fd3d
fix osmo genesis helpers
bekauz Jan 19, 2024
1ad473c
removing concentratedliquidity entries from osmo genesis modifications
bekauz Jan 19, 2024
78b225e
enable single party pol in CI
bekauz Jan 19, 2024
f030ee4
osmo genesis modifications
bekauz Jan 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
389 changes: 308 additions & 81 deletions Cargo.lock

Large diffs are not rendered by default.

88 changes: 45 additions & 43 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ members = [
resolver = "2"

[workspace.package]
edition = "2021"
license = "BSD-3"
version = "1.0.0"
edition = "2021"
license = "BSD-3"
version = "1.0.0"
repository = "https://github.com/timewave-computer/covenants"
# rust-version = "1.71.0"

Expand All @@ -24,61 +24,63 @@ panic = 'abort'
rpath = false

[workspace.dependencies]
covenant-clock = { path = "contracts/clock" }
covenant-clock-tester = { path = "contracts/clock-tester" }
covenant-ibc-forwarder = { path = "contracts/ibc-forwarder" }
covenant-native-splitter = { path = "contracts/native-splitter" }
covenant-interchain-splitter = { path = "contracts/interchain-splitter" }
covenant-swap-holder = { path = "contracts/swap-holder" }
swap-covenant = { path = "contracts/swap-covenant" }
covenant-interchain-router = { path = "contracts/interchain-router" }
covenant-two-party-pol-holder = { path = "contracts/two-party-pol-holder" }
covenant-two-party-pol = { path = "contracts/two-party-pol-covenant" }
covenant-clock = { path = "contracts/clock" }
covenant-clock-tester = { path = "contracts/clock-tester" }
covenant-ibc-forwarder = { path = "contracts/ibc-forwarder" }
covenant-native-splitter = { path = "contracts/native-splitter" }
covenant-interchain-splitter = { path = "contracts/interchain-splitter" }
covenant-swap-holder = { path = "contracts/swap-holder" }
swap-covenant = { path = "contracts/swap-covenant" }
covenant-interchain-router = { path = "contracts/interchain-router" }
covenant-two-party-pol-holder = { path = "contracts/two-party-pol-holder" }
covenant-two-party-pol = { path = "contracts/two-party-pol-covenant" }
covenant-astroport-liquid-pooler = { path = "contracts/astroport-liquid-pooler" }
covenant-native-router = { path = "contracts/native-router" }
covenant-osmo-liquid-pooler = { path = "contracts/osmo-liquid-pooler" }
covenant-outpost-osmo-liquid-pooler = { path = "contracts/outpost-osmo-liquid-pooler" }
covenant-single-party-pol-holder = { path = "contracts/single-party-pol-holder"}
covenant-stride-liquid-staker = { path = "contracts/stride-liquid-staker" }

# packages
polytone = "1.0.0"
clock-derive = { path = "packages/clock-derive" }
cw-fifo = { path = "packages/cw-fifo" }
covenant-macros = { path = "packages/covenant-macros" }
covenant-utils = { path = "packages/covenant-utils" }
covenant-utils = { path = "packages/covenant-utils" }
# the sha2 version here is the same as the one used by
# cosmwasm-std. when bumping cosmwasm-std, this should also be
# updated. to find cosmwasm_std's sha function:
# ```cargo tree --package cosmwasm-std```
sha2 = "0.10.8"
neutron-sdk = { git = "https://github.com/neutron-org/neutron-sdk", branch = "feat/cw-dex-bindings" }
sha2 = "0.10.8"
neutron-sdk = { git = "https://github.com/neutron-org/neutron-sdk", branch = "feat/cw-dex-bindings" }
cosmos-sdk-proto = { version = "0.14.0", default-features = false }
protobuf = { version = "3.2.0", features = ["with-bytes"] }
serde-json-wasm = { version = "0.4.1" }
base64 = "0.13.0"
prost = "0.11"
astroport = "2.9.5"
prost-types = "0.11"
bech32 = "0.9.0"
cosmwasm-schema = "1.5.0"
cosmwasm-std = { version = "1.5.0", features = ["ibc3", "cosmwasm_1_1", "cosmwasm_1_2"] }
cw-storage-plus = "1.2.0"
cw-utils = "1.0.3"
getrandom = { version = "0.2", features = ["js"] }
cw2 = "1.0.1"
serde = { version = "1.0.145", default-features = false, features = ["derive"] }
thiserror = "1.0.31"
schemars = "0.8.10"
protobuf = { version = "3.2.0", features = ["with-bytes"] }
serde-json-wasm = { version = "0.4.1" }
base64 = "0.13.0"
prost = "0.11"
astroport = "2.9.5"
prost-types = "0.11"
bech32 = "0.9.0"
cosmwasm-schema = "1.5.0"
cosmwasm-std = { version = "1.5.0", features = ["ibc3", "cosmwasm_1_1", "cosmwasm_1_2"] }
cw-storage-plus = "1.2.0"
cw-utils = "1.0.3"
getrandom = { version = "0.2", features = ["js"] }
cw2 = "1.0.1"
serde = { version = "1.0.145", default-features = false, features = ["derive"] }
thiserror = "1.0.31"
schemars = "0.8.10"
cw20 = { version = "1.1.2" }
proc-macro2 = "1"
quote = "1"
syn = "1"
proc-macro2 = "1"
quote = "1"
syn = "1"

# dev-dependencies
cw-multi-test = "0.20.0"
anyhow = { version = "1.0.51" }
cw1-whitelist = "1.1.2"
astroport-token = {git = "https://github.com/astroport-fi/astroport-core.git", rev="700f66d"}
astroport-whitelist = {git = "https://github.com/astroport-fi/astroport-core.git", rev="700f66d"}
astroport-factory = {git = "https://github.com/astroport-fi/astroport-core.git", rev="700f66d"}
astroport-native-coin-registry = {git = "https://github.com/astroport-fi/astroport-core.git", rev="700f66d"}
astroport-pair-stable = {git = "https://github.com/astroport-fi/astroport-core.git", rev="700f66d"}
cw-multi-test = "0.20.0"
anyhow = { version = "1.0.51" }
cw1-whitelist = "1.1.2"
astroport-token = { git = "https://github.com/astroport-fi/astroport-core.git", rev = "700f66d" }
astroport-whitelist = { git = "https://github.com/astroport-fi/astroport-core.git", rev = "700f66d" }
astroport-factory = { git = "https://github.com/astroport-fi/astroport-core.git", rev = "700f66d" }
astroport-native-coin-registry = { git = "https://github.com/astroport-fi/astroport-core.git", rev = "700f66d" }
astroport-pair-stable = { git = "https://github.com/astroport-fi/astroport-core.git", rev = "700f66d" }
34 changes: 17 additions & 17 deletions contracts/astroport-liquid-pooler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ exclude = [
"hash.txt",
]


[lib]
crate-type = ["cdylib", "rlib"]

Expand All @@ -25,7 +24,7 @@ library = []

[dependencies]
covenant-macros = { workspace = true }
covenant-clock = { workspace = true, features=["library"] }
covenant-clock = { workspace = true, features = ["library"] }

cosmwasm-schema = { workspace = true }
cosmwasm-std = { workspace = true }
Expand All @@ -38,22 +37,23 @@ thiserror = { workspace = true }
# cosmwasm-std. when bumping cosmwasm-std, this should also be
# updated. to find cosmwasm_std's sha function:
# ```cargo tree --package cosmwasm-std```
sha2 = { workspace = true }
neutron-sdk = { workspace = true }
protobuf = { workspace = true }
schemars = { workspace = true }
bech32 = { workspace = true }
astroport = { workspace = true }
cw20 = { workspace = true }
sha2 = { workspace = true }
neutron-sdk = { workspace = true }
protobuf = { workspace = true }
schemars = { workspace = true }
bech32 = { workspace = true }
astroport = { workspace = true }
cw20 = { workspace = true }
covenant-utils = { workspace = true }

# dev-dependencies
[dev-dependencies]
cw-multi-test = { workspace = true }
astroport = { workspace = true }
cw1-whitelist = { workspace = true }
covenant-two-party-pol-holder = { workspace = true }
astroport-token = { workspace = true }
astroport-whitelist = { workspace = true }
astroport-factory = { workspace = true }
cw-multi-test = { workspace = true }
astroport = { workspace = true }
cw1-whitelist = { workspace = true }
covenant-two-party-pol-holder = { workspace = true }
astroport-token = { workspace = true }
astroport-whitelist = { workspace = true }
astroport-factory = { workspace = true }
astroport-native-coin-registry = { workspace = true }
astroport-pair-stable = { workspace = true }
astroport-pair-stable = { workspace = true }
114 changes: 87 additions & 27 deletions contracts/astroport-liquid-pooler/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
#[cfg(not(feature = "library"))]
use cosmwasm_std::entry_point;
use cosmwasm_std::{
to_json_binary, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo,
ensure, to_json_binary, Binary, Coin, CosmosMsg, Decimal, Deps, DepsMut, Env, MessageInfo,
QuerierWrapper, Reply, Response, StdError, StdResult, SubMsg, Uint128, WasmMsg,
};
use covenant_clock::helpers::{enqueue_msg, verify_clock};
use covenant_utils::{query_astro_pool_token, withdraw_lp_helper::WithdrawLPMsgs};
use cw2::set_contract_version;

use astroport::{
asset::{Asset, PairInfo},
factory::PairType,
pair::{ExecuteMsg::ProvideLiquidity, PoolResponse},
pair::{Cw20HookMsg, ExecuteMsg::ProvideLiquidity, PoolResponse},
DecimalCheckedOps,
};
use cw20::Cw20ExecuteMsg;
use cw_utils::parse_reply_instantiate_data;

use crate::{
Expand Down Expand Up @@ -94,9 +96,80 @@ pub fn execute(
) -> Result<Response, ContractError> {
match msg {
ExecuteMsg::Tick {} => try_tick(deps, env, info),
ExecuteMsg::Withdraw { percentage } => try_withdraw(deps, env, info, percentage),
}
}

fn try_withdraw(
deps: DepsMut,
env: Env,
info: MessageInfo,
percent: Option<Decimal>,
) -> Result<Response, ContractError> {
let percent = percent.unwrap_or(Decimal::one());
// Verify percentage is < 1 and > 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment seems outdated/out of place

let holder_addr = HOLDER_ADDRESS
.load(deps.storage)
.map_err(|_| ContractError::MissingHolderError {})?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can skip this map err as in the instantiation we already do addr_validate and then save it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are probably right, this error should never be reached in practice.


ensure!(info.sender == holder_addr, ContractError::NotHolder {});

// Query LP position of the LPer
let lp_config = LP_CONFIG.load(deps.storage)?;
let lp_token_info = query_astro_pool_token(
deps.querier,
lp_config.pool_address.to_string(),
env.contract.address.to_string(),
)?;

// If percentage is 100%, use the whole balance
// If percentage is less than 100%, calculate the percentage of share we want to withdraw
let withdraw_shares_amount = if percent == Decimal::one() {
lp_token_info.balance_response.balance
} else {
Decimal::from_atomics(lp_token_info.balance_response.balance, 0)?
.checked_mul(percent)?
.to_uint_floor()
};

// Clculate the withdrawn amount of A and B tokens from the shares we have
let withdrawn_coins = deps
.querier
.query_wasm_smart::<Vec<Asset>>(
lp_config.pool_address.to_string(),
&astroport::pair::QueryMsg::Share {
amount: withdraw_shares_amount,
},
)?
.iter()
.map(|asset| asset.to_coin())
.collect::<Result<Vec<Coin>, _>>()?;

// exit pool and withdraw funds with the shares calculated
let withdraw_liquidity_hook = &Cw20HookMsg::WithdrawLiquidity { assets: vec![] };
let withdraw_msg = WasmMsg::Execute {
contract_addr: lp_token_info.pair_info.liquidity_token.to_string(),
msg: to_json_binary(&Cw20ExecuteMsg::Send {
contract: lp_config.pool_address.to_string(),
amount: withdraw_shares_amount,
msg: to_json_binary(withdraw_liquidity_hook)?,
})?,
funds: vec![],
};

// send message to holder that we finished with the withdrawal
// with the funds we withdrew from the pool
let to_holder_msg = WasmMsg::Execute {
contract_addr: holder_addr.to_string(),
msg: to_json_binary(&WithdrawLPMsgs::Distribute {})?,
funds: withdrawn_coins,
};

Ok(Response::default()
.add_message(withdraw_msg)
.add_message(to_holder_msg))
}

/// attempts to advance the state machine. performs `info.sender` validation.
fn try_tick(deps: DepsMut, env: Env, info: MessageInfo) -> Result<Response, ContractError> {
// Verify caller is the clock
Expand Down Expand Up @@ -165,7 +238,7 @@ fn try_lp(mut deps: DepsMut, env: Env) -> Result<Response, ContractError> {
// exactly one balance is non-zero, we attempt single-side
(true, false) | (false, true) => {
let single_sided_submsg =
try_get_single_side_lp_submsg(deps.branch(), coin_a, coin_b, lp_config)?;
try_get_single_side_lp_submsg(deps.branch(), env, (coin_a, coin_b), lp_config)?;
if let Some(msg) = single_sided_submsg {
return Ok(Response::default()
.add_submessage(msg)
Expand All @@ -176,11 +249,10 @@ fn try_lp(mut deps: DepsMut, env: Env) -> Result<Response, ContractError> {
(false, false) => {
let double_sided_submsg = try_get_double_side_lp_submsg(
deps.branch(),
coin_a,
coin_b,
env,
(coin_a, coin_b),
a_to_b_ratio,
pool_token_a_bal,
pool_token_b_bal,
(pool_token_a_bal, pool_token_b_bal),
lp_config,
)?;
if let Some(msg) = double_sided_submsg {
Expand All @@ -205,18 +277,12 @@ fn try_lp(mut deps: DepsMut, env: Env) -> Result<Response, ContractError> {
/// the existing pool ratio.
fn try_get_double_side_lp_submsg(
deps: DepsMut,
token_a: Coin,
token_b: Coin,
env: Env,
(token_a, token_b): (Coin, Coin),
pool_token_ratio: Decimal,
pool_token_a_bal: Uint128,
pool_token_b_bal: Uint128,
(pool_token_a_bal, pool_token_b_bal): (Uint128, Uint128),
lp_config: LpConfig,
) -> Result<Option<SubMsg>, ContractError> {
let holder_address = match HOLDER_ADDRESS.may_load(deps.storage)? {
Some(addr) => addr,
None => return Err(ContractError::MissingHolderError {}),
};

// we thus find the required token amount to enter into the position using all available b tokens:
let required_token_a_amount = pool_token_ratio.checked_mul_uint128(token_b.amount)?;

Expand Down Expand Up @@ -248,7 +314,7 @@ fn try_get_double_side_lp_submsg(
assets: vec![asset_a_double_sided, asset_b_double_sided],
slippage_tolerance: lp_config.slippage_tolerance,
auto_stake: Some(false),
receiver: Some(holder_address.to_string()),
receiver: Some(env.contract.address.to_string()),
};

// update the provided amounts and leftover assets
Expand Down Expand Up @@ -277,15 +343,10 @@ fn try_get_double_side_lp_submsg(
/// single-side liquidity limits, we provide it.
fn try_get_single_side_lp_submsg(
deps: DepsMut,
coin_a: Coin,
coin_b: Coin,
env: Env,
(coin_a, coin_b): (Coin, Coin),
lp_config: LpConfig,
) -> Result<Option<SubMsg>, ContractError> {
let holder_address = match HOLDER_ADDRESS.may_load(deps.storage)? {
Some(addr) => addr,
None => return Err(ContractError::MissingHolderError {}),
};

let assets = lp_config
.asset_data
.to_asset_vec(coin_a.amount, coin_b.amount);
Expand All @@ -295,7 +356,7 @@ fn try_get_single_side_lp_submsg(
assets,
slippage_tolerance: lp_config.slippage_tolerance,
auto_stake: Some(false),
receiver: Some(holder_address.to_string()),
receiver: Some(env.contract.address.to_string()),
};

// now we try to submit the message for either B or A token single side liquidity
Expand Down Expand Up @@ -439,8 +500,7 @@ fn handle_double_sided_reply_id(
_env: Env,
msg: Reply,
) -> Result<Response, ContractError> {
let parsed_data = parse_reply_instantiate_data(msg);
match parsed_data {
match parse_reply_instantiate_data(msg) {
Ok(response) => Ok(Response::default()
.add_attribute("method", "handle_double_sided_reply_id")
.add_attribute(
Expand Down
Loading
Loading