Skip to content

Commit

Permalink
First Quasar implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Kayanski committed Jan 17, 2024
1 parent 00830d0 commit ad5af98
Show file tree
Hide file tree
Showing 11 changed files with 77 additions and 74 deletions.
7 changes: 6 additions & 1 deletion contracts/savings-app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ export = []
# enable node-backed tests (ensure Docker is running)
# run with `cargo test --jobs 1 --features node-tests`
node-tests = ["interface"]
interface = ["export", "dep:abstract-interface", "dep:cw-orch"]
interface = [
"export",
"dep:abstract-interface",
"dep:cw-orch",
"abstract-app/interface-macro",
]
schema = ["abstract-app/schema"]

[dependencies]
Expand Down
12 changes: 12 additions & 0 deletions contracts/savings-app/src/cl_vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Coin, Uint128};

use crate::msg::AssetsBalanceResponse;

#[cw_serde]
pub enum ExecuteMsg {
ExactDeposit {
Expand All @@ -23,6 +25,7 @@ pub enum VaultMessage {
#[cw_serde]
pub enum QueryMsg {
TotalAssets {},
ConvertToAssets { amount: Uint128 },
VaultExtension(VaultQuery),
}

Expand All @@ -38,6 +41,10 @@ pub enum VaultQuery {
pub enum BalancesQuery {
#[returns(UserSharesBalanceResponse)]
UserSharesBalance { user: String },
#[returns(AssetsBalanceResponse)]
UserAssetsBalance { user: String },
#[returns(UserRewardsResponse)]
UserRewards { user: String },
}

#[cw_serde]
Expand All @@ -50,3 +57,8 @@ pub struct TotalAssetsResponse {
pub struct UserSharesBalanceResponse {
pub balance: Uint128,
}

#[cw_serde]
pub struct UserRewardsResponse {
pub rewards: Vec<Coin>,
}
3 changes: 1 addition & 2 deletions contracts/savings-app/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::{
error::AppError,
handlers,
msg::{AppExecuteMsg, AppInstantiateMsg, AppQueryMsg},
replies::{self},
};
use abstract_app::AppContract;
use abstract_core::objects::dependency::StaticDependency;
Expand All @@ -21,7 +20,7 @@ pub type AppResult<T = Response> = Result<T, AppError>;
pub type App = AppContract<AppError, AppInstantiateMsg, AppExecuteMsg, AppQueryMsg, AppMigrateMsg>;

const DEX_DEPENDENCY: StaticDependency = StaticDependency::new(
abstract_dex_adapter::EXCHANGE,
abstract_dex_adapter::DEX_ADAPTER_ID,
&[abstract_dex_adapter::contract::CONTRACT_VERSION],
);

Expand Down
59 changes: 19 additions & 40 deletions contracts/savings-app/src/handlers/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::cl_vault::{
use crate::contract::{App, AppResult};
use crate::error::AppError;
use crate::msg::{AppExecuteMsg, ExecuteMsg};
use crate::state::{CONFIG, STATE};
use crate::state::CONFIG;
use abstract_core::ans_host::{AssetPairingFilter, AssetPairingMapEntry};
use abstract_core::objects::{AnsAsset, AssetEntry};
use abstract_dex_adapter::api::Dex;
Expand Down Expand Up @@ -60,7 +60,7 @@ fn deposit(deps: DepsMut, env: Env, info: MessageInfo, app: App) -> AppResult {
});

Ok(app
.tag_response(Response::default(), "deposit")
.response("deposit")
.add_message(msg_swap)
.add_message(msg_deposit))
}
Expand All @@ -78,7 +78,7 @@ fn withdraw(
let (withdraw_msg, withdraw_amount) = _inner_withdraw(deps, &env, amount, &app)?;

Ok(app
.tag_response(Response::default(), "withdraw")
.response("withdraw")
.add_attribute("withdraw_amount", withdraw_amount)
.add_message(withdraw_msg))
}
Expand Down Expand Up @@ -109,21 +109,12 @@ fn autocompound(deps: DepsMut, env: Env, info: MessageInfo, app: App) -> AppResu
});

Ok(app
.tag_response(Response::default(), "auto-compound")
.response("auto-compound")
.add_message(msg_claim)
.add_message(msg_swap)
.add_message(msg_deposit))
}

fn restake(deps: DepsMut, env: Env, info: MessageInfo, app: App) -> AppResult {
// Only the authorized addresses (admin ?) can auto-compound
if env.contract.address != info.sender {
return Err(AppError::Unauthorized {});
}

Ok(app.tag_response(Response::default(), "restake"))
}

fn internal_deposit_all(deps: Deps, env: Env, info: MessageInfo, app: App) -> AppResult<Response> {
if info.sender != env.contract.address {
return Err(AppError::Unauthorized {});
Expand Down Expand Up @@ -160,17 +151,14 @@ fn internal_deposit_all(deps: Deps, env: Env, info: MessageInfo, app: App) -> Ap
],
});

