forked from Vero-protocol/vero-core-engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproxy.rs
More file actions
74 lines (57 loc) · 2.57 KB
/
Copy pathproxy.rs
File metadata and controls
74 lines (57 loc) · 2.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! Upgradeable Proxy Pattern Entry Point
//!
//! Provides a hardened, audit-ready foundation for the Vero Protocol control plane.
//! Includes storage gap to prevent storage collisions, admin controls, and
//! adheres to Soroban/Rust security standards.
use soroban_sdk::{contract, contractimpl, contracterror, panic_with_error, Address, BytesN, Env, Symbol, Bytes};
extern crate alloc;
use crate::{audit, types::StateCommitment};
const ADMIN_KEY: Symbol = soroban_sdk::symbol_short!("ADMIN");
const GAP_KEY: Symbol = soroban_sdk::symbol_short!("GAP");
#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
pub enum ProxyError {
NotInitialized = 1,
AlreadyInitialized = 2,
InvalidWasmHash = 3,
}
#[contract]
pub struct UpgradeableProxy;
#[contractimpl]
impl UpgradeableProxy {
/// Initialize the proxy with an admin address and a storage gap.
pub fn init(env: Env, admin: Address) {
crate::non_reentrant!(&env);
if env.storage().instance().has(&ADMIN_KEY) {
panic_with_error!(&env, ProxyError::AlreadyInitialized);
}
admin.require_auth();
env.storage().instance().set(&ADMIN_KEY, &admin);
// Storage gap to reserve slots and prevent collisions in future upgrades
let gap: soroban_sdk::Vec<u64> = soroban_sdk::Vec::from_array(&env, [0u64; 50]);
env.storage().instance().set(&GAP_KEY, &gap);
}
/// Upgrade the contract's WASM code. Only the admin can perform this operation.
/// This provides a direct admin-controlled upgrade path.
pub fn upgrade(env: Env, new_wasm_hash: BytesN<32>) {
crate::non_reentrant!(&env);
if !env.storage().instance().has(&ADMIN_KEY) {
panic_with_error!(&env, ProxyError::NotInitialized);
}
let admin: Address = env.storage().instance().get(&ADMIN_KEY).unwrap();
admin.require_auth();
if new_wasm_hash.to_array() == [0u8; 32] {
panic_with_error!(&env, ProxyError::InvalidWasmHash);
}
env.deployer().update_current_contract_wasm(new_wasm_hash);
}
/// ZK-ready integrity check invoked via the audit layer
pub fn verify_integrity(env: Env, commitment: StateCommitment, payload: Bytes) {
crate::non_reentrant!(&env);
// Copy bytes to verify transition
let mut payload_buf = alloc::vec::Vec::new();
payload_buf.resize(payload.len() as usize, 0);
payload.copy_into_slice(&mut payload_buf);
audit::validate_transition(&env, &commitment, &payload_buf);
}
}