Problem
The factory uses a simple 4-byte encoding of pool_id as the deployment salt:
fn pool_salt(env: &Env, pool_id: u32) -> BytesN<32> {
let mut bytes = [0u8; 32];
bytes[28..].copy_from_slice(&pool_id.to_be_bytes()); // only last 4 bytes are non-zero
BytesN::from_array(env, &bytes)
}
This creates two issues:
1. Factory replacement collision
If the factory contract is redeployed (at a different address) and starts creating pools with the same pool_id values, the pool addresses will be different (since salt alone doesn't determine address — the deployer address matters). However, if a second factory is deployed at the exact same address via a different mechanism, pool address collisions become possible.
2. Salt is not human-readable or auditable
An auditor reviewing the on-chain salt has no way to know it corresponds to pool_id = 3 without knowing the encoding scheme.
Recommended Fix
Encode the full pool context into the salt using env.crypto().sha256:
fn pool_salt(env: &Env, pool_id: u32, asset: &Address) -> BytesN<32> {
let mut pre_image = soroban_sdk::Bytes::new(env);
pre_image.extend_from_slice(&pool_id.to_be_bytes());
// Encode asset bytes into pre_image
env.crypto().sha256(&pre_image)
}
This makes the salt:
- Unique per (factory_address, pool_id, asset) triple
- Collision-resistant by construction
- Reproducible deterministically
Also document the salt scheme in a comment so auditors can verify.
Acceptance Criteria
Problem
The factory uses a simple 4-byte encoding of
pool_idas the deployment salt:This creates two issues:
1. Factory replacement collision
If the factory contract is redeployed (at a different address) and starts creating pools with the same
pool_idvalues, the pool addresses will be different (since salt alone doesn't determine address — the deployer address matters). However, if a second factory is deployed at the exact same address via a different mechanism, pool address collisions become possible.2. Salt is not human-readable or auditable
An auditor reviewing the on-chain salt has no way to know it corresponds to
pool_id = 3without knowing the encoding scheme.Recommended Fix
Encode the full pool context into the salt using
env.crypto().sha256:This makes the salt:
Also document the salt scheme in a comment so auditors can verify.
Acceptance Criteria
pool_saltincludes bothpool_idandassetin the pre-image