diff --git a/pool/src/auctions/backstop_interest_auction.rs b/pool/src/auctions/backstop_interest_auction.rs index 962062a1..91cb65e9 100644 --- a/pool/src/auctions/backstop_interest_auction.rs +++ b/pool/src/auctions/backstop_interest_auction.rs @@ -67,6 +67,9 @@ pub fn fill_interest_auction( ) { // bid only contains the USDC token let backstop = storage::get_backstop(e); + if filler.clone() == backstop { + panic_with_error!(e, PoolError::BadRequest); + } let usdc_token = storage::get_usdc_token(e); let usdc_bid_amount = auction_data.bid.get_unchecked(usdc_token); @@ -587,4 +590,95 @@ mod tests { assert_eq!(reserve_1_data.backstop_credit, 5_0000000); }); } + + #[test] + #[should_panic(expected = "Error(Contract, #2)")] + fn test_fill_interest_auction_with_backstop() { + let e = Env::default(); + e.mock_all_auths_allowing_non_root_auth(); + e.budget().reset_unlimited(); + + e.ledger().set(LedgerInfo { + timestamp: 12345, + protocol_version: 20, + sequence_number: 301, + network_id: Default::default(), + base_reserve: 10, + min_temp_entry_ttl: 10, + min_persistent_entry_ttl: 10, + max_entry_ttl: 2000000, + }); + + let bombadil = Address::generate(&e); + let samwise = Address::generate(&e); + + let pool_address = create_pool(&e); + + let (usdc_id, usdc_client) = testutils::create_usdc_token(&e, &pool_address, &bombadil); + let (backstop_address, _backstop_client) = testutils::create_backstop(&e); + testutils::setup_backstop( + &e, + &pool_address, + &backstop_address, + &Address::generate(&e), + &usdc_id, + &Address::generate(&e), + ); + + let (underlying_0, underlying_0_client) = testutils::create_token_contract(&e, &bombadil); + let (mut reserve_config_0, reserve_data_0) = testutils::default_reserve_meta(); + reserve_config_0.index = 0; + testutils::create_reserve( + &e, + &pool_address, + &underlying_0, + &reserve_config_0, + &reserve_data_0, + ); + underlying_0_client.mint(&pool_address, &1_000_0000000); + + let (underlying_1, underlying_1_client) = testutils::create_token_contract(&e, &bombadil); + let (mut reserve_config_1, reserve_data_1) = testutils::default_reserve_meta(); + reserve_config_1.index = 1; + testutils::create_reserve( + &e, + &pool_address, + &underlying_1, + &reserve_config_1, + &reserve_data_1, + ); + underlying_1_client.mint(&pool_address, &1_000_0000000); + + let pool_config = PoolConfig { + oracle: Address::generate(&e), + bstop_rate: 0_100_000_000, + status: 0, + max_positions: 4, + }; + let mut auction_data = AuctionData { + bid: map![&e, (usdc_id.clone(), 95_0000000)], + lot: map![ + &e, + (underlying_0.clone(), 100_0000000), + (underlying_1.clone(), 25_0000000) + ], + block: 51, + }; + usdc_client.mint(&samwise, &100_0000000); + e.as_contract(&pool_address, || { + e.mock_all_auths_allowing_non_root_auth(); + storage::set_auction( + &e, + &(AuctionType::InterestAuction as u32), + &backstop_address, + &auction_data, + ); + storage::set_pool_config(&e, &pool_config); + storage::set_backstop(&e, &backstop_address); + storage::set_usdc_token(&e, &usdc_id); + + let mut pool = Pool::load(&e); + fill_interest_auction(&e, &mut pool, &mut auction_data, &backstop_address); + }); + } } diff --git a/pool/src/auctions/bad_debt_auction.rs b/pool/src/auctions/bad_debt_auction.rs index fdbd615d..5bdb7d43 100644 --- a/pool/src/auctions/bad_debt_auction.rs +++ b/pool/src/auctions/bad_debt_auction.rs @@ -77,6 +77,9 @@ pub fn fill_bad_debt_auction( filler_state: &mut User, ) { let backstop_address = storage::get_backstop(e); + if filler_state.address == backstop_address { + panic_with_error!(e, PoolError::BadRequest); + } let mut backstop_state = User::load(e, &backstop_address); // bid only contains d_token asset amounts @@ -1065,4 +1068,128 @@ mod tests { ); }); } + + #[test] + #[should_panic(expected = "Error(Contract, #2)")] + fn test_fill_bad_debt_auction_with_backstop() { + let e = Env::default(); + e.mock_all_auths_allowing_non_root_auth(); + e.budget().reset_unlimited(); // setup exhausts budget + + e.ledger().set(LedgerInfo { + timestamp: 12345, + protocol_version: 20, + sequence_number: 51, + network_id: Default::default(), + base_reserve: 10, + min_temp_entry_ttl: 10, + min_persistent_entry_ttl: 10, + max_entry_ttl: 2000000, + }); + + let bombadil = Address::generate(&e); + let samwise = Address::generate(&e); + + let pool_address = create_pool(&e); + + let (blnd, blnd_client) = testutils::create_blnd_token(&e, &pool_address, &bombadil); + let (usdc, usdc_client) = testutils::create_usdc_token(&e, &pool_address, &bombadil); + let (lp_token, lp_token_client) = + testutils::create_comet_lp_pool(&e, &bombadil, &blnd, &usdc); + let (backstop_address, backstop_client) = testutils::create_backstop(&e); + testutils::setup_backstop( + &e, + &pool_address, + &backstop_address, + &lp_token, + &usdc, + &blnd, + ); + // mint lp tokens + blnd_client.mint(&samwise, &500_001_0000000); + blnd_client.approve(&samwise, &lp_token, &i128::MAX, &99999); + usdc_client.mint(&samwise, &12_501_0000000); + usdc_client.approve(&samwise, &lp_token, &i128::MAX, &99999); + lp_token_client.join_pool( + &50_000_0000000, + &vec![&e, 500_001_0000000, 12_501_0000000], + &samwise, + ); + backstop_client.deposit(&samwise, &pool_address, &50_000_0000000); + backstop_client.update_tkn_val(); + + 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.d_rate = 1_100_000_000; + reserve_data_0.last_time = 12345; + reserve_config_0.index = 0; + testutils::create_reserve( + &e, + &pool_address, + &underlying_0, + &reserve_config_0, + &reserve_data_0, + ); + + let (underlying_1, _) = testutils::create_token_contract(&e, &bombadil); + let (mut reserve_config_1, mut reserve_data_1) = testutils::default_reserve_meta(); + reserve_data_1.d_rate = 1_200_000_000; + reserve_data_1.last_time = 12345; + reserve_config_1.index = 1; + testutils::create_reserve( + &e, + &pool_address, + &underlying_1, + &reserve_config_1, + &reserve_data_1, + ); + + let (underlying_2, _) = testutils::create_token_contract(&e, &bombadil); + let (mut reserve_config_2, mut reserve_data_2) = testutils::default_reserve_meta(); + reserve_data_2.b_rate = 1_100_000_000; + reserve_data_2.last_time = 12345; + reserve_config_2.index = 1; + testutils::create_reserve( + &e, + &pool_address, + &underlying_2, + &reserve_config_2, + &reserve_data_2, + ); + let pool_config = PoolConfig { + oracle: Address::generate(&e), + bstop_rate: 0_100_000_000, + status: 0, + max_positions: 4, + }; + let mut auction_data = AuctionData { + bid: map![&e, (underlying_0, 10_0000000), (underlying_1, 2_5000000)], + lot: map![&e, (lp_token.clone(), 47_6000000)], + block: 51, + }; + let positions: Positions = Positions { + collateral: map![&e], + liabilities: map![ + &e, + (reserve_config_0.index, 10_0000000), + (reserve_config_1.index, 2_5000000) + ], + supply: map![&e], + }; + + e.as_contract(&pool_address, || { + storage::set_auction( + &e, + &(AuctionType::BadDebtAuction as u32), + &backstop_address, + &auction_data, + ); + storage::set_pool_config(&e, &pool_config); + storage::set_user_positions(&e, &backstop_address, &positions); + + let mut pool = Pool::load(&e); + let mut backstop_state = User::load(&e, &backstop_address); + fill_bad_debt_auction(&e, &mut pool, &mut auction_data, &mut backstop_state); + }); + } }