diff --git a/Cargo.lock b/Cargo.lock index 7876fca..c787d0c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -180,6 +180,12 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bech32" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" + [[package]] name = "bitflags" version = "1.3.2" @@ -472,7 +478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c1556156fdf892a55cced6115968b961eaaadd6f724a2c2cb7d1e168e32dd3" dependencies = [ "base64 0.21.7", - "bech32", + "bech32 0.9.1", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -495,6 +501,7 @@ dependencies = [ "async-trait", "base16ct", "base64 0.22.1", + "bech32 0.11.0", "clap", "cosmwasm-std", "covenant-utils", @@ -535,7 +542,7 @@ version = "0.1.0" source = "git+https://github.com/timewave-computer/covenants?tag=v0.1.0#e41120b6f0e9fe11934b5274033db21cd7deb271" dependencies = [ "astroport", - "bech32", + "bech32 0.9.1", "cosmos-sdk-proto 0.14.0", "cosmwasm-schema", "cosmwasm-std", @@ -1482,7 +1489,7 @@ name = "neutron-sdk" version = "0.8.0" source = "git+https://github.com/neutron-org/neutron-sdk?tag=v0.8.0#40f6592f1eec9e2e1bf0e0531a011294d70d1711" dependencies = [ - "bech32", + "bech32 0.9.1", "cosmos-sdk-proto 0.20.0", "cosmwasm-schema", "cosmwasm-std", @@ -2950,7 +2957,7 @@ version = "0.1.0" source = "git+https://github.com/timewave-computer/covenants?tag=v0.1.0#e41120b6f0e9fe11934b5274033db21cd7deb271" dependencies = [ "astroport", - "bech32", + "bech32 0.9.1", "cosmwasm-schema", "cosmwasm-std", "covenant-macros", @@ -2989,7 +2996,7 @@ version = "0.1.0" source = "git+https://github.com/timewave-computer/covenants?tag=v0.1.0#e41120b6f0e9fe11934b5274033db21cd7deb271" dependencies = [ "astroport", - "bech32", + "bech32 0.9.1", "cosmos-sdk-proto 0.14.0", "cosmwasm-schema", "cosmwasm-std", @@ -3020,7 +3027,7 @@ name = "valence-covenant-swap" version = "0.1.0" source = "git+https://github.com/timewave-computer/covenants?tag=v0.1.0#e41120b6f0e9fe11934b5274033db21cd7deb271" dependencies = [ - "bech32", + "bech32 0.9.1", "cosmos-sdk-proto 0.14.0", "cosmwasm-schema", "cosmwasm-std", @@ -3050,7 +3057,7 @@ version = "0.1.0" source = "git+https://github.com/timewave-computer/covenants?tag=v0.1.0#e41120b6f0e9fe11934b5274033db21cd7deb271" dependencies = [ "astroport", - "bech32", + "bech32 0.9.1", "cosmos-sdk-proto 0.14.0", "cosmwasm-schema", "cosmwasm-std", @@ -3080,7 +3087,7 @@ name = "valence-ibc-forwarder" version = "0.1.0" source = "git+https://github.com/timewave-computer/covenants?tag=v0.1.0#e41120b6f0e9fe11934b5274033db21cd7deb271" dependencies = [ - "bech32", + "bech32 0.9.1", "cosmos-sdk-proto 0.14.0", "cosmwasm-schema", "cosmwasm-std", @@ -3105,7 +3112,7 @@ name = "valence-interchain-router" version = "0.1.0" source = "git+https://github.com/timewave-computer/covenants?tag=v0.1.0#e41120b6f0e9fe11934b5274033db21cd7deb271" dependencies = [ - "bech32", + "bech32 0.9.1", "cosmos-sdk-proto 0.14.0", "cosmwasm-schema", "cosmwasm-std", @@ -3129,7 +3136,7 @@ name = "valence-native-router" version = "0.1.0" source = "git+https://github.com/timewave-computer/covenants?tag=v0.1.0#e41120b6f0e9fe11934b5274033db21cd7deb271" dependencies = [ - "bech32", + "bech32 0.9.1", "cosmos-sdk-proto 0.14.0", "cosmwasm-schema", "cosmwasm-std", @@ -3169,7 +3176,7 @@ name = "valence-osmo-liquid-pooler" version = "0.1.0" source = "git+https://github.com/timewave-computer/covenants?tag=v0.1.0#e41120b6f0e9fe11934b5274033db21cd7deb271" dependencies = [ - "bech32", + "bech32 0.9.1", "cosmwasm-schema", "cosmwasm-std", "covenant-macros", diff --git a/Cargo.toml b/Cargo.toml index c753d87..5fd09a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ anyhow = "1.0.81" async-trait = "0.1.80" base16ct = "0.2.0" base64 = "0.22.0" +bech32 = "0.11.0" clap = { version = "4.5.4", features = ["derive"] } dotenv = "0.15.0" itertools = "0.12.1" diff --git a/src/utils/mod.rs b/src/utils/mod.rs index d906691..196f94d 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,5 +1,36 @@ +use anyhow::Error; +use bech32::{primitives::decode::CheckedHrpstring, Bech32}; + +use crate::validations::CovenantValidationContext; + pub mod assets; pub mod astroport; pub mod chain; pub mod neutron; pub mod path; + +pub fn validate_party_address<'a>(ctx: &mut CovenantValidationContext<'a>, + key: &'a str, field : &'a str, address: &str) { + // Decode the Bech32 address + match validate_bech32_address(address) { + Ok(_) => { + // Note: no check is done on the HRP (Human Readable Part) for now + ctx.valid_field(key, field, "valid Bech32 address".to_owned()); + }, + Err(_) => { + ctx.invalid_field(key, field, "Invalid Bech32 address".to_owned()); + } + } +} + +fn validate_bech32_address(address: &str) -> Result<(), Error> { + let _ = CheckedHrpstring::new::(address) + .map_err(|e| anyhow::anyhow!(e))?; + Ok(()) +} + +#[test] +fn test_validate_bech32_address() { + validate_bech32_address("cosmos1ayw8xtxkty5cfzx44z6vxpevmtudg2n3f4etcq").unwrap(); + validate_bech32_address("neutron1ayw8xtxkty5cfzx44z6vxpevmtudg2n3d2sfz8").unwrap(); +} \ No newline at end of file diff --git a/src/validations/single_party_pol_covenant.rs b/src/validations/single_party_pol_covenant.rs index 3037653..78c4b2f 100644 --- a/src/validations/single_party_pol_covenant.rs +++ b/src/validations/single_party_pol_covenant.rs @@ -10,6 +10,7 @@ use super::{CovenantValidationContext, Validate}; use crate::utils::assets::get_chain_asset_info; use crate::utils::chain::get_chain_info; use crate::utils::path::{get_path_info, IBCPath}; +use crate::utils::validate_party_address; use crate::validations::neutron::verify_expiration; use crate::validations::{ astroport::verify_astroport_liquid_pooler_config, @@ -168,9 +169,12 @@ impl<'a> Validate<'a> for SinglePartyPolCovenantInstMsg { ); } + field = "party_receiver_addr"; + validate_party_address(ctx, key, field, msg.covenant_party_config.party_receiver_addr.as_str()); + field = "addr"; + validate_party_address(ctx, key, field, msg.covenant_party_config.addr.as_str()); + //TODO: Validate the rest of the covenant party config - // field = "party_receiver_addr"; - // field = "addr"; // field = "denom_to_pfm_map"; // field = "fallback_address"; diff --git a/src/validations/two_party_pol_covenant.rs b/src/validations/two_party_pol_covenant.rs index db51cf2..f3212d8 100644 --- a/src/validations/two_party_pol_covenant.rs +++ b/src/validations/two_party_pol_covenant.rs @@ -9,6 +9,7 @@ use super::{CovenantValidationContext, Validate}; use crate::utils::assets::get_chain_asset_info; use crate::utils::chain::get_chain_info; use crate::utils::path::{get_path_info, IBCPath}; +use crate::utils::validate_party_address; use crate::validations::astroport::verify_astroport_liquid_pooler_config; use crate::validations::neutron::verify_expiration; use crate::validations::{ @@ -289,9 +290,10 @@ async fn verify_party_config<'a>( ); } - //TODO: validate addresses - // field = "party_receiver_addr"; - // field = "addr"; + field = "party_receiver_addr"; + validate_party_address(ctx, key, field, native_party.party_receiver_addr.as_str()); + field = "addr"; + validate_party_address(ctx, key, field, native_party.addr.as_str()); } tppc::CovenantPartyConfig::Interchain(interchain_party) => { let path_info = @@ -449,9 +451,12 @@ async fn verify_party_config<'a>( ); } + field = "party_receiver_addr"; + validate_party_address(ctx, key, field, interchain_party.party_receiver_addr.as_str()); + field = "addr"; + validate_party_address(ctx, key, field, interchain_party.addr.as_str()); + //TODO: Validate the rest of the covenant party config - // field = "party_receiver_addr"; - // field = "addr"; // field = "denom_to_pfm_map"; // field = "fallback_address"; }