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

Diff for audit #4

Closed
wants to merge 69 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
12b60c0
initial commit
epanchee Sep 7, 2023
1e8be22
use custom test-tube
epanchee Sep 7, 2023
7312a39
disable cw20 on instatiation;
epanchee Sep 7, 2023
c911ec3
use pool id in swap endpoint
epanchee Sep 7, 2023
fc4a6a4
refactoring
epanchee Sep 7, 2023
371bcdf
check pair is bricked if instantiated outside of factory
epanchee Sep 7, 2023
354fd5d
swap: assert provided asset belongs to the pair
epanchee Sep 11, 2023
f59988a
process lp token denom in reply
epanchee Sep 11, 2023
548f508
add tests for factory
epanchee Sep 11, 2023
d23ed5d
set 1000 OSMO as pool creation fee
epanchee Sep 12, 2023
670ee8e
add TODO
epanchee Sep 12, 2023
5cba0a7
increase factory coverage
epanchee Sep 12, 2023
b7f252c
add comment
epanchee Sep 12, 2023
9fe9e37
address Osmosis comments
epanchee Sep 13, 2023
c0ffd26
set response data in SudoMessage::SwapExactAmountIn
epanchee Sep 13, 2023
6ffe1af
reverse swap via DEX finally works!
epanchee Sep 13, 2023
3b5b584
fix osmosis fee in error
epanchee Sep 13, 2023
5289983
integration tests with Stargate messages!
epanchee Sep 14, 2023
a766c53
address clippy issues
epanchee Sep 14, 2023
7f23418
use cw-multi-test from astroport-fi
epanchee Sep 15, 2023
b9488f5
minor Stargate module refactoring
epanchee Sep 15, 2023
f1fbe2a
increase PCL code coverage
epanchee Sep 15, 2023
91fca05
refactoring
epanchee Sep 18, 2023
bef0fa1
test cw20 are not supported
epanchee Sep 18, 2023
77489af
tests refactoring
epanchee Sep 18, 2023
d59b84f
coverage for sudo SwapExactAmountOut
epanchee Sep 18, 2023
5d77770
repair copy pasted tests
epanchee Sep 18, 2023
be4037c
setup GitHub actions
epanchee Sep 18, 2023
6e09771
add Cargo.lock
epanchee Sep 18, 2023
3808a54
fix coverage gh action
epanchee Sep 18, 2023
3f9fdba
add wasm32 target in test flow
epanchee Sep 18, 2023
400676c
add fallback cache key in coverage action
epanchee Sep 18, 2023
094331e
no reason to cache data in coverage action
epanchee Sep 18, 2023
850a1c8
exclude random files in ./target dir from coverage report
epanchee Sep 18, 2023
167b2a3
disable multithreaded testing
epanchee Sep 18, 2023
6f95f01
address clippy issues
epanchee Sep 18, 2023
9d24cc7
attach coverage report in gh action
epanchee Sep 18, 2023
10effde
attach coverage report in gh action
epanchee Sep 18, 2023
ce17326
attach coverage report in gh action
epanchee Sep 18, 2023
3d0eead
build coverage reports in Xml and Html formats
epanchee Sep 18, 2023
06dfa6b
build coverage reports in Xml and Html formats
epanchee Sep 18, 2023
32dddea
resolve one TODO
epanchee Sep 18, 2023
f2e76d8
update astroport deps
epanchee Sep 19, 2023
fd6e169
remove python setup from gh action
epanchee Sep 19, 2023
a95dfe2
fix comment
epanchee Sep 20, 2023
08e84eb
disable cache always()
epanchee Sep 20, 2023
18501a2
gh actions: do not override rustc x86 target
epanchee Sep 20, 2023
d2ee1db
update gh action
epanchee Sep 20, 2023
b7df5a3
use main branch of astroport-core repo
epanchee Sep 26, 2023
e78447c
bump deps
epanchee Oct 31, 2023
058f4e0
remove deprecated calls
epanchee Oct 31, 2023
8c20ef6
dynamic pool creation fee
epanchee Oct 31, 2023
0244be3
resolve TODOs
epanchee Nov 1, 2023
d9b5035
minor optimization
epanchee Nov 1, 2023
5745a9b
export internal functions
epanchee Nov 2, 2023
811cc5f
pin testnet factory address
epanchee Nov 2, 2023
f71f0c2
bump test-tube
epanchee Nov 4, 2023
e0a996f
resolve TODOs; add PCL readme
epanchee Nov 7, 2023
716f921
address clippy issues
epanchee Nov 7, 2023
3694658
revert factory_address
epanchee Nov 7, 2023
fe012b9
e2e helper minor refactoring
epanchee Nov 10, 2023
200e188
adjust oracle query to new observation layout
epanchee Nov 13, 2023
0132415
remove spread assertion in swap_exact_amount_out
epanchee Nov 13, 2023
e990ab1
update cw-multi-test to the latest version to enable stargate
epanchee Dec 1, 2023
6fd7d4b
pull pcl updates from upstream
epanchee Dec 1, 2023
4a66e16
remove coin registry crate; rename PCL contract folder
epanchee Dec 1, 2023
b261f82
move file with factory address
epanchee Dec 1, 2023
fd18ca2
remove unused files after rebasing
epanchee Dec 1, 2023
e4df7ed
Merge branch 'preaudit_code' into diff_for_audit
epanchee Dec 1, 2023
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
Prev Previous commit
Next Next commit
address Osmosis comments
  • Loading branch information
