Skip to content

Commit

Permalink
feat: Add min_lp_to_receive in join_pool (#63)
Browse files Browse the repository at this point in the history
This PR adds a `min_lp_to_receive` parameter during `JoinPool`
execution. If the user is getting back less than the specified amount of
LP tokens back, the transaction will fail. This is useful to handle
front-running scenarios during liquidity provisions.
  • Loading branch information
abhimanyusinghgaur committed Feb 24, 2023
1 parent 6773bfb commit b6a0beb
Show file tree
Hide file tree
Showing 11 changed files with 74 additions and 91 deletions.
3 changes: 0 additions & 3 deletions contracts/pools/stable_5pool/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,11 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
QueryMsg::OnJoinPool {
assets_in,
mint_amount,
slippage_tolerance,
} => to_binary(&query_on_join_pool(
deps,
env,
assets_in,
mint_amount,
slippage_tolerance,
)?),
QueryMsg::OnExitPool {
assets_out,
Expand Down Expand Up @@ -381,7 +379,6 @@ pub fn query_on_join_pool(
env: Env,
assets_in: Option<Vec<Asset>>,
_mint_amount: Option<Uint128>,
_slippage_tolerance: Option<Decimal>,
) -> StdResult<AfterJoinResponse> {
// If the user has not provided any assets to be provided, then return a `Failure` response
if assets_in.is_none() {
Expand Down
23 changes: 6 additions & 17 deletions contracts/pools/stable_5pool/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,9 +389,8 @@ fn test_update_config() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg.clone()),
};
app.execute_contract(
Expand Down Expand Up @@ -638,7 +637,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: None,
mint_amount: Some(Uint128::from(1000_000_000u128)),
slippage_tolerance: None,
},
)
.unwrap();
Expand Down Expand Up @@ -697,7 +695,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: Some(assets_msg.clone()),
mint_amount: None,
slippage_tolerance: None,
},
)
.unwrap();
Expand Down Expand Up @@ -733,9 +730,8 @@ fn test_query_on_join_pool() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg.clone()),
};

Expand Down Expand Up @@ -1009,7 +1005,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: Some(assets_msg.clone()),
mint_amount: None,
slippage_tolerance: Some(Decimal::from_ratio(49u128, 100u128)),
},
)
.unwrap();
Expand All @@ -1020,9 +1015,8 @@ fn test_query_on_join_pool() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: Some("recipient".to_string()),
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: Some(Decimal::from_ratio(49u128, 100u128)),
assets: Some(assets_msg.clone()),
};

Expand Down Expand Up @@ -1196,7 +1190,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: Some(assets_msg.clone()),
mint_amount: None,
slippage_tolerance: Some(Decimal::from_ratio(49u128, 100u128)),
},
)
.unwrap();
Expand All @@ -1210,9 +1203,8 @@ fn test_query_on_join_pool() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: Some("recipient".to_string()),
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: Some(Decimal::from_ratio(49u128, 100u128)),
assets: Some(assets_msg.clone()),
};

Expand Down Expand Up @@ -1263,7 +1255,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: Some(assets_msg.clone()),
mint_amount: None,
slippage_tolerance: Some(Decimal::from_ratio(49u128, 100u128)),
},
)
.unwrap();
Expand Down Expand Up @@ -1341,9 +1332,8 @@ fn test_on_exit_pool() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg.clone()),
};
app.execute_contract(
Expand Down Expand Up @@ -2001,9 +1991,8 @@ fn test_swap() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg.clone()),
};
app.execute_contract(
Expand Down
3 changes: 0 additions & 3 deletions contracts/pools/weighted_pool/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,13 +271,11 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
QueryMsg::OnJoinPool {
assets_in,
mint_amount,
slippage_tolerance,
} => to_binary(&query_on_join_pool(
deps,
env,
assets_in,
mint_amount,
slippage_tolerance,
)?),
QueryMsg::OnExitPool {
assets_out,
Expand Down Expand Up @@ -386,7 +384,6 @@ pub fn query_on_join_pool(
_env: Env,
assets_in: Option<Vec<Asset>>,
_mint_amount: Option<Uint128>,
_slippage_tolerance: Option<Decimal>,
) -> StdResult<AfterJoinResponse> {

// Note - We follow the same logic as implemented by Osmosis here - https://github.com/osmosis-labs/osmosis/blob/2ce796c81664f9e983fb2a8a943818831deddfe2/x/gamm/pool-models/balancer/pool.go#L692
Expand Down
33 changes: 9 additions & 24 deletions contracts/pools/weighted_pool/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: None,
mint_amount: Some(Uint128::from(1000_000_000u128)),
slippage_tolerance: None,
},
)
.unwrap();
Expand Down Expand Up @@ -462,7 +461,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: Some(assets_msg.clone()),
mint_amount: None,
slippage_tolerance: None,
},
)
.unwrap();
Expand Down Expand Up @@ -501,9 +499,8 @@ fn test_query_on_join_pool() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg.clone()),
};

Expand Down Expand Up @@ -744,7 +741,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: Some(single_asset_msg.clone()),
mint_amount: None,
slippage_tolerance: None,
},
)
.unwrap();
Expand Down Expand Up @@ -789,9 +785,8 @@ fn test_query_on_join_pool() {
let single_join_msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(single_asset_msg.clone()),
};

