@@ -8,10 +8,6 @@ native mulDiv(a: Int, b: Int, c: Int): Int;
88@name (fill_zeros)
99native fillZerosCheckLen (jetton_wallets : map <Address , Address >, want_len : Int ): map <Address , Int >;
1010
11- @name (load_msg_addr)
12- extends mutates native loadAddress (self : Slice ): Address ;
13- // SAFETY: doesn't check if address is std-type
14-
1511
1612
1713message DexDeploy {
@@ -45,8 +41,7 @@ struct SystemInfo {
4541 owner_address : Address ;
4642}
4743
48- // swap#4a2663c4 otherJettonMaster:MsgAddressInt = Swap;
49- // TODO (see below): add also otherJettonMinExpected:(VarUInteger 16)
44+ // swap#4a2663c4 other_jetton_master:MsgAddressInt other_jetton_min_expected:(VarUInteger 16) = Swap;
5045// the problem is that Tact doesn't support parsing slices as arbitrary structs
5146
5247
@@ -111,19 +106,29 @@ contract MultitokenDex {
111106 if (swap .loadUint (32 ) != 0x4a2663c4 ) {
112107 self .transferJettonTo (ctx .sender , msg .sender , received ,
113108 msg .query_id , " Unknown operation" );
109+ return ;
114110 }
115- // SAFETY: we test whether provided address is among listed jetton masters
116- // it can fail due to invalid key length, but that's hard to achieve and doesn't harm DEX
117- let otherJettonMaster : Address = swap .loadAddress ();
118-
111+ let other_jetton_master : Address = swap .loadAddress ();
112+ let other_jetton_min_expected : Int = swap .loadCoins ();
119113
120- let other_jw : Address = self .jetton_wallets .get (otherJettonMaster )!! ;
114+ let other_jw : Address = self .jetton_wallets .get (other_jetton_master )!! ;
121115 let old_balance_dst : Int = self .assets .get (other_jw )!! ;
116+ if (other_jetton_min_expected >= old_balance_dst ) {
117+ self .transferJettonTo (ctx .sender , msg .sender , received ,
118+ msg .query_id , " Liquidity pool doesn't have enough funds" );
119+ return ;
120+ }
121+ // now, other_jetton_min_expected <= old_balance_dst - 1
122122
123123 let swap_value : Int = self .calc_swap (old_balance_src !! , old_balance_dst , received );
124-
125- // TODO safeguard against slippage: paying attention to otherJettonMinExpected
126- // TODO safeguard against liquidity pool draining
124+ if (swap_value >= old_balance_dst ) { // safeguard against liquidity pool draining
125+ swap_value = old_balance_dst - 1 ; // still above other_jetton_min_expected, though we still check this next
126+ }
127+ if (swap_value < other_jetton_min_expected ) {
128+ self .transferJettonTo (ctx .sender , msg .sender , received ,
129+ msg .query_id , " Slippage protection: swap can't give requested count of tokens" );
130+ return ;
131+ }
127132
128133 self .transferJettonTo (other_jw , msg .sender , swap_value , msg .query_id , " Swap completed" );
129134 self .assets .set (ctx .sender , old_balance_src + received );
0 commit comments