epanchee committed Dec 1, 2023
commit 9fe9e37d568ff8b9d53d3d6bc3b1a4f504b8e3fe
6 changes: 4 additions & 2 deletions contracts/pair_pcl/src/contract.rs
Original file line number Diff line number Diff line change
@@ -230,7 +230,7 @@ pub fn execute(
max_spread,
to,
..
} => execute_swap(deps, info, offer_asset, belief_price, max_spread, to),
} => execute_swap(deps, env, info, offer_asset, belief_price, max_spread, to),
ExecuteMsg::WithdrawLiquidity { assets } => withdraw_liquidity(deps, env, info, assets),
ExecuteMsg::UpdateConfig { params } => update_config(deps, env, info, params),
ExecuteMsg::ProposeNewOwner { owner, expires_in } => {
@@ -604,6 +604,7 @@ fn withdraw_liquidity(

fn execute_swap(
deps: DepsMut,
env: Env,
info: MessageInfo,
offer_asset: Asset,
belief_price: Option<Decimal>,
@@ -622,11 +623,12 @@ fn execute_swap(
&SwapParams {
belief_price,
max_spread,
sender: info.sender,
to: addr_opt_validate(deps.api, &to)?,
},
)?;
let dispatch_swap_msg = MsgSwapExactAmountIn {
sender: info.sender.to_string(),
sender: env.contract.address.to_string(),
routes: vec![SwapAmountInRoute {
// If for some reason pool id was not set on instantiation any swap will fail which is totally safe.
// Pool contract must know its pool id in Osmosis DEX module.
4 changes: 2 additions & 2 deletions contracts/pair_pcl/src/queries.rs
Original file line number Diff line number Diff line change
@@ -151,8 +151,8 @@ pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> {
spot_price: spot_price.into(),
})
}
// TODO: PCL pools have dynamic fees which also depend on a swap size. Not sure whether we need to handle this query.
// TODO: However, Osmosis does this query prior calling sudo swap endpoint so I propose to leave default here.
// It was needed due to Osmosis legacy multi hop osmo swap fee reduction where it needs swap fee to pass into the swap interface.
// Osmosis confirmed we can safely set 0% here
QueryMsg::GetSwapFee {} => to_binary(&GetSwapFeeResponse::default()),
// TODO: there is no clear documentation how does it work
QueryMsg::IsActive {} => to_binary(&IsActiveResponse { is_active: true }),
1 change: 1 addition & 0 deletions contracts/pair_pcl/src/state.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ use cw_storage_plus::{Item, SnapshotMap};
pub struct SwapParams {
pub belief_price: Option<Decimal>,
pub max_spread: Option<Decimal>,
pub sender: Addr,
pub to: Option<Addr>,
}

15 changes: 10 additions & 5 deletions contracts/pair_pcl/src/sudo.rs
Original file line number Diff line number Diff line change
@@ -18,25 +18,29 @@ pub fn sudo(deps: DepsMut, env: Env, msg: SudoMessage) -> Result<Response, Contr
token_out_min_amount,
..
} => {
let sender = deps.api.addr_validate(&sender)?;
let mut sender = deps.api.addr_validate(&sender)?;
let offer_asset = native_asset_info(token_in.denom).with_balance(token_in.amount);

let mut belief_price = Some(Decimal::from_ratio(token_in.amount, token_out_min_amount));
// TODO: I assume Osmosis applies slippage on frontend side hence we won't disrupt
// TODO: this logic with our additional default 0.02% slippage tolerance
// Osmosis applies slippage on their frontend side hence we won't disrupt
// this logic with our additional default 0.02% slippage tolerance.
let mut max_spread = Some(Decimal::zero());
let mut to = None;
// If swap was dispatched from Astroport pair it must have SWAP_PARAMS in the storage
if let Some(swap_params) = SWAP_PARAMS.may_load(deps.storage)? {
belief_price = swap_params.belief_price;
max_spread = swap_params.max_spread;
sender = swap_params.sender;
to = swap_params.to;
// Remove params so they won't be used if SwapExactAmountIn is called directly from DEX module

// Remove params so they won't be used if SwapExactAmountIn is called directly from the DEX module
SWAP_PARAMS.remove(deps.storage);
}

let response_data = to_binary(&SwapExactAmountInResponseData {
token_out_amount: 1u8.into(), // TODO: does it matter if we send tokens ourselves?
// TODO: extract amount from the response. Osmosis: "It’s needed in case of multi pool swap routing"
// https://github.com/osmosis-labs/osmosis/blob/294302637a47ffec5cafc0c1953e88a54390b20e/x/poolmanager/router.go#L102C3-L113
token_out_amount: 1u8.into(),
})?;
internal_swap(deps, env, sender, offer_asset, belief_price, max_spread, to).map(|res| {
res.add_attribute("method", "swap_exact_amount_in")
@@ -45,6 +49,7 @@ pub fn sudo(deps: DepsMut, env: Env, msg: SudoMessage) -> Result<Response, Contr
}
SudoMessage::SwapExactAmountOut { .. } => {
todo!("Unsafe function! Osmosis doesn't pull out expected coins from sender balance!")
// TODO: implement according to internal Osmosis logic described here https://github.com/osmosis-labs/osmosis/blob/294302637a47ffec5cafc0c1953e88a54390b20e/x/cosmwasmpool/pool_module.go#L272-L324
/*let sender = deps.api.addr_validate(&sender)?;
let ask_asset = native_asset_info(token_out.denom).with_balance(token_out.amount);

23 changes: 11 additions & 12 deletions e2e_tests/tests/e2e_testing.rs
Original file line number Diff line number Diff line change
@@ -129,6 +129,17 @@ fn dex_swap_test() {
assert_eq!(bar_bal, 0);
assert_eq!(foo_bal, 994806);

// Direct swap via pair contract FOO -> BAR (which essentially proxies it to DEX module)
let asset = foo.with_balance(foo_bal);
helper
.swap_on_pair(&user, &pair_addr, &asset, None)
.unwrap();

let foo_bal = helper.coin_balance(&user.address().to_string(), &foo_denom);
let bar_bal = helper.coin_balance(&user.address().to_string(), &bar_denom);
assert_eq!(foo_bal, 0);
assert_eq!(bar_bal, 1984437);

// TODO: this DEX endpoint is harmful!
// Reverse swap via DEX: FOO -> BAR
// let asset = foo.with_balance(1_000000u128);
@@ -143,18 +154,6 @@ fn dex_swap_test() {
// let foo_bal = helper.coin_balance(&user2.address().to_string(), &foo_denom);
// let bar_bal = helper.coin_balance(&user2.address().to_string(), &bar_denom);
// dbg!(foo_bal, bar_bal);

// Direct swap via pair contract FOO -> BAR (which essentially proxies it to DEX module)
// TODO: currently throws an error "failed to execute message; message index: 0: dispatch: submessages: contract doesn't have permission: unauthorized"
// let asset = foo.with_balance(foo_bal);
// helper
// .swap_on_pair(&user, &pair_addr, &asset, None)
// .unwrap();
//
// let foo_bal = helper.coin_balance(&user.address().to_string(), &foo_denom);
// let bar_bal = helper.coin_balance(&user.address().to_string(), &bar_denom);
// assert_eq!(foo_bal, 0);
// assert_eq!(bar_bal, 1984437);
}

#[test]