Skip to main content

aztec_core/
constants.rs

1//! Well-known protocol contract addresses and domain separators.
2//!
3//! These addresses and constants are deterministic and identical across all Aztec networks.
4
5use crate::types::{AztecAddress, Fr};
6
7/// Well-known protocol contract addresses.
8pub mod protocol_contract_address {
9    use super::*;
10
11    /// The Fee Juice contract — manages fee token balances and claims.
12    pub fn fee_juice() -> AztecAddress {
13        AztecAddress(Fr::from(5u64))
14    }
15
16    /// The AuthRegistry protocol contract — manages public authorization witnesses.
17    pub fn auth_registry() -> AztecAddress {
18        AztecAddress(Fr::from(1u64))
19    }
20
21    /// The Contract Instance Deployer — registers contract instances on-chain.
22    pub fn contract_instance_deployer() -> AztecAddress {
23        AztecAddress(Fr::from(2u64))
24    }
25
26    /// The Contract Instance Registry — canonical public deployment registry.
27    pub fn contract_instance_registry() -> AztecAddress {
28        contract_instance_deployer()
29    }
30
31    /// The Contract Class Registerer — publishes contract classes on-chain.
32    pub fn contract_class_registerer() -> AztecAddress {
33        AztecAddress(Fr::from(3u64))
34    }
35
36    /// The Contract Class Registry — canonical class publication registry.
37    pub fn contract_class_registry() -> AztecAddress {
38        contract_class_registerer()
39    }
40
41    /// The Multi-Call Entrypoint — batches multiple calls in one tx.
42    pub fn multi_call_entrypoint() -> AztecAddress {
43        AztecAddress(Fr::from(4u64))
44    }
45}
46
47/// Domain separators used in Poseidon2 hashing throughout the protocol.
48///
49/// These must match the TS constants in `constants.gen.ts`.
50pub mod domain_separator {
51    /// Domain separator for authwit inner hash.
52    ///
53    /// TS: `DomainSeparator.AUTHWIT_INNER = 221354163`
54    pub const AUTHWIT_INNER: u32 = 221_354_163;
55
56    /// Domain separator for authwit outer hash.
57    ///
58    /// TS: `DomainSeparator.AUTHWIT_OUTER = 3283595782`
59    pub const AUTHWIT_OUTER: u32 = 3_283_595_782;
60
61    /// Domain separator for function args hashing.
62    ///
63    /// TS: `DomainSeparator.FUNCTION_ARGS = 3576554347`
64    pub const FUNCTION_ARGS: u32 = 3_576_554_347;
65
66    /// Domain separator for public keys hash computation.
67    pub const PUBLIC_KEYS_HASH: u32 = 777_457_226;
68
69    /// Domain separator for partial address / salted initialization hash.
70    pub const PARTIAL_ADDRESS: u32 = 2_103_633_018;
71
72    /// Domain separator for contract class ID computation.
73    pub const CONTRACT_CLASS_ID: u32 = 3_923_495_515;
74
75    /// Domain separator for private function leaf hashing.
76    pub const PRIVATE_FUNCTION_LEAF: u32 = 1_389_398_688;
77
78    /// Domain separator for public bytecode commitment.
79    pub const PUBLIC_BYTECODE: u32 = 260_313_585;
80
81    /// Domain separator for initialization hash computation.
82    pub const INITIALIZER: u32 = 385_396_519;
83
84    /// Domain separator for contract address V1 derivation.
85    pub const CONTRACT_ADDRESS_V1: u32 = 1_788_365_517;
86}
87
88/// Size constants for deployment computations.
89
90/// Height of the private functions Merkle tree.
91pub const FUNCTION_TREE_HEIGHT: usize = 7;
92
93/// Maximum number of field elements in packed public bytecode.
94pub const MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS: usize = 3000;
95
96/// Maximum height of the artifact function tree.
97pub const ARTIFACT_FUNCTION_TREE_MAX_HEIGHT: usize = 7;
98
99/// Maximum processable L2 gas for a transaction.
100pub const MAX_PROCESSABLE_L2_GAS: u64 = 6_540_000;
101
102/// Bytecode capsule slot used by the Contract Class Registry.
103pub fn contract_class_registry_bytecode_capsule_slot() -> Fr {
104    Fr::from_hex("0x1f61038721b052d5389449bf44f73c817146aedfab1ef13d37f16ce928df1fb7")
105        .expect("valid contract class registry capsule slot constant")
106}
107
108#[cfg(test)]
109#[allow(clippy::expect_used)]
110mod tests {
111    use super::*;
112
113    #[test]
114    fn fee_juice_address_is_5() {
115        let addr = protocol_contract_address::fee_juice();
116        assert_eq!(addr, AztecAddress(Fr::from(5u64)));
117    }
118
119    #[test]
120    fn auth_registry_address_is_1() {
121        let addr = protocol_contract_address::auth_registry();
122        assert_eq!(addr, AztecAddress(Fr::from(1u64)));
123    }
124
125    #[test]
126    fn domain_separator_values_match_ts() {
127        assert_eq!(domain_separator::AUTHWIT_INNER, 221_354_163);
128        assert_eq!(domain_separator::AUTHWIT_OUTER, 3_283_595_782);
129        assert_eq!(domain_separator::FUNCTION_ARGS, 3_576_554_347);
130        assert_eq!(domain_separator::PUBLIC_KEYS_HASH, 777_457_226);
131        assert_eq!(domain_separator::PARTIAL_ADDRESS, 2_103_633_018);
132        assert_eq!(domain_separator::CONTRACT_CLASS_ID, 3_923_495_515);
133        assert_eq!(domain_separator::PRIVATE_FUNCTION_LEAF, 1_389_398_688);
134        assert_eq!(domain_separator::PUBLIC_BYTECODE, 260_313_585);
135        assert_eq!(domain_separator::INITIALIZER, 385_396_519);
136        assert_eq!(domain_separator::CONTRACT_ADDRESS_V1, 1_788_365_517);
137    }
138
139    #[test]
140    fn protocol_contract_addresses() {
141        assert_eq!(
142            protocol_contract_address::contract_instance_deployer(),
143            AztecAddress(Fr::from(2u64))
144        );
145        assert_eq!(
146            protocol_contract_address::contract_class_registerer(),
147            AztecAddress(Fr::from(3u64))
148        );
149        assert_eq!(
150            protocol_contract_address::multi_call_entrypoint(),
151            AztecAddress(Fr::from(4u64))
152        );
153    }
154
155    #[test]
156    fn size_constants() {
157        assert_eq!(super::FUNCTION_TREE_HEIGHT, 7);
158        assert_eq!(super::MAX_PACKED_PUBLIC_BYTECODE_SIZE_IN_FIELDS, 3000);
159        assert_eq!(super::ARTIFACT_FUNCTION_TREE_MAX_HEIGHT, 7);
160        assert_eq!(super::MAX_PROCESSABLE_L2_GAS, 6_540_000);
161    }
162
163    #[test]
164    fn capsule_slot_constant_matches_ts() {
165        assert_eq!(
166            contract_class_registry_bytecode_capsule_slot(),
167            Fr::from_hex("0x1f61038721b052d5389449bf44f73c817146aedfab1ef13d37f16ce928df1fb7")
168                .expect("valid slot")
169        );
170    }
171}