Ok(app
.tag_response(Response::default(), "deposit_all")
.add_message(msg))
Ok(app.response("deposit_all").add_message(msg))
}

fn internal_swap_correct_amount(deps: DepsMut, env: Env, info: MessageInfo, app: App) -> AppResult {
if info.sender != env.contract.address {
return Err(AppError::Unauthorized {});
}
let config = CONFIG.load(deps.storage)?;
let state = STATE.load(deps.storage)?;
let ans = app.name_service(deps.as_ref());

// First we query the pool to know the ratio we can provide liquidity at :
Expand All @@ -182,10 +170,14 @@ fn internal_swap_correct_amount(deps: DepsMut, env: Env, info: MessageInfo, app:

let token0 = all_quasar_assets.token0;
let token1 = all_quasar_assets.token1;
let quasar_asset_entries = ans.query(&AssetList::from(&vec![token0, token1]).to_vec())?;
let quasar_asset_entries =
ans.query(&AssetList::from(&vec![token0.clone(), token1.clone()]).to_vec())?;
let asset_pairing_resp: Vec<AssetPairingMapEntry> = ans.pool_list(
Some(AssetPairingFilter {
asset_pair: Some((quasar_asset_entries[0].name, quasar_asset_entries[1].name)),
asset_pair: Some((
quasar_asset_entries[0].name.clone(),
quasar_asset_entries[1].name.clone(),
)),
dex: None,
}),
None,
Expand All @@ -201,10 +193,7 @@ fn internal_swap_correct_amount(deps: DepsMut, env: Env, info: MessageInfo, app:

let dex_name = pair.dex();

let ratio = Decimal::from_ratio(
all_quasar_assets.token0.amount,
all_quasar_assets.token1.amount,
);
let ratio = Decimal::from_ratio(token0.amount, token1.amount);

// Then we do swaps to get the right ratio of liquidity to provide

Expand All @@ -213,19 +202,18 @@ fn internal_swap_correct_amount(deps: DepsMut, env: Env, info: MessageInfo, app:

let funds = ContractBalances {
token0: AnsAsset {
name: quasar_asset_entries[0].name,
name: quasar_asset_entries[0].name.clone(),
amount: balances.token0,
},
token1: AnsAsset {
name: quasar_asset_entries[1].name,
name: quasar_asset_entries[1].name.clone(),
amount: balances.token1,
},
};

let price = get_price_for(
deps.as_ref(),
quasar_asset_entries[0],
quasar_asset_entries[1].name,
quasar_asset_entries[0].clone(),
quasar_asset_entries[1].name.clone(),
&app.dex(deps.as_ref(), dex_name.to_string()),
)?;

Expand All @@ -240,9 +228,7 @@ fn internal_swap_correct_amount(deps: DepsMut, env: Env, info: MessageInfo, app:
None,
)?;

Ok(app
.tag_response(Response::default(), "swap_all")
.add_message(trigger_swap_msg))
Ok(app.response("swap_all").add_message(trigger_swap_msg))
}

fn _inner_withdraw(
Expand All @@ -252,8 +238,6 @@ fn _inner_withdraw(
app: &App,
) -> AppResult<(CosmosMsg, Uint128)> {
let config = CONFIG.load(deps.storage)?;
let state = STATE.load(deps.storage)?;
let position_id = state.current_position_id.ok_or(AppError::NoPosition {})?;

let liquidity_amount = if let Some(amount) = amount {
amount
Expand Down Expand Up @@ -281,13 +265,8 @@ fn _inner_withdraw(
Ok((msg, liquidity_amount))
}

fn get_price_for(
deps: Deps,
token0: OfferAsset,
token1: AssetEntry,
dex: &Dex<App>,
) -> AppResult<Decimal> {
let swap_response = dex.simulate_swap(token0, token1)?;
fn get_price_for(token0: OfferAsset, token1: AssetEntry, dex: &Dex<App>) -> AppResult<Decimal> {
let swap_response = dex.simulate_swap(token0.clone(), token1)?;

Ok(Decimal::from_ratio(
swap_response.return_amount,
Expand Down
4 changes: 2 additions & 2 deletions contracts/savings-app/src/handlers/instantiate.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use abstract_sdk::AbstractResponse;
use cosmwasm_std::{DepsMut, Env, MessageInfo, Response};
use cosmwasm_std::{DepsMut, Env, MessageInfo};

use crate::contract::{App, AppResult};
use crate::msg::AppInstantiateMsg;
Expand All @@ -21,5 +21,5 @@ pub fn instantiate_handler(
CONFIG.save(deps.storage, &config)?;

// Example instantiation that doesn't do anything
Ok(app.tag_response(Response::new(), "instantiate_savings_app"))
Ok(app.response("instantiate_savings_app"))
}
4 changes: 2 additions & 2 deletions contracts/savings-app/src/handlers/migrate.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::contract::{App, AppResult};
use crate::msg::AppMigrateMsg;
use abstract_sdk::AbstractResponse;
use cosmwasm_std::{DepsMut, Env, Response};
use cosmwasm_std::{DepsMut, Env};

/// Handle the app migrate msg
/// The top-level Abstract app does version checking and dispatches to this handler
pub fn migrate_handler(_deps: DepsMut, _env: Env, app: App, _msg: AppMigrateMsg) -> AppResult {
Ok(app.tag_response(Response::default(), "migrate"))
Ok(app.response("migrate"))
}
39 changes: 26 additions & 13 deletions contracts/savings-app/src/handlers/query.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use crate::cl_vault::{self, BalancesQuery, UserRewardsResponse};
use crate::contract::{App, AppResult};
use crate::msg::{AppQueryMsg, AvailableRewardsResponse, StateResponse};
use crate::msg::{AppQueryMsg, AssetsBalanceResponse, AvailableRewardsResponse, StateResponse};
use crate::state::CONFIG;
use cosmwasm_std::{
coin, coins, to_json_binary, BalanceResponse, Binary, Deps, Env, StdResult, Uint128,
};
use cosmwasm_std::{to_json_binary, Binary, Deps, Env, StdResult, Uint128};

pub fn query_handler(deps: Deps, _env: Env, app: &App, msg: AppQueryMsg) -> AppResult<Binary> {
pub fn query_handler(deps: Deps, env: Env, _app: &App, msg: AppQueryMsg) -> AppResult<Binary> {
match msg {
AppQueryMsg::State {} => to_json_binary(&query_state(deps)?),
AppQueryMsg::Balance {} => to_json_binary(&query_balance(deps, app)?),
AppQueryMsg::AvailableRewards {} => to_json_binary(&query_rewards(deps, app)?),
AppQueryMsg::Balance {} => to_json_binary(&query_balance(deps, env)?),
AppQueryMsg::AvailableRewards {} => to_json_binary(&query_rewards(deps, env)?),
}
.map_err(Into::into)
}
Expand All @@ -23,17 +22,31 @@ fn query_state(deps: Deps) -> StdResult<StateResponse> {
})
}

fn query_balance(deps: Deps, app: &App) -> StdResult<BalanceResponse> {
fn query_balance(deps: Deps, env: Env) -> StdResult<AssetsBalanceResponse> {
let config = CONFIG.load(deps.storage)?;

Ok(BalanceResponse {
amount: coin(0, config.deposit_info.to_string()),
})
deps.querier.query_wasm_smart(
config.quasar_pool.to_string(),
&cl_vault::QueryMsg::VaultExtension(cl_vault::VaultQuery::Balances(
BalancesQuery::UserAssetsBalance {
user: env.contract.address.to_string(),
},
)),
)
}
fn query_rewards(deps: Deps, app: &App) -> StdResult<AvailableRewardsResponse> {
fn query_rewards(deps: Deps, env: Env) -> StdResult<AvailableRewardsResponse> {
let config = CONFIG.load(deps.storage)?;

let response: UserRewardsResponse = deps.querier.query_wasm_smart(
config.quasar_pool.to_string(),
&cl_vault::QueryMsg::VaultExtension(cl_vault::VaultQuery::Balances(
BalancesQuery::UserRewards {
user: env.contract.address.to_string(),
},
)),
)?;
Ok(AvailableRewardsResponse {
available_rewards: coins(0, config.deposit_info.to_string()),
available_rewards: response.rewards,
})
}

Expand Down
11 changes: 8 additions & 3 deletions contracts/savings-app/src/msg.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use abstract_dex_adapter::msg::DexName;
use cosmwasm_schema::QueryResponses;
use cosmwasm_std::{Coin, Int64, Uint128};
use cosmwasm_schema::{cw_serde, QueryResponses};
use cosmwasm_std::{Coin, Uint128};
use cw_asset::AssetInfoBase;

use crate::contract::App;
Expand Down Expand Up @@ -48,7 +48,7 @@ pub enum AppExecuteMsg {
pub enum AppQueryMsg {
#[returns(StateResponse)]
State {},
#[returns(BalanceResponse)]
#[returns(AssetsBalanceResponse)]
Balance {},
#[returns(AvailableRewardsResponse)]
AvailableRewards {},
Expand All @@ -72,3 +72,8 @@ pub struct BalanceResponse {
pub struct AvailableRewardsResponse {
pub available_rewards: Vec<Coin>,
}

#[cw_serde]
pub struct AssetsBalanceResponse {
pub balances: Vec<Coin>,
}
4 changes: 0 additions & 4 deletions contracts/savings-app/src/replies/deposit.rs

This file was deleted.

2 changes: 1 addition & 1 deletion contracts/savings-app/src/replies/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mod deposit;

6 changes: 0 additions & 6 deletions contracts/savings-app/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,4 @@ impl Config {
}
}

#[cosmwasm_schema::cw_serde]
pub struct State {
pub current_position_id: Option<u64>,
}

pub const CONFIG: Item<Config> = Item::new("config");
pub const STATE: Item<State> = Item::new("state");

0 comments on commit ad5af98

Please sign in to comment.