diff --git a/Cargo.lock b/Cargo.lock index 9ae5ddfd..b4c9f4e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1008,6 +1008,7 @@ dependencies = [ "anoma-rm-risc0", "dotenvy", "serde", + "serde_json", "thiserror 2.0.18", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 2f797697..93cba3e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ anoma-rm-risc0 = { version = "1.1.1", features = ["bonsai", "aggregation"] } anoma-rm-risc0-test-app = { version = "1.1.1", features = ["bonsai"] } dotenvy = { version = "0.15.7", features = ["cli"] } serde = { version = "1.0.228", default-features = false } +serde_json = "1.0" thiserror = "2.0.18" tokio = { version = "1.51", features = ["rt-multi-thread"] } diff --git a/RELEASE_CHECKLIST.md b/RELEASE_CHECKLIST.md index 5e481e4e..63aa824f 100644 --- a/RELEASE_CHECKLIST.md +++ b/RELEASE_CHECKLIST.md @@ -9,16 +9,13 @@ Releases of the packages contained in this monorepo follow the [SemVer conventio We distinguish between three release cases: - Deploying a **new** protocol adapter version to multiple new chains resulting in a new - - `contracts/vX.Y.Z` version - `bindings/vA.0.0` version - Deploying an **existing** protocol adapter version to multiple new chains resulting in a new - - `bindings/vA.B.0` version - Maintaining the bindings resulting in a new - - `bindings/vA.B.C` version ## Deploying a new Protocol Adapter Version @@ -75,13 +72,7 @@ We distinguish between three release cases: - [ ] Bump the `_PROTOCOL_ADAPTER_VERSION` constant in [`./contracts/src/libs/Versioning.sol`](./contracts/src/libs/Versioning.sol) to the new version number following [SemVer](https://semver.org/spec/v2.0.0.html). -- [ ] Remove all chain name and address pairs in the - - ```rust - pub fn protocol_adapter_deployments_map() -> HashMap - ``` - - function in [`./bindings/src/addresses.rs`](./bindings/src/addresses.rs). +- [ ] Remove all entries from [`./deployments.json`](./deployments.json) (replace the array contents with `[]`). ### 3. Build the Contracts @@ -112,7 +103,6 @@ For each chain, you want to deploy to, do the following: ``` - [ ] Verify the contract on - - [ ] sourcify ```sh @@ -129,13 +119,7 @@ For each chain, you want to deploy to, do the following: ### 5. Update the Deployments Map and Create a new `contracts` and `bindings` GitHub Release -- [ ] Add the **new** address and chain name pairs in the - - ```rust - pub fn protocol_adapter_deployments_map() -> HashMap - ``` - - function in [`./bindings/src/addresses.rs`](./bindings/src/addresses.rs). +- [ ] Add a deployment entry to [`./deployments.json`](./deployments.json) for each chain deployed. - [ ] Change the `bindings` package version number in the [`./bindings/Cargo.toml`](./bindings/Cargo.toml) file to `A.0.0`, where `A` is the last `MAJOR` version number incremented by 1. @@ -148,7 +132,6 @@ For each chain, you want to deploy to, do the following: - [ ] Run the tests with `just bindings-test`. - [ ] After merging, create new tags for: - - [ ] `contracts/vX.Y.Z` where `X.Y.Z` must match the protocol adapter version number and - [ ] `bindings/vA.0.0` tag, where `A` is the last `MAJOR` version incremented by 1. @@ -262,7 +245,6 @@ For each **new** chain, you want to deploy to, do the following: ``` - [ ] Verify the contract on - - [ ] sourcify ```sh @@ -279,13 +261,7 @@ For each **new** chain, you want to deploy to, do the following: ### 4. Update the Deployments Map and Create a new `bindings` GitHub Release -- [ ] Add the **new** address and chain name pairs in the - - ```rust - pub fn protocol_adapter_deployments_map() -> HashMap - ``` - - function in `./bindings/src/addresses.rs`. +- [ ] Add a deployment entry to [`./deployments.json`](./deployments.json) for each **new** chain deployed. - [ ] Change the `bindings` package version number in the `./bindings/Cargo.toml` file to `A.B.0`, where `A` is the last `MAJOR` version and `B` is the last `MINOR` version number incremented by 1. diff --git a/bindings/Cargo.toml b/bindings/Cargo.toml index 39c76378..15f0cc16 100644 --- a/bindings/Cargo.toml +++ b/bindings/Cargo.toml @@ -13,6 +13,7 @@ alloy = { workspace = true } alloy-chains = { workspace = true } anoma-rm-risc0 = { workspace = true } serde = { workspace = true } +serde_json = { workspace = true } thiserror = { workspace = true } dotenvy = { workspace = true } diff --git a/bindings/src/addresses.rs b/bindings/src/addresses.rs index 4eeb9aef..5d9aca4f 100644 --- a/bindings/src/addresses.rs +++ b/bindings/src/addresses.rs @@ -1,22 +1,37 @@ -use alloy::primitives::{Address, address}; +use alloy::primitives::Address; use alloy_chains::NamedChain; +use serde::Deserialize; use std::collections::HashMap; +use std::sync::LazyLock; + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct DeploymentEntry { + chain_id: u64, + contract_address: String, +} + +static DEPLOYMENTS: LazyLock> = LazyLock::new(|| { + let entries: Vec = + serde_json::from_str(include_str!("../../deployments.json")) + .expect("deployments.json: invalid JSON"); + + entries + .into_iter() + .filter_map(|e| { + let chain = NamedChain::try_from(e.chain_id).ok()?; + let addr: Address = e.contract_address.parse().ok()?; + Some((chain, addr)) + }) + .collect() +}); /// Returns a map of protocol adapter deployments for all supported chains. pub fn protocol_adapter_deployments_map() -> HashMap { - HashMap::from([ - ( - NamedChain::TempoModerato, - address!("0x5573d493120736322794D870cCEDF74073588b24"), // Unverified contract due to foundry issues. - ), - ( - NamedChain::Tempo, - address!("0x5573d493120736322794D870cCEDF74073588b24"), // Unverified contract due to foundry issues. - ), - ]) + DEPLOYMENTS.clone() } /// Returns the address of the protocol adapter deployed on the provided chain, if any. pub fn protocol_adapter_address(chain: &NamedChain) -> Option
{ - protocol_adapter_deployments_map().get(chain).cloned() + DEPLOYMENTS.get(chain).cloned() } diff --git a/bindings/tests/deployments.rs b/bindings/tests/deployments.rs new file mode 100644 index 00000000..4d51b3dd --- /dev/null +++ b/bindings/tests/deployments.rs @@ -0,0 +1,82 @@ +use alloy::primitives::Address; +use alloy_chains::NamedChain; +use anoma_pa_evm_bindings::addresses::{ + protocol_adapter_address, protocol_adapter_deployments_map, +}; +use std::collections::HashSet; + +#[derive(serde::Deserialize)] +#[serde(rename_all = "camelCase")] +struct RawEntry { + chain_id: u64, + contract_address: String, +} + +fn raw_entries() -> Vec { + serde_json::from_str(include_str!("../../deployments.json")) + .expect("deployments.json: invalid JSON") +} + +#[test] +fn all_entries_have_valid_chain_ids() { + for entry in raw_entries() { + NamedChain::try_from(entry.chain_id).unwrap_or_else(|_| { + panic!( + "chain ID {} does not map to a known NamedChain variant", + entry.chain_id + ) + }); + } +} + +#[test] +fn all_entries_have_valid_addresses() { + for entry in raw_entries() { + entry + .contract_address + .parse::
() + .unwrap_or_else(|_| { + panic!( + "invalid contract address '{}' for chain ID '{}'", + entry.contract_address, entry.chain_id + ) + }); + } +} + +#[test] +fn no_duplicate_chain_ids() { + let entries = raw_entries(); + let mut seen = HashSet::new(); + for entry in &entries { + assert!( + seen.insert(entry.chain_id), + "duplicate chain ID {}", + entry.chain_id + ); + } +} + +#[test] +fn deployments_map_has_expected_count() { + let map = protocol_adapter_deployments_map(); + let entries = raw_entries(); + assert_eq!( + map.len(), + entries.len(), + "deployments map size ({}) does not match JSON entries ({})", + map.len(), + entries.len() + ); +} + +#[test] +fn each_chain_is_individually_addressable() { + let map = protocol_adapter_deployments_map(); + for chain in map.keys() { + assert!( + protocol_adapter_address(chain).is_some(), + "protocol_adapter_address returned None for chain '{chain}'" + ); + } +} diff --git a/deployments.json b/deployments.json new file mode 100644 index 00000000..66818b3b --- /dev/null +++ b/deployments.json @@ -0,0 +1,10 @@ +[ + { + "chainId": 4217, + "contractAddress": "0x5573d493120736322794D870cCEDF74073588b24" + }, + { + "chainId": 42431, + "contractAddress": "0x5573d493120736322794D870cCEDF74073588b24" + } +]