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

Include auction assets #19

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
260 changes: 180 additions & 80 deletions pool/src/auctions/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,79 +38,58 @@ impl AuctionType {
#[derive(Clone)]
#[contracttype]
pub struct AuctionData {
/// A map of the assets being bid on and the amount being bid. These are tokens spent
/// by the filler of the auction.
///
/// The bid is different based on each auction type:
/// - UserLiquidation: dTokens
/// - BadDebtAuction: dTokens
/// - InterestAuction: Underlying assets (backstop token)
pub bid: Map<Address, i128>,
/// A map of the assets being auctioned off and the amount being auctioned. These are tokens
/// received by the filler of the auction.
///
/// The lot is different based on each auction type:
/// - UserLiquidation: bTokens
/// - BadDebtAuction: Underlying assets (backstop token)
/// - InterestAuction: Underlying assets
pub lot: Map<Address, i128>,
/// The block the auction begins on. This is used to determine how the auction
/// should be scaled based on the number of blocks that have passed since the auction began.
pub block: u32,
}

/// Create a bad debt auction. Stores the resulting auction to the ledger to begin on the next block
/// Create a new auction. Stores the resulting auction to the ledger to begin on the next block.
///
/// Returns the AuctionData object created.
///
/// ### Panics
/// If the auction is unable to be created
pub fn create_bad_debt_auction(e: &Env) -> AuctionData {
let backstop = storage::get_backstop(e);
let auction_data = create_bad_debt_auction_data(e, &backstop);

storage::set_auction(
e,
&(AuctionType::BadDebtAuction as u32),
&backstop,
&auction_data,
);

auction_data
}

/// Create an interest auction. Stores the resulting auction to the ledger to begin on the next block
///
/// Returns the AuctionData object created.
///
/// ### Arguments
/// * `assets` - The assets interest is being auctioned off from
///
/// ### Panics
/// If the auction is unable to be created
pub fn create_interest_auction(e: &Env, assets: &Vec<Address>) -> AuctionData {
let backstop = storage::get_backstop(e);
let auction_data = create_interest_auction_data(e, &backstop, assets);

storage::set_auction(
e,
&(AuctionType::InterestAuction as u32),
&backstop,
&auction_data,
);

auction_data
}

/// Create a liquidation auction. Stores the resulting auction to the ledger to begin on the next block
///
/// Returns the AuctionData object created.
/// Returns the AuctionData object created
///
/// ### Arguments
/// * `user` - The user being liquidated
/// * `liq_data` - The liquidation metadata
/// * `auction_type` - The type of auction being created
/// * `user` - The user involved in the auction
/// * `bid` - The assets being bid on
/// * `lot` - The assets being auctioned off
/// * `percent` - The percentage of the user's positions being liquidated
///
/// ### Panics
/// If the auction is unable to be created
pub fn create_liquidation(e: &Env, user: &Address, percent_liquidated: u64) -> AuctionData {
let user_clone = user.clone();
if user_clone == e.current_contract_address() || user_clone == storage::get_backstop(e) {
panic_with_error!(e, PoolError::InvalidLiquidation);
}

let auction_data = create_user_liq_auction_data(e, user, percent_liquidated);

storage::set_auction(
e,
&(AuctionType::UserLiquidation as u32),
user,
&auction_data,
);

/// * If the max positions are exceeded
/// * If the user and percent are invalid for the auction type
/// * If the auction is unable to be created
pub fn create_auction(
e: &Env,
auction_type: u32,
user: &Address,
bid: &Vec<Address>,
lot: &Vec<Address>,
percent: u32,
) -> AuctionData {
// panics if auction_type parameter is not valid
let auction_type_enum = AuctionType::from_u32(e, auction_type);
let auction_data = match auction_type_enum {
AuctionType::UserLiquidation => create_user_liq_auction_data(e, user, bid, lot, percent),
AuctionType::BadDebtAuction => create_bad_debt_auction_data(e, user, bid, lot, percent),
AuctionType::InterestAuction => create_interest_auction_data(e, user, bid, lot, percent),
};
storage::set_auction(e, &auction_type, user, &auction_data);
auction_data
}

Expand Down Expand Up @@ -383,9 +362,9 @@ mod tests {
&Asset::Other(Symbol::new(&e, "USD1")),
&vec![
&e,
Asset::Stellar(underlying_0),
Asset::Stellar(underlying_1),
Asset::Stellar(underlying_2),
Asset::Stellar(underlying_0.clone()),
Asset::Stellar(underlying_1.clone()),
Asset::Stellar(underlying_2.clone()),
Asset::Stellar(usdc),
Asset::Stellar(blnd),
],
Expand Down Expand Up @@ -421,7 +400,14 @@ mod tests {
storage::set_pool_config(&e, &pool_config);
storage::set_user_positions(&e, &backstop_address, &positions);

create_bad_debt_auction(&e);
create_auction(
&e,
1,
&backstop_address,
&vec![&e, underlying_0, underlying_1],
&vec![&e, lp_token],
100,
);
assert!(storage::has_auction(&e, &1, &backstop_address));
});
}
Expand Down Expand Up @@ -530,7 +516,14 @@ mod tests {
e.as_contract(&pool_address, || {
storage::set_pool_config(&e, &pool_config);

create_interest_auction(&e, &vec![&e, underlying_0, underlying_1]);
create_auction(
&e,
2,
&backstop_address,
&vec![&e, backstop_token_id],
&vec![&e, underlying_0, underlying_1],
100,
);
assert!(storage::has_auction(&e, &2, &backstop_address));
});
}
Expand Down Expand Up @@ -607,9 +600,9 @@ mod tests {
&Asset::Other(Symbol::new(&e, "USD")),
&vec![
&e,
Asset::Stellar(underlying_0),
Asset::Stellar(underlying_1),
Asset::Stellar(underlying_2),
Asset::Stellar(underlying_0.clone()),
Asset::Stellar(underlying_1.clone()),
Asset::Stellar(underlying_2.clone()),
],
&7,
&300,
Expand Down Expand Up @@ -638,7 +631,14 @@ mod tests {
storage::set_pool_config(&e, &pool_config);

e.budget().reset_unlimited();
create_liquidation(&e, &samwise, liq_pct);
create_auction(
&e,
0,
&samwise,
&vec![&e, underlying_2],
&vec![&e, underlying_0, underlying_1],
liq_pct,
);
assert!(storage::has_auction(&e, &0, &samwise));
});
}
Expand Down Expand Up @@ -713,9 +713,9 @@ mod tests {
&Asset::Other(Symbol::new(&e, "USD")),
&vec![
&e,
Asset::Stellar(underlying_0),
Asset::Stellar(underlying_1),
Asset::Stellar(underlying_2),
Asset::Stellar(underlying_0.clone()),
Asset::Stellar(underlying_1.clone()),
Asset::Stellar(underlying_2.clone()),
],
&7,
&300,
Expand Down Expand Up @@ -743,7 +743,14 @@ mod tests {
storage::set_user_positions(&e, &pool_address, &positions);
storage::set_pool_config(&e, &pool_config);

create_liquidation(&e, &pool_address, liq_pct);
create_auction(
&e,
0,
&pool_address,
&vec![&e, underlying_2],
&vec![&e, underlying_0, underlying_1],
liq_pct,
);
});
}

