Skip to content

Commit

Permalink
fix(smart-contracts): fix bug to let users exit pool after auction is…
Browse files Browse the repository at this point in the history
… over
  • Loading branch information
nseguias committed Mar 7, 2024
1 parent 604f283 commit f43502b
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 7 deletions.
2 changes: 1 addition & 1 deletion contracts/injective-auction-pool/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use cosmwasm_std::{Decimal, Instantiate2AddressError, OverflowError, StdError};
use cw_utils::PaymentError;
use thiserror::Error;

#[derive(Error, Debug)]
#[derive(Error, Debug, PartialEq)]
pub enum ContractError {
#[error("{0}")]
Std(#[from] StdError),
Expand Down
8 changes: 5 additions & 3 deletions contracts/injective-auction-pool/src/executions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,14 @@ pub(crate) fn exit_pool(

// prevents the user from exiting the pool in the last day of the auction
if current_auction_round_response
.auction_closing_time
.ok_or(ContractError::CurrentAuctionQueryError)?
.auction_closing_time()
.saturating_sub(env.block.time.seconds())
< DAY_IN_SECONDS
&& env.block.time.seconds() < current_auction_round_response.auction_closing_time()
{
return Err(ContractError::PooledAuctionLocked);
{
return Err(ContractError::PooledAuctionLocked);
}
}

// subtract the amount of INJ to send from the bidding balance
Expand Down
98 changes: 95 additions & 3 deletions contracts/injective-auction-pool/src/tests/test_helpers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::marker::PhantomData;

use cosmwasm_std::testing::{mock_env, mock_info, BankQuerier, MockApi, MockStorage};
use cosmwasm_std::testing::{
mock_env, mock_info, BankQuerier, MockApi, MockStorage, MOCK_CONTRACT_ADDR,
};
use cosmwasm_std::{
attr, coins, from_json, to_json_binary, BankMsg, Binary, ContractResult as CwContractResult,
CosmosMsg, Decimal, Empty, Env, MemoryStorage, MessageInfo, OwnedDeps, Querier, QuerierResult,
Expand All @@ -12,6 +14,7 @@ use treasurechest::tf::tokenfactory::TokenFactoryType;

use crate::contract::{execute, instantiate};
use crate::state::BIDDING_BALANCE;
use crate::ContractError;

pub struct AuctionQuerier {
bank: BankQuerier,
Expand Down Expand Up @@ -41,7 +44,8 @@ impl Querier for AuctionQuerier {
amount: "10000".to_string(),
}],
auction_round: Some(1),
auction_closing_time: Some(10_000_000),
// simulates now + 7 days in seconds
auction_closing_time: Some(1_571_797_419 + 7 * 86_400),
highest_bidder: Some("highest_bidder".to_string()),
highest_bid_amount: Some("20000".to_string()),
})
Expand Down Expand Up @@ -147,6 +151,7 @@ pub fn user_joins_pool() {
})
);

// checking attributes are fine
assert_eq!(
res.attributes,
vec![
Expand All @@ -157,6 +162,93 @@ pub fn user_joins_pool() {
]
);

// contract balance should be 100
// bidding balance should now be 100
assert_eq!(BIDDING_BALANCE.load(&deps.storage).unwrap(), Uint128::from(100u128));
}

#[test]
fn user_exit_pool_works() {
let (mut deps, env) = init();

let info = mock_info("robinho", &coins(100, "native_denom"));
let msg = ExecuteMsg::JoinPool {
auction_round: 1,
basket_value: Uint128::from(10_000u128),
};
let _ = execute(deps.as_mut().branch(), env.clone(), info, msg).unwrap();

let info = mock_info("robinho", &coins(100, format!("factory/{}/1", env.contract.address)));
let msg = ExecuteMsg::ExitPool {};

let res = execute(deps.as_mut().branch(), env.clone(), info, msg).unwrap();

// contract burns 100 lp tokens from the user
assert_eq!(
res.messages[0].msg,
TokenFactoryType::Injective.burn(
env.contract.address.clone(),
format!("factory/{}/1", env.contract.address).as_str(),
Uint128::from(100u128),
)
);

// contract returns 100 native_denom to the user
assert_eq!(
res.messages[1].msg,
BankMsg::Send {
to_address: "robinho".to_string(),
amount: coins(100, "native_denom"),
}
.into()
);

// checking attributes are fine
assert_eq!(res.attributes, vec![attr("action", "exit_pool")]);
}

#[test]
fn user_exit_pool_fails() {
let (mut deps, mut env) = init();

let info = mock_info("robinho", &coins(100, "native_denom"));
let msg = ExecuteMsg::JoinPool {
auction_round: 1,
basket_value: Uint128::from(10_000u128),
};
let _ = execute(deps.as_mut().branch(), env.clone(), info, msg).unwrap();

let info = mock_info("robinho", &coins(100, format!("factory/{}/1", env.contract.address)));
let msg = ExecuteMsg::ExitPool {};

// move time to 6 days later (1+ day before auction ends)
env.block.time = env.block.time.plus_seconds(6 * 86_400 + 1);

let res = execute(deps.as_mut().branch(), env.clone(), info.clone(), msg.clone()).unwrap_err();

// contract burns 100 lp tokens from the user
assert_eq!(res, ContractError::PooledAuctionLocked {});

// move time one more day, should be able to exit now
env.block.time = env.block.time.plus_seconds(86_400);

let res = execute(deps.as_mut().branch(), env.clone(), info, msg).unwrap();
assert_eq!(
res.messages[0].msg,
TokenFactoryType::Injective.burn(
env.contract.address.clone(),
format!("factory/{}/1", env.contract.address).as_str(),
Uint128::from(100u128),
)
);

assert_eq!(
res.messages[1].msg,
BankMsg::Send {
to_address: "robinho".to_string(),
amount: coins(100, "native_denom"),
}
.into()
);

assert_eq!(res.attributes, vec![attr("action", "exit_pool")]);
}

0 comments on commit f43502b

Please sign in to comment.