Skip to content

Commit

Permalink
fix(smart-contracts): refactor math on try bid
Browse files Browse the repository at this point in the history
  • Loading branch information
nseguias committed Mar 4, 2024
1 parent fc9e9e0 commit cd6221c
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 37 deletions.
96 changes: 61 additions & 35 deletions contracts/injective-auction-pool/src/executions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ use crate::helpers::query_current_auction;
use crate::state::{Auction, BIDDING_BALANCE, CONFIG, CURRENT_AUCTION, TREASURE_CHEST_CONTRACTS};
use crate::ContractError;
use cosmwasm_std::{
coins, ensure, to_json_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, DepsMut, Env,
coins, ensure, to_json_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Decimal, DepsMut, Env,
MessageInfo, OverflowError, Response, Uint128, WasmMsg,
};
use injective_auction::auction::MsgBid;
use injective_auction::auction_pool::ExecuteMsg::TryBid;
use treasurechest::tf::tokenfactory::TokenFactoryType;
use prost::Message;

const DAY_IN_SECONDS: u64 = 86400;

Expand All @@ -20,36 +21,32 @@ pub(crate) fn join_pool(
auction_round: u64,
basket_value: Uint128,
) -> Result<Response, ContractError> {
//todo ?Will reject funds once pool is above the current reward pool price?)

let config = CONFIG.load(deps.storage)?;

let amount = cw_utils::must_pay(&info, &config.native_denom)?;

let current_auction_round = query_current_auction(deps.as_ref())?
.auction_round
.ok_or(ContractError::CurrentAuctionQueryError)?;

// prevents the user from joining the pool if the auction round is over
ensure!(
current_auction_round == auction_round,
ContractError::InvalidAuctionRound {
if auction_round != current_auction_round {
return Err(ContractError::InvalidAuctionRound {
current_auction_round,
auction_round
}
);
auction_round,
});
}

let mut messages = vec![];

let lp_subdenom = CURRENT_AUCTION.load(deps.storage)?.lp_subdenom;

// mint the lp token and send it to the user
let lp_subdenom = CURRENT_AUCTION.load(deps.storage)?.lp_subdenom;
messages.push(config.token_factory_type.mint(
env.contract.address.clone(),
lp_subdenom.to_string().as_str(),
amount,
));

// send the minted lp token to the user
let lp_denom = format!("factory/{}/{}", env.contract.address, lp_subdenom);
messages.push(
BankMsg::Send {
Expand All @@ -59,6 +56,7 @@ pub(crate) fn join_pool(
.into(),
);

// increase the balance that can be used for bidding
BIDDING_BALANCE
.update::<_, ContractError>(deps.storage, |balance| Ok(balance.checked_add(amount)?))?;

Expand Down Expand Up @@ -140,48 +138,76 @@ pub(crate) fn try_bid(
auction_round: u64,
basket_value: Uint128,
) -> Result<Response, ContractError> {
// only whitelist addresses or the contract itself can bid on the auction
let config = CONFIG.load(deps.storage)?;
if info.sender != env.contract.address || !config.whitelisted_addresses.contains(&info.sender) {
return Err(ContractError::Unauthorized {});
}
let current_auction_round_response = query_current_auction(deps.as_ref())?;
let current_auction_round = current_auction_round_response
.auction_round
.ok_or(ContractError::CurrentAuctionQueryError)?;

// prevents the contract from bidding on the wrong auction round
if auction_round
!= current_auction_round_response
.auction_round
.ok_or(ContractError::CurrentAuctionQueryError)?
{
if auction_round != current_auction_round {
return Err(ContractError::InvalidAuctionRound {
current_auction_round: current_auction_round_response
.auction_round
.ok_or(ContractError::CurrentAuctionQueryError)?,
current_auction_round,
auction_round,
});
}

// only whitelist addresses or the contract itself can bid on the auction
let config = CONFIG.load(deps.storage)?;
if info.sender != env.contract.address || !config.whitelisted_addresses.contains(&info.sender) {
return Err(ContractError::Unauthorized {});
}

// prevents the contract from bidding if the contract is already the highest bidder
if current_auction_round_response.highest_bidder == Some(env.contract.address.to_string()) {
return Ok(Response::default()
.add_attribute("action", "did_not_bid")
.add_attribute("reason", "contract_is_already_the_highest_bidder"));
}

// prevents the contract from bidding if the current bid is higher than the basket value
let current_bid_amount: Uint128 =
current_auction_round_response.highest_bid_amount.unwrap_or(0.to_string()).parse()?;
// calculate the minimum allowed bid to not be rejected by the auction module
// minimum_allowed_bid = (highest_bid_amount * (1 + min_next_bid_increment_rate)) + 1
let minimum_allowed_bid = current_auction_round_response
.highest_bid_amount
.unwrap_or(0.to_string())
.parse::<Decimal>()?
.checked_mul((Decimal::one().checked_add(config.min_next_bid_increment_rate))?)?
.to_uint_ceil()
.checked_add(Uint128::one())?;

// prevents the contract from bidding if the minimum allowed bid is higher than bidding balance
let bidding_balance: Uint128 = BIDDING_BALANCE.load(deps.storage)?;
if minimum_allowed_bid > bidding_balance {
return Ok(Response::default()
.add_attribute("action", "did_not_bid")
.add_attribute("reason", "minimum_allowed_bid_is_higher_than_bidding_balance"));
}

if current_bid_amount >= basket_value {
// prevents the contract from bidding if the returns are not high enough
if basket_value * (Decimal::one() - config.min_return) > minimum_allowed_bid {
return Ok(Response::default()
.add_attribute("action", "did_not_bid")
.add_attribute("reason", "bid_is_higher_than_basket_amount"));
.add_attribute("reason", "basket_value_is_not_worth_bidding_for"));
}

// TODO: continue with the bidding process
// TODO: need to send some funds here?
let message: CosmosMsg = CosmosMsg::Stargate {
type_url: "/injective.auction.v1beta1.MsgBid".to_string(),
value: {
let msg = MsgBid {
sender: env.contract.address.to_string(),
bid_amount: Some(injective_auction::auction::Coin {
denom: config.native_denom,
amount: minimum_allowed_bid.to_string(),
}),
round: auction_round,
};
Binary(msg.encode_to_vec())
},
};

Ok(Response::default().add_attributes(vec![("action", "try_bid".to_string())]))
Ok(Response::default()
.add_message(message)
.add_attribute("action", "try_bid".to_string())
.add_attribute("amount", minimum_allowed_bid.to_string()))
}

pub fn settle_auction(
Expand Down Expand Up @@ -271,7 +297,7 @@ pub fn settle_auction(
denom: config.native_denom.clone(),
owner: env.contract.address.to_string(),
notes: "".to_string(),
token_factory: TokenFactoryType::Injective.to_string(),
token_factory: config.token_factory_type.to_string(),
burn_it: Some(false),
})?,
funds: basket_to_treasure_chest,
Expand Down
4 changes: 2 additions & 2 deletions packages/injective_auction/src/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use osmosis_std_derive::CosmwasmExt;
schemars::JsonSchema,
CosmwasmExt,
)]
#[proto_message(type_url = "/cosmos.base.v1beta1.Coin")]
#[proto_message(type_url = "/injective.base.v1beta1.Coin")]
pub struct Coin {
#[prost(string, tag = "1")]
pub denom: ::prost::alloc::string::String,
Expand Down Expand Up @@ -73,7 +73,7 @@ pub struct QueryCurrentAuctionBasketResponse {
pub struct MsgBid {
#[prost(string, tag = "1")]
pub sender: ::prost::alloc::string::String,
#[prost(message, tag = "2")]
#[prost(message, optional, tag = "2")]
pub bid_amount: ::core::option::Option<Coin>,
#[prost(uint64, tag = "3")]
pub round: u64,
Expand Down

0 comments on commit cd6221c

Please sign in to comment.