From d58d669b60e7864214b17245c9afce7ffad1f6b4 Mon Sep 17 00:00:00 2001 From: mootz12 Date: Sun, 31 Dec 2023 10:32:03 -0500 Subject: [PATCH] backstop: chore: add payer and payee sanity checks to deposit and donate --- backstop/src/backstop/deposit.rs | 51 +++++++++- backstop/src/backstop/fund_management.rs | 115 ++++++++++++++++++++++- 2 files changed, 163 insertions(+), 3 deletions(-) diff --git a/backstop/src/backstop/deposit.rs b/backstop/src/backstop/deposit.rs index 482cea65..6f914c92 100644 --- a/backstop/src/backstop/deposit.rs +++ b/backstop/src/backstop/deposit.rs @@ -1,12 +1,15 @@ -use crate::{contract::require_nonnegative, emissions, storage}; +use crate::{contract::require_nonnegative, emissions, storage, BackstopError}; use sep_41_token::TokenClient; -use soroban_sdk::{Address, Env}; +use soroban_sdk::{panic_with_error, Address, Env}; use super::require_is_from_pool_factory; /// Perform a deposit into the backstop module pub fn execute_deposit(e: &Env, from: &Address, pool_address: &Address, amount: i128) -> i128 { require_nonnegative(e, amount); + if from == pool_address || from == &e.current_contract_address() { + panic_with_error!(e, &BackstopError::BadRequest) + } let mut pool_balance = storage::get_pool_balance(e, pool_address); require_is_from_pool_factory(e, pool_address, pool_balance.shares); let mut user_balance = storage::get_user_balance(e, pool_address, from); @@ -141,6 +144,50 @@ mod tests { }); } + #[test] + #[should_panic(expected = "Error(Contract, #1)")] + fn test_execute_deposit_from_is_to() { + let e = Env::default(); + e.mock_all_auths_allowing_non_root_auth(); + + let backstop_address = create_backstop(&e); + let pool_0_id = Address::generate(&e); + let bombadil = Address::generate(&e); + let samwise = Address::generate(&e); + + let (_, backstop_token_client) = create_backstop_token(&e, &backstop_address, &bombadil); + backstop_token_client.mint(&samwise, &100_0000000); + + let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_address); + mock_pool_factory_client.set_pool(&pool_0_id); + + e.as_contract(&backstop_address, || { + execute_deposit(&e, &pool_0_id, &pool_0_id, 100); + }); + } + + #[test] + #[should_panic(expected = "Error(Contract, #1)")] + fn test_execute_deposit_from_self() { + let e = Env::default(); + e.mock_all_auths_allowing_non_root_auth(); + + let backstop_address = create_backstop(&e); + let pool_0_id = Address::generate(&e); + let bombadil = Address::generate(&e); + let samwise = Address::generate(&e); + + let (_, backstop_token_client) = create_backstop_token(&e, &backstop_address, &bombadil); + backstop_token_client.mint(&samwise, &100_0000000); + + let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_address); + mock_pool_factory_client.set_pool(&pool_0_id); + + e.as_contract(&backstop_address, || { + execute_deposit(&e, &pool_0_id, &pool_0_id, 100); + }); + } + #[test] #[should_panic(expected = "Error(Contract, #10)")] fn text_execute_deposit_not_pool() { diff --git a/backstop/src/backstop/fund_management.rs b/backstop/src/backstop/fund_management.rs index 148b0598..32ea9a18 100644 --- a/backstop/src/backstop/fund_management.rs +++ b/backstop/src/backstop/fund_management.rs @@ -1,9 +1,10 @@ use crate::{ constants::SCALAR_7, contract::require_nonnegative, dependencies::CometClient, storage, + BackstopError, }; use sep_41_token::TokenClient; use soroban_fixed_point_math::FixedPoint; -use soroban_sdk::{unwrap::UnwrapOptimized, Address, Env}; +use soroban_sdk::{panic_with_error, unwrap::UnwrapOptimized, Address, Env}; use super::require_is_from_pool_factory; @@ -23,6 +24,9 @@ pub fn execute_draw(e: &Env, pool_address: &Address, amount: i128, to: &Address) /// Perform a donation to a pool's backstop pub fn execute_donate(e: &Env, from: &Address, pool_address: &Address, amount: i128) { require_nonnegative(e, amount); + if from == pool_address || from == &e.current_contract_address() { + panic_with_error!(e, &BackstopError::BadRequest) + } let mut pool_balance = storage::get_pool_balance(e, pool_address); require_is_from_pool_factory(e, pool_address, pool_balance.shares); @@ -37,6 +41,9 @@ pub fn execute_donate(e: &Env, from: &Address, pool_address: &Address, amount: i /// Perform a donation of USDC to a pool's backstop pub fn execute_donate_usdc(e: &Env, from: &Address, pool_address: &Address, amount: i128) { require_nonnegative(e, amount); + if from == pool_address || from == &e.current_contract_address() { + panic_with_error!(e, &BackstopError::BadRequest) + } let mut pool_usdc = storage::get_pool_usdc(e, pool_address); require_is_from_pool_factory(e, pool_address, pool_usdc); @@ -172,6 +179,66 @@ mod tests { }); } + #[test] + #[should_panic(expected = "Error(Contract, #1)")] + fn test_execute_donate_from_is_to() { + let e = Env::default(); + e.mock_all_auths_allowing_non_root_auth(); + e.budget().reset_unlimited(); + + let backstop_id = create_backstop(&e); + let pool_0_id = Address::generate(&e); + let bombadil = Address::generate(&e); + let samwise = Address::generate(&e); + let frodo = Address::generate(&e); + + let (_, backstop_token_client) = create_backstop_token(&e, &backstop_id, &bombadil); + backstop_token_client.mint(&samwise, &100_0000000); + backstop_token_client.mint(&frodo, &100_0000000); + + let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_id); + mock_pool_factory_client.set_pool(&pool_0_id); + + // initialize pool 0 with funds + e.as_contract(&backstop_id, || { + execute_deposit(&e, &frodo, &pool_0_id, 25_0000000); + }); + + e.as_contract(&backstop_id, || { + execute_donate(&e, &pool_0_id, &pool_0_id, 10_0000000); + }); + } + + #[test] + #[should_panic(expected = "Error(Contract, #1)")] + fn test_execute_donate_from_is_self() { + let e = Env::default(); + e.mock_all_auths_allowing_non_root_auth(); + e.budget().reset_unlimited(); + + let backstop_id = create_backstop(&e); + let pool_0_id = Address::generate(&e); + let bombadil = Address::generate(&e); + let samwise = Address::generate(&e); + let frodo = Address::generate(&e); + + let (_, backstop_token_client) = create_backstop_token(&e, &backstop_id, &bombadil); + backstop_token_client.mint(&samwise, &100_0000000); + backstop_token_client.mint(&frodo, &100_0000000); + + let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_id); + mock_pool_factory_client.set_pool(&pool_0_id); + + // initialize pool 0 with funds + e.as_contract(&backstop_id, || { + execute_deposit(&e, &frodo, &pool_0_id, 25_0000000); + }); + + e.as_contract(&backstop_id, || { + execute_donate(&e, &backstop_id, &pool_0_id, 10_0000000); + }); + } + #[test] #[should_panic(expected = "Error(Contract, #10)")] fn test_execute_donate_not_pool() { @@ -348,6 +415,52 @@ mod tests { }); } + #[test] + #[should_panic(expected = "Error(Contract, #1)")] + fn test_execute_donate_usdc_from_is_to() { + let e = Env::default(); + e.mock_all_auths_allowing_non_root_auth(); + e.budget().reset_unlimited(); + + let backstop_id = create_backstop(&e); + let pool_0_id = Address::generate(&e); + let bombadil = Address::generate(&e); + let samwise = Address::generate(&e); + + let (_, usdc_token_client) = create_usdc_token(&e, &backstop_id, &bombadil); + usdc_token_client.mint(&samwise, &100_0000000); + + let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_id); + mock_pool_factory_client.set_pool(&pool_0_id); + + e.as_contract(&backstop_id, || { + execute_donate_usdc(&e, &pool_0_id, &pool_0_id, 10_0000000); + }); + } + + #[test] + #[should_panic(expected = "Error(Contract, #1)")] + fn test_execute_donate_usdc_from_is_self() { + let e = Env::default(); + e.mock_all_auths_allowing_non_root_auth(); + e.budget().reset_unlimited(); + + let backstop_id = create_backstop(&e); + let pool_0_id = Address::generate(&e); + let bombadil = Address::generate(&e); + let samwise = Address::generate(&e); + + let (_, usdc_token_client) = create_usdc_token(&e, &backstop_id, &bombadil); + usdc_token_client.mint(&samwise, &100_0000000); + + let (_, mock_pool_factory_client) = create_mock_pool_factory(&e, &backstop_id); + mock_pool_factory_client.set_pool(&pool_0_id); + + e.as_contract(&backstop_id, || { + execute_donate_usdc(&e, &backstop_id, &pool_0_id, 10_0000000); + }); + } + #[test] #[should_panic(expected = "Error(Contract, #10)")] fn test_execute_donate_usdc_not_pool() {