Expand Down Expand Up @@ -818,9 +825,9 @@ mod tests {
&Asset::Other(Symbol::new(&e, "USD")),
&vec![
&e,
Asset::Stellar(underlying_0),
Asset::Stellar(underlying_1),
Asset::Stellar(underlying_2),
Asset::Stellar(underlying_0.clone()),
Asset::Stellar(underlying_1.clone()),
Asset::Stellar(underlying_2.clone()),
],
&7,
&300,
Expand Down Expand Up @@ -848,7 +855,100 @@ mod tests {
storage::set_user_positions(&e, &backstop, &positions);
storage::set_pool_config(&e, &pool_config);

create_liquidation(&e, &backstop, liq_pct);
create_auction(
&e,
0,
&backstop,
&vec![&e, underlying_2],
&vec![&e, underlying_0, underlying_1],
liq_pct,
);
});
}

#[test]
#[should_panic(expected = "Error(Contract, #1200)")]
fn test_create_auction_invalid_type() {
let e = Env::default();
e.mock_all_auths();
e.budget().reset_unlimited(); // setup exhausts budget

e.ledger().set(LedgerInfo {
timestamp: 12345,
protocol_version: 22,
sequence_number: 50,
network_id: Default::default(),
base_reserve: 10,
min_temp_entry_ttl: 10,
min_persistent_entry_ttl: 10,
max_entry_ttl: 3110400,
});

let bombadil = Address::generate(&e);

let pool_address = create_pool(&e);
let (usdc_id, _) = testutils::create_token_contract(&e, &bombadil);
let (blnd_id, _) = testutils::create_blnd_token(&e, &pool_address, &bombadil);

let (backstop_token_id, _) = create_comet_lp_pool(&e, &bombadil, &blnd_id, &usdc_id);
let (backstop_address, backstop_client) = testutils::create_backstop(&e);
testutils::setup_backstop(
&e,
&pool_address,
&backstop_address,
&backstop_token_id,
&usdc_id,
&blnd_id,
);
backstop_client.deposit(&bombadil, &pool_address, &(50 * SCALAR_7));
backstop_client.update_tkn_val();
let (oracle_id, oracle_client) = testutils::create_mock_oracle(&e);

let (underlying_0, _) = testutils::create_token_contract(&e, &bombadil);
let (mut reserve_config_0, mut reserve_data_0) = testutils::default_reserve_meta();
reserve_data_0.last_time = 12345;
reserve_data_0.backstop_credit = 200_0000000;
reserve_data_0.b_supply = 1000_0000000;
reserve_data_0.d_supply = 750_0000000;
reserve_config_0.index = 0;
testutils::create_reserve(
&e,
&pool_address,
&underlying_0,
&reserve_config_0,
&reserve_data_0,
);

oracle_client.set_data(
&bombadil,
&Asset::Other(Symbol::new(&e, "USD")),
&vec![
&e,
Asset::Stellar(underlying_0.clone()),
Asset::Stellar(usdc_id),
],
&7,
&300,
);
oracle_client.set_price_stable(&vec![&e, 2_0000000, 1_0000000]);

let pool_config = PoolConfig {
oracle: oracle_id,
bstop_rate: 0_1000000,
status: 0,
max_positions: 4,
};
e.as_contract(&pool_address, || {
storage::set_pool_config(&e, &pool_config);

create_auction(
&e,
3,
&backstop_address,
&vec![&e, backstop_token_id],
&vec![&e, underlying_0],
100,
);
});
}

Expand Down
Loading
Loading