@@ -222,7 +222,7 @@ pub async fn claim_token(
222222
223223 let network = faucet_info. network ( ) ;
224224 set_current_network ( network) ;
225- let recipient = parse_and_validate_address ( & address, network ) ?;
225+ let recipient = parse_and_validate_address ( & address, faucet_info ) ?;
226226 let rpc = Provider :: from_network ( network) ;
227227 let from = faucet_address ( faucet_info)
228228 . await ?
@@ -271,18 +271,36 @@ pub async fn claim_token_all(address: String) -> Result<Vec<ClaimResponse>, Serv
271271 Ok ( results)
272272}
273273
274+ /// Checks if the provided address is valid for the faucet, ensuring invalid addresses are rejected.
275+ #[ cfg( feature = "ssr" ) ]
276+ fn check_valid_address ( address : Address , faucet_info : FaucetInfo ) -> Result < ( ) , ServerFnError > {
277+ use fvm_shared:: address:: Protocol ;
278+
279+ if matches ! ( faucet_info, FaucetInfo :: CalibnetUSDFC )
280+ && ( address. protocol ( ) != Protocol :: Delegated )
281+ {
282+ log:: error!( "Invalid address: {:?}" , address) ;
283+ set_response_status ( StatusCode :: BAD_REQUEST ) ;
284+ return Err ( ServerFnError :: ServerError ( "Invalid address: Only Ethereum-compatible addresses (delegated t4 addresses or native Ethereum 0x addresses) are allowed for Calibnet USDFC token claims." . to_string ( ) ) ) ;
285+ }
286+ Ok ( ( ) )
287+ }
288+
274289#[ cfg( feature = "ssr" ) ]
275290fn parse_and_validate_address (
276291 address : & str ,
277- network : fvm_shared :: address :: Network ,
292+ faucet_info : FaucetInfo ,
278293) -> Result < Address , ServerFnError > {
279- match crate :: utils:: address:: parse_address ( address, network) {
280- Ok ( addr) => Ok ( addr) ,
294+ match crate :: utils:: address:: parse_address ( address, faucet_info. network ( ) ) {
295+ Ok ( addr) => {
296+ check_valid_address ( addr, faucet_info) ?;
297+ Ok ( addr)
298+ }
281299 Err ( e) => {
282- log:: error!( "Invalid address: {}" , e) ;
300+ log:: error!( "Invalid address - failed to parse : {}" , e) ;
283301 set_response_status ( StatusCode :: BAD_REQUEST ) ;
284302 Err ( ServerFnError :: ServerError ( format ! (
285- "Invalid address: {}" ,
303+ "Invalid address - failed to parse : {}" ,
286304 e
287305 ) ) )
288306 }
@@ -403,5 +421,81 @@ fn handle_faucet_error(err: FaucetError) -> ServerFnError {
403421
404422#[ cfg( feature = "ssr" ) ]
405423fn set_response_status ( status : StatusCode ) {
406- leptos:: prelude:: expect_context :: < ResponseOptions > ( ) . set_status ( status) ;
424+ if let Some ( res) = leptos:: context:: use_context :: < ResponseOptions > ( ) {
425+ res. set_status ( status)
426+ }
427+ }
428+
429+ #[ cfg( all( test, feature = "ssr" ) ) ]
430+ mod tests {
431+ use crate :: faucet:: server_api:: * ;
432+
433+ fn assert_valid_address ( address : & str , faucet : FaucetInfo ) {
434+ let network = faucet. network ( ) ;
435+ let addr = crate :: utils:: address:: parse_address ( address, network) . unwrap ( ) ;
436+ assert ! ( check_valid_address( addr, faucet) . is_ok( ) ) ;
437+ assert ! ( parse_and_validate_address( address, faucet) . is_ok( ) ) ;
438+ }
439+
440+ fn assert_invalid_address ( address : & str , faucet : FaucetInfo ) {
441+ let network = faucet. network ( ) ;
442+ let addr = crate :: utils:: address:: parse_address ( address, network) . unwrap ( ) ;
443+ assert ! ( check_valid_address( addr, faucet) . is_err( ) ) ;
444+ assert ! ( parse_and_validate_address( address, faucet) . is_err( ) ) ;
445+ }
446+
447+ #[ test]
448+ fn test_check_valid_address_mainnet ( ) {
449+ let addresses = [
450+ "f03603846" ,
451+ "f1rgci272nfk4k6cpyejepzv4xstpejjckldlzidy" ,
452+ "f2yjb6dq3jggychgnuhevcwe7ehv3ot2rkhkbk4qy" ,
453+ "f3s5kg6rehbbmgvngpec6b7m4uxmwbscdafn2pvtrrp65wbgjuymrr2z6qbkqiunkyjul6b62buqk76q47cjeq" ,
454+ "f410fv2oexfiizeuzm3xtoie3gnxfpfwwglg4q3dgxki" ,
455+ "0xff0000000000000000000000000000000036fd86" ,
456+ "0xAe9C4b9508c929966ef37209b336E5796D632CDc" ,
457+ ] ;
458+ for addr in addresses. iter ( ) {
459+ assert_valid_address ( addr, FaucetInfo :: MainnetFIL ) ;
460+ }
461+ }
462+
463+ #[ test]
464+ fn test_check_valid_address_calibnet ( ) {
465+ let addresses = [
466+ "t03603846" ,
467+ "t1rgci272nfk4k6cpyejepzv4xstpejjckldlzidy" ,
468+ "t2yjb6dq3jggychgnuhevcwe7ehv3ot2rkhkbk4qy" ,
469+ "t3s5kg6rehbbmgvngpec6b7m4uxmwbscdafn2pvtrrp65wbgjuymrr2z6qbkqiunkyjul6b62buqk76q47cjeq" ,
470+ "t410fv2oexfiizeuzm3xtoie3gnxfpfwwglg4q3dgxki" ,
471+ "0xff0000000000000000000000000000000036f672" ,
472+ "0xAe9C4b9508c929966ef37209b336E5796D632CDc" ,
473+ ] ;
474+ for addr in addresses. iter ( ) {
475+ assert_valid_address ( addr, FaucetInfo :: CalibnetFIL ) ;
476+ }
477+ }
478+
479+ #[ test]
480+ fn test_check_valid_address_calibnet_usdfc ( ) {
481+ let valid_addresses = [
482+ "0xAe9C4b9508c929966ef37209b336E5796D632CDc" ,
483+ "t410fv2oexfiizeuzm3xtoie3gnxfpfwwglg4q3dgxki" ,
484+ ] ;
485+ let invalid_addresses = [
486+ "t03603846" ,
487+ "t1rgci272nfk4k6cpyejepzv4xstpejjckldlzidy" ,
488+ "t2yjb6dq3jggychgnuhevcwe7ehv3ot2rkhkbk4qy" ,
489+ "t3s5kg6rehbbmgvngpec6b7m4uxmwbscdafn2pvtrrp65wbgjuymrr2z6qbkqiunkyjul6b62buqk76q47cjeq" ,
490+ "0xff0000000000000000000000000000000036f672" ,
491+ ] ;
492+
493+ for addr in valid_addresses. iter ( ) {
494+ assert_valid_address ( addr, FaucetInfo :: CalibnetUSDFC ) ;
495+ }
496+
497+ for addr in invalid_addresses. iter ( ) {
498+ assert_invalid_address ( addr, FaucetInfo :: CalibnetUSDFC ) ;
499+ }
500+ }
407501}
0 commit comments