|
3 | 3 | use crate::{prelude::*, state::*};
|
4 | 4 | use core::panic;
|
5 | 5 | use cosmwasm_std::{
|
6 |
| - from_binary, to_binary, Addr, BankMsg, Binary, Coin, ContractInfo, CosmosMsg, Deps, DepsMut, |
7 |
| - Env, MessageInfo, Response, StdError, StdResult, SubMsgResult, Timestamp, Uint128, Uint256, |
8 |
| - WasmMsg, |
| 6 | + from_binary, to_binary, Addr, Attribute, BankMsg, Binary, Coin, ContractInfo, CosmosMsg, |
| 7 | + Decimal, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, SubMsgResult, |
| 8 | + Timestamp, Uint128, Uint256, WasmMsg, |
9 | 9 | };
|
| 10 | + |
10 | 11 | use ethnum::U256;
|
11 | 12 | use serde::Serialize;
|
| 13 | +use shade_protocol::lb_libraries::constants::PRECISION; |
| 14 | +use shade_protocol::liquidity_book::lb_pair::QueryMsg::GetPairInfo; |
12 | 15 | use shade_protocol::{
|
13 | 16 | c_std::{shd_entry_point, Reply, SubMsg},
|
14 | 17 | contract_interfaces::liquidity_book::{
|
@@ -39,6 +42,7 @@ use shade_protocol::{
|
39 | 42 | utils::pad_handle_result,
|
40 | 43 | BLOCK_SIZE,
|
41 | 44 | };
|
| 45 | +use shadeswap_shared::router::ExecuteMsgResponse; |
42 | 46 | use std::{collections::HashMap, ops::Sub};
|
43 | 47 | use tokens::TokenType;
|
44 | 48 | use types::{Bytes32, LBPairInformation, MintArrays};
|
@@ -218,7 +222,7 @@ pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> R
|
218 | 222 | };
|
219 | 223 |
|
220 | 224 | let swap_for_y: bool;
|
221 |
| - if info.sender == config.token_x.unique_key() { |
| 225 | + if offer.token.unique_key() == config.token_x.unique_key() { |
222 | 226 | swap_for_y = true;
|
223 | 227 | } else {
|
224 | 228 | swap_for_y = false;
|
@@ -419,21 +423,38 @@ fn try_swap(
|
419 | 423 | })?;
|
420 | 424 |
|
421 | 425 | let mut messages: Vec<CosmosMsg> = Vec::new();
|
| 426 | + let amount_out; |
422 | 427 | if swap_for_y {
|
423 |
| - let msg = BinHelper::transfer_y(amounts_out, token_y, to); |
| 428 | + amount_out = amounts_out.decode_y(); |
| 429 | + let msg = BinHelper::transfer_y(amounts_out, token_y.clone(), to); |
424 | 430 |
|
425 | 431 | if let Some(message) = msg {
|
426 | 432 | messages.push(message);
|
427 | 433 | }
|
428 | 434 | } else {
|
429 |
| - let msg = BinHelper::transfer_x(amounts_out, token_x, to); |
| 435 | + amount_out = amounts_out.decode_x(); |
| 436 | + let msg = BinHelper::transfer_x(amounts_out, token_x.clone(), to); |
430 | 437 |
|
431 | 438 | if let Some(message) = msg {
|
432 | 439 | messages.push(message);
|
433 | 440 | }
|
434 | 441 | }
|
435 | 442 |
|
436 |
| - Ok(Response::default().add_messages(messages)) |
| 443 | + Ok(Response::new() |
| 444 | + .add_messages(messages) |
| 445 | + .add_attributes(vec![ |
| 446 | + Attribute::new("amount_in", amounts_received), |
| 447 | + Attribute::new("amount_out", amount_out.to_string()), |
| 448 | + Attribute::new("lp_fee_amount", "0".to_string()), // TODO FILL with correct parameters |
| 449 | + Attribute::new("total_fee_amount", "0".to_string()), // TODO FILL with correct parameters |
| 450 | + Attribute::new("shade_dao_fee_amount", "0".to_string()), // TODO FILL with correct parameters |
| 451 | + Attribute::new("token_in_key", token_x.unique_key()), |
| 452 | + Attribute::new("token_out_key", token_y.unique_key()), |
| 453 | + ]) |
| 454 | + .set_data(to_binary(&ExecuteMsgResponse::SwapResult { |
| 455 | + amount_in: amounts_received, |
| 456 | + amount_out: Uint128::from(amount_out), |
| 457 | + })?)) |
437 | 458 | }
|
438 | 459 |
|
439 | 460 | /// Flash loan tokens from the pool to a receiver contract and execute a callback function.
|
@@ -1421,6 +1442,7 @@ fn receiver_callback(
|
1421 | 1442 | #[shd_entry_point]
|
1422 | 1443 | pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<Binary> {
|
1423 | 1444 | match msg {
|
| 1445 | + QueryMsg::GetPairInfo {} => to_binary(&query_pair_info(deps)?).map_err(Error::CwErr), |
1424 | 1446 | QueryMsg::GetFactory {} => to_binary(&query_factory(deps)?).map_err(Error::CwErr),
|
1425 | 1447 | QueryMsg::GetTokenX {} => to_binary(&query_token_x(deps)?).map_err(Error::CwErr),
|
1426 | 1448 | QueryMsg::GetTokenY {} => to_binary(&query_token_y(deps)?).map_err(Error::CwErr),
|
@@ -1467,9 +1489,118 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result<Binary> {
|
1467 | 1489 | }
|
1468 | 1490 | QueryMsg::GetLbToken {} => to_binary(&query_lb_token(deps)?).map_err(Error::CwErr),
|
1469 | 1491 | QueryMsg::GetTokens {} => to_binary(&query_tokens(deps)?).map_err(Error::CwErr),
|
| 1492 | + GetPairInfo {} => todo!(), |
| 1493 | + QueryMsg::SwapSimulation { offer, exclude_fee } => { |
| 1494 | + to_binary(&query_swap_simulation(deps, env, offer, exclude_fee)?).map_err(Error::CwErr) |
| 1495 | + } |
1470 | 1496 | }
|
1471 | 1497 | }
|
1472 | 1498 |
|
| 1499 | +/// Returns the Liquidity Book Factory. |
| 1500 | +/// |
| 1501 | +/// # Returns |
| 1502 | +/// |
| 1503 | +/// * `factory` - The Liquidity Book Factory |
| 1504 | +fn query_pair_info(deps: Deps) -> Result<shadeswap_shared::msg::amm_pair::QueryMsgResponse> { |
| 1505 | + let state = CONFIG.load(deps.storage)?; |
| 1506 | + |
| 1507 | + let (mut reserve_x, mut reserve_y) = state.reserves.decode(); |
| 1508 | + let (protocol_fee_x, protocol_fee_y) = state.protocol_fees.decode(); |
| 1509 | + |
| 1510 | + Ok( |
| 1511 | + shadeswap_shared::msg::amm_pair::QueryMsgResponse::GetPairInfo { |
| 1512 | + liquidity_token: shade_protocol::Contract { |
| 1513 | + address: state.lb_token.address, |
| 1514 | + code_hash: state.lb_token.code_hash, |
| 1515 | + }, |
| 1516 | + factory: Some(shade_protocol::Contract { |
| 1517 | + address: state.factory.address, |
| 1518 | + code_hash: state.factory.code_hash, |
| 1519 | + }), |
| 1520 | + pair: shadeswap_shared::core::TokenPair { |
| 1521 | + 0: state.token_x, |
| 1522 | + 1: state.token_y, |
| 1523 | + 2: false, |
| 1524 | + }, |
| 1525 | + amount_0: Uint128::from(reserve_x), |
| 1526 | + amount_1: Uint128::from(reserve_y), |
| 1527 | + total_liquidity: Uint128::default(), // no global liquidity, liquidity is calculated on per bin basis |
| 1528 | + contract_version: 1, // TODO set this like const AMM_PAIR_CONTRACT_VERSION: u32 = 1; |
| 1529 | + fee_info: shadeswap_shared::amm_pair::FeeInfo { |
| 1530 | + shade_dao_address: Addr::unchecked(""), // TODO set shade dao address |
| 1531 | + lp_fee: shadeswap_shared::core::Fee { |
| 1532 | + // TODO set this |
| 1533 | + nom: state.pair_parameters.get_base_fee_u64(state.bin_step), |
| 1534 | + denom: 1_000_000_000_000_000_000, |
| 1535 | + }, |
| 1536 | + shade_dao_fee: shadeswap_shared::core::Fee { |
| 1537 | + // TODO set this |
| 1538 | + nom: state.pair_parameters.get_base_fee_u64(state.bin_step), |
| 1539 | + denom: 1_000_000_000_000_000_000, |
| 1540 | + }, |
| 1541 | + stable_lp_fee: shadeswap_shared::core::Fee { |
| 1542 | + // TODO set this |
| 1543 | + nom: state.pair_parameters.get_base_fee_u64(state.bin_step), |
| 1544 | + denom: 1_000_000_000_000_000_000, |
| 1545 | + }, |
| 1546 | + stable_shade_dao_fee: shadeswap_shared::core::Fee { |
| 1547 | + // TODO set this |
| 1548 | + nom: state.pair_parameters.get_base_fee_u64(state.bin_step), |
| 1549 | + denom: 1_000_000_000_000_000_000, |
| 1550 | + }, |
| 1551 | + }, |
| 1552 | + stable_info: None, |
| 1553 | + }, |
| 1554 | + ) |
| 1555 | +} |
| 1556 | + |
| 1557 | +// / Returns the Liquidity Book Factory. |
| 1558 | +// / |
| 1559 | +// / # Returns |
| 1560 | +// / |
| 1561 | +// / * `factory` - The Liquidity Book Factory |
| 1562 | +fn query_swap_simulation( |
| 1563 | + deps: Deps, |
| 1564 | + env: Env, |
| 1565 | + offer: shade_protocol::lb_libraries::tokens::TokenAmount, |
| 1566 | + exclude_fee: Option<bool>, |
| 1567 | +) -> Result<shadeswap_shared::msg::amm_pair::QueryMsgResponse> { |
| 1568 | + let state = CONFIG.load(deps.storage)?; |
| 1569 | + |
| 1570 | + let (mut reserve_x, mut reserve_y) = state.reserves.decode(); |
| 1571 | + let (protocol_fee_x, protocol_fee_y) = state.protocol_fees.decode(); |
| 1572 | + let mut swap_for_y = false; |
| 1573 | + match offer.token { |
| 1574 | + token if token == state.token_x => swap_for_y = true, |
| 1575 | + token if token == state.token_y => {} |
| 1576 | + _ => panic!("No such token"), |
| 1577 | + }; |
| 1578 | + |
| 1579 | + let res = query_swap_out(deps, env, offer.amount.into(), swap_for_y)?; |
| 1580 | + |
| 1581 | + if (res.amount_in_left.u128() > 0u128) { |
| 1582 | + return Err(Error::AmountInLeft { |
| 1583 | + amount_left_in: res.amount_in_left, |
| 1584 | + total_amount: offer.amount, |
| 1585 | + swapped_amount: res.amount_out, |
| 1586 | + }); |
| 1587 | + } |
| 1588 | + |
| 1589 | + let price = Decimal::from_ratio(res.amount_out, offer.amount).to_string(); |
| 1590 | + |
| 1591 | + Ok( |
| 1592 | + shadeswap_shared::msg::amm_pair::QueryMsgResponse::SwapSimulation { |
| 1593 | + total_fee_amount: res.fee, |
| 1594 | + lp_fee_amount: res.fee, //TODO lpfee |
| 1595 | + shade_dao_fee_amount: res.fee, // dao fee |
| 1596 | + result: SwapResult { |
| 1597 | + return_amount: res.amount_out, |
| 1598 | + }, |
| 1599 | + price, |
| 1600 | + }, |
| 1601 | + ) |
| 1602 | +} |
| 1603 | + |
1473 | 1604 | /// Returns the Liquidity Book Factory.
|
1474 | 1605 | ///
|
1475 | 1606 | /// # Returns
|
|
0 commit comments