diff --git a/contracts/pool-manager/src/manager/commands.rs b/contracts/pool-manager/src/manager/commands.rs index cdee583..d549306 100644 --- a/contracts/pool-manager/src/manager/commands.rs +++ b/contracts/pool-manager/src/manager/commands.rs @@ -75,6 +75,12 @@ pub fn create_pool( // Load config for pool creation fee let config: Config = CONFIG.load(deps.storage)?; + // Ensure that the number of assets and decimals match, and that the number of assets is within the allowed range + ensure!( + asset_denoms.len() == asset_decimals.len() && asset_denoms.len() <= MAX_ASSETS_PER_POOL, + ContractError::AssetMismatch + ); + // check if the pool and token factory fees were paid validate_fees_are_paid( &config.pool_creation_fee, diff --git a/contracts/pool-manager/src/tests/integration_tests.rs b/contracts/pool-manager/src/tests/integration_tests.rs index e1e985e..df7490c 100644 --- a/contracts/pool-manager/src/tests/integration_tests.rs +++ b/contracts/pool-manager/src/tests/integration_tests.rs @@ -5170,4 +5170,125 @@ mod multiple_pools { }, ); } + + #[test] + fn cant_create_pool_with_large_number_of_assets() { + let mut suite = TestingSuite::default_with_balances( + vec![ + coin(1_000_000_000u128, "uusdy".to_string()), + coin(1_000_000_000u128, "uusdc".to_string()), + coin(1_000_000_000u128, "uusdt".to_string()), + coin(1_000_000_000u128, "uusd".to_string()), + coin(1_000_000_000u128, "uom".to_string()), + ], + StargateMock::new("uom".to_string(), "8888".to_string()), + ); + let creator = suite.creator(); + + // Asset denoms with uwhale and uluna + let asset_denoms = vec![ + "uusdy".to_string(), + "uusdc".to_string(), + "uusdt".to_string(), + "uusd".to_string(), + ]; + + let pool_fees = PoolFee { + protocol_fee: Fee { + share: Decimal::percent(10), + }, + swap_fee: Fee { + share: Decimal::percent(7), + }, + burn_fee: Fee { + share: Decimal::percent(3), + }, + extra_fees: vec![], + }; + + // Create pools + suite + .instantiate_default() + .add_one_epoch() + .create_pool( + &creator, + asset_denoms.clone(), + vec![6u8, 6u8], + pool_fees.clone(), + PoolType::StableSwap { amp: 80 }, + Some("stableswap".to_string()), + vec![coin(1000, "uusd"), coin(8888, "uom")], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::AssetMismatch { .. } => {} + _ => { + panic!("Wrong error type, should return ContractError::AssetMismatch") + } + } + }, + ) + .create_pool( + &creator, + asset_denoms.clone(), + vec![6u8, 6u8, 6u8], + pool_fees.clone(), + PoolType::StableSwap { amp: 80 }, + Some("stableswap".to_string()), + vec![coin(1000, "uusd"), coin(8888, "uom")], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::AssetMismatch { .. } => {} + _ => { + panic!("Wrong error type, should return ContractError::AssetMismatch") + } + } + }, + ) + .create_pool( + &creator, + vec![ + "uusdy".to_string(), + "uusdc".to_string(), + "uusdt".to_string(), + "uusd".to_string(), + "uom".to_string(), + ], + vec![6u8, 6u8, 6u8, 6u8, 6u8], + pool_fees.clone(), + PoolType::StableSwap { amp: 80 }, + Some("stableswap".to_string()), + vec![coin(1000, "uusd"), coin(8888, "uom")], + |result| { + let err = result.unwrap_err().downcast::().unwrap(); + + match err { + ContractError::AssetMismatch { .. } => {} + _ => { + panic!("Wrong error type, should return ContractError::AssetMismatch") + } + } + }, + ) + .create_pool( + &creator, + vec![ + "uusdy".to_string(), + "uusdc".to_string(), + "uusdt".to_string(), + "uusd".to_string(), + ], + vec![6u8, 6u8, 6u8, 6u8], + pool_fees.clone(), + PoolType::StableSwap { amp: 80 }, + Some("stableswap".to_string()), + vec![coin(1000, "uusd"), coin(8888, "uom")], + |result| { + result.unwrap(); + }, + ); + } }