11use  anyhow:: Context ; 
2+ use  namada_ibc:: OsmosisSwapMemoDataInner ; 
23use  namada_ibc:: apps:: nft_transfer:: types:: PORT_ID_STR  as  NFT_PORT_ID_STR ; 
34use  namada_ibc:: apps:: transfer:: types:: packet:: PacketData  as  FtPacketData ; 
45use  namada_ibc:: apps:: transfer:: types:: { 
@@ -10,6 +11,7 @@ use namada_ibc::core::channel::types::msgs::PacketMsg;
1011use  namada_ibc:: core:: channel:: types:: packet:: Packet ; 
1112use  namada_ibc:: core:: handler:: types:: msgs:: MsgEnvelope ; 
1213use  namada_ibc:: core:: host:: types:: identifiers:: { ChannelId ,  PortId } ; 
14+ use  namada_ibc:: trace:: convert_to_address; 
1315use  namada_sdk:: address:: Address ; 
1416use  namada_sdk:: token:: Transfer ; 
1517
@@ -100,7 +102,49 @@ fn packet_msg_to_balance_info(
100102    native_token :  Id , 
101103    packet_msg :  PacketMsg , 
102104)  -> anyhow:: Result < Option < BalanceChange > >  { 
105+     let  try_extract_swap_overflow = |packet :  Packet | -> anyhow:: Result < 
106+         Option < BalanceChange > , 
107+     >  { 
108+         let  native_token = native_token. clone ( ) ; 
109+         let  packet_data = serde_json:: from_slice :: < FtPacketData > ( & packet. data ) 
110+             . context ( "Could not deserialize IBC fungible token packet" ) ?; 
111+ 
112+         let  memo_data = 
113+             serde_json:: from_str :: < serde_json:: Value > ( packet_data. memo . as_ref ( ) ) 
114+                 . context ( "Invalid JSON" ) ?
115+             . pointer ( "/forward/next/wasm/msg/osmosis_swap/final_memo/namada/osmosis_swap" ) 
116+             . map ( |swap| { 
117+                 serde_json:: from_value :: < OsmosisSwapMemoDataInner > ( swap. clone ( ) ) 
118+                     . context ( "Failed to deserialize Osmosis swap memo" ) 
119+             } ) 
120+             . transpose ( ) ?; 
121+ 
122+         if  let  Some ( memo_data)  = memo_data { 
123+             let  trace = memo_data. overflow_trace ; 
124+ 
125+             let  token =
126+                 // For nam overflow_trace should be nam's tnam address 
127+                 if  Id :: Account ( trace. clone ( ) )  == native_token { 
128+                     Token :: Native ( native_token) 
129+                 // For ibc overflow_trace should be /transfer/channel-x/denom 
130+                 }  else  { 
131+                     Token :: Ibc ( crate :: token:: IbcToken  { 
132+                         address :  convert_to_address ( & trace) 
133+                             . context ( "Failed to convert IBC trace to address" ) ?
134+                             . into ( ) , 
135+                         trace :  Id :: IbcTrace ( trace) , 
136+                     } ) 
137+                 } ; 
138+             let  source = Id :: from ( memo_data. overflow_receiver ) ; 
139+ 
140+             return  Ok ( Some ( BalanceChange :: new ( source,  token) ) ) ; 
141+         } ; 
142+ 
143+         Ok ( None ) 
144+     } ; 
145+ 
103146    let  extract = |packet :  Packet | -> anyhow:: Result < BalanceChange >  { 
147+         let  native_token = native_token. clone ( ) ; 
104148        let  packet_data = serde_json:: from_slice :: < FtPacketData > ( & packet. data ) 
105149            . context ( "Could not deserialize IBC fungible token packet" ) ?; 
106150
@@ -128,7 +172,10 @@ fn packet_msg_to_balance_info(
128172            . context ( "Could not deserialize IBC acknowledgement" ) ?; 
129173
130174            match  ack { 
131-                 AcknowledgementStatus :: Success ( _)  => Ok ( None ) , 
175+                 AcknowledgementStatus :: Success ( _)  => { 
176+                     // Needed to update the balance of overflow receiver when doing shielded swaps 
177+                     try_extract_swap_overflow ( msg. packet ) 
178+                 } 
132179                AcknowledgementStatus :: Error ( _)  => { 
133180                    extract ( msg. packet ) . map ( Some ) 
134181                } 
0 commit comments