Expand Down Expand Up @@ -833,7 +828,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: Some(single_asset_msg.clone()),
mint_amount: None,
slippage_tolerance: None,
},
)
.unwrap();
Expand Down Expand Up @@ -878,9 +872,8 @@ fn test_query_on_join_pool() {
let single_join_msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(single_asset_msg.clone()),
};

Expand Down Expand Up @@ -997,7 +990,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: Some(multi_asset_msg.clone()),
mint_amount: None,
slippage_tolerance: None,
},
)
.unwrap();
Expand Down Expand Up @@ -1052,9 +1044,8 @@ fn test_query_on_join_pool() {
let multi_asset_join_msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(multi_asset_msg.clone()),
};
app.execute_contract(
Expand Down Expand Up @@ -1212,7 +1203,6 @@ fn test_query_on_join_pool() {
&QueryMsg::OnJoinPool {
assets_in: Some(multi_asset_msg.clone()),
mint_amount: None,
slippage_tolerance: None,
},
)
.unwrap();
Expand Down Expand Up @@ -1265,9 +1255,8 @@ fn test_query_on_join_pool() {
let multi_asset_join_msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(multi_asset_msg.clone()),
};
app.execute_contract(
Expand Down Expand Up @@ -1350,9 +1339,8 @@ fn test_on_exit_pool() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg.clone()),
};
app.execute_contract(
Expand Down Expand Up @@ -1614,9 +1602,8 @@ fn test_swap() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg.clone()),
};
app.execute_contract(
Expand Down Expand Up @@ -2040,9 +2027,8 @@ fn test_join_pool_large_liquidity() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg.clone()),
};

Expand Down Expand Up @@ -2087,9 +2073,8 @@ fn test_join_pool_large_liquidity() {
let msg = VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(1u128),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg_large.clone()),
};

Expand Down
6 changes: 2 additions & 4 deletions contracts/router/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -661,9 +661,8 @@ fn test_router_functionality() {
&VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(stable5_pool_id),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg.clone()),
},
&[
Expand Down Expand Up @@ -720,9 +719,8 @@ fn test_router_functionality() {
&VaultExecuteMsg::JoinPool {
pool_id: Uint128::from(weighted_pool_id),
recipient: None,
lp_to_mint: None,
min_lp_to_receive: None,
auto_stake: None,
slippage_tolerance: None,
assets: Some(assets_msg.clone()),
},
&[
Expand Down
19 changes: 10 additions & 9 deletions contracts/vault/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,7 @@ pub fn execute(
pool_id,
recipient,
assets,
lp_to_mint,
slippage_tolerance,
min_lp_to_receive,
auto_stake,
} => execute_join_pool(
deps,
Expand All @@ -226,8 +225,7 @@ pub fn execute(
pool_id,
recipient,
assets,
lp_to_mint,
slippage_tolerance,
min_lp_to_receive,
auto_stake,
),
ExecuteMsg::Swap {
Expand Down Expand Up @@ -996,7 +994,7 @@ pub fn reply(deps: DepsMut, env: Env, msg: Reply) -> Result<Response, ContractEr
/// * **pool_id** is the id of the pool to be joined.
/// * **op_recipient** Optional parameter. If provided, the Vault will transfer the LP tokens to the provided address.
/// * **assets_in** Optional parameter. It is the list of assets the user is willing to provide to join the pool
/// * **lp_to_mint** Optional parameter. The number of LP tokens the user wants to get against the provided assets.
/// * **min_lp_to_receive** Optional parameter. The minimum number of LP tokens the user wants to receive against the provided assets.
/// * **auto_stake** Optional parameter. If provided, the Vault will automatically stake the provided assets with the multistaking contract.
pub fn execute_join_pool(
deps: DepsMut,
Expand All @@ -1005,8 +1003,7 @@ pub fn execute_join_pool(
pool_id: Uint128,
op_recipient: Option<String>,
assets_in: Option<Vec<Asset>>,
lp_to_mint: Option<Uint128>,
slippage_tolerance: Option<Decimal>,
min_lp_to_receive: Option<Uint128>,
auto_stake: Option<bool>,
) -> Result<Response, ContractError> {
// Read - Vault Config
Expand Down Expand Up @@ -1045,8 +1042,7 @@ pub fn execute_join_pool(
contract_addr: pool_info.pool_addr.to_string(),
msg: to_binary(&dexter::pool::QueryMsg::OnJoinPool {
assets_in,
mint_amount: lp_to_mint,
slippage_tolerance,
mint_amount: None,
})?,
}))?;

Expand All @@ -1059,6 +1055,11 @@ pub fn execute_join_pool(
return Err(ContractError::PoolQueryFailed {
error: "LP tokens to mint cannot be 0".to_string(),
});
} else if min_lp_to_receive.is_some() && pool_join_transition.new_shares.lt(&min_lp_to_receive.unwrap()) {
return Err(ContractError::MinReceiveError{
min_receive: min_lp_to_receive.unwrap(),
ask_amount: pool_join_transition.new_shares,
});
}

// Error - Number of Assets should match
Expand Down
Loading

0 comments on commit b6a0beb

Please sign in to comment.