Skip to content

Commit 518bdf6

Browse files
authored
Merge pull request #1544 from martinshub-tech/fix-admin-force-rebalance-tests
Fix admin force rebalance tests
2 parents 085d25d + a14e359 commit 518bdf6

2 files changed

Lines changed: 133 additions & 0 deletions

File tree

contracts/benchmarks/BASELINES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Current baseline (native test runtime):
77
- `initialize`: CPU `1,500,000`, memory `200,000`
88
- `create_portfolio`: CPU `2,500,000`, memory `300,000`
99
- `execute_rebalance`: CPU `5,000,000`, memory `500,000`
10+
- `execute_rebalance_max_assets`: CPU `10,000,000`, memory `1,000,000`
1011
- `deposit`: CPU `2,000,000`, memory `250,000`
1112

1213
The benchmark assertions fail if any metric exceeds 120% of the baseline.

contracts/src/test.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ const BASELINE_CREATE_PORTFOLIO_CPU: u64 = 2_500_000;
4444
const BASELINE_CREATE_PORTFOLIO_MEM: u64 = 300_000;
4545
const BASELINE_EXECUTE_REBALANCE_CPU: u64 = 5_000_000;
4646
const BASELINE_EXECUTE_REBALANCE_MEM: u64 = 500_000;
47+
const BASELINE_EXECUTE_REBALANCE_MAX_ASSETS_CPU: u64 = 10_000_000; // Will adjust later
48+
const BASELINE_EXECUTE_REBALANCE_MAX_ASSETS_MEM: u64 = 1_000_000; // Will adjust later
4749
const BASELINE_DEPOSIT_CPU: u64 = 2_000_000;
4850
const BASELINE_DEPOSIT_MEM: u64 = 250_000;
4951

@@ -2089,6 +2091,68 @@ fn test_admin_force_rebalance_bypasses_cooldown() {
20892091
assert_eq!(portfolio.last_rebalance, 10010);
20902092
}
20912093

2094+
#[test]
2095+
#[should_panic]
2096+
fn test_admin_force_rebalance_non_admin_rejected() {
2097+
let env = Env::default();
2098+
env.mock_all_auths();
2099+
let contract_id = env.register_contract(None, PortfolioRebalancer);
2100+
let client = PortfolioRebalancerClient::new(&env, &contract_id);
2101+
let reflector_id = env.register_contract(None, reflector_contract::MockReflector);
2102+
let admin = Address::generate(&env);
2103+
let user = Address::generate(&env);
2104+
client.initialize(&admin, &reflector_id);
2105+
2106+
let mut allocations = Map::new(&env);
2107+
let asset = Address::generate(&env);
2108+
allocations.set(asset, 10000);
2109+
let pid = create_portfolio_with_defaults(&env, &client, &user, &allocations, 5, 50);
2110+
2111+
let unauthorized = Address::generate(&env);
2112+
let actual_balances = Map::new(&env);
2113+
client
2114+
.mock_auths(&[MockAuth {
2115+
address: &unauthorized,
2116+
invoke: &MockAuthInvoke {
2117+
contract: &contract_id,
2118+
fn_name: "admin_force_rebalance",
2119+
args: (pid, actual_balances.clone()).into_val(&env),
2120+
sub_invokes: &[],
2121+
},
2122+
}])
2123+
.admin_force_rebalance(&pid, &actual_balances);
2124+
}
2125+
2126+
#[test]
2127+
fn test_admin_force_rebalance_admin_success() {
2128+
let env = Env::default();
2129+
env.mock_all_auths();
2130+
let contract_id = env.register_contract(None, PortfolioRebalancer);
2131+
let client = PortfolioRebalancerClient::new(&env, &contract_id);
2132+
let reflector_id = env.register_contract(None, reflector_contract::MockReflector);
2133+
let admin = Address::generate(&env);
2134+
let user = Address::generate(&env);
2135+
client.initialize(&admin, &reflector_id);
2136+
2137+
let mut allocations = Map::new(&env);
2138+
let asset = Address::generate(&env);
2139+
allocations.set(asset, 10000);
2140+
let pid = create_portfolio_with_defaults(&env, &client, &user, &allocations, 5, 50);
2141+
2142+
let actual_balances = Map::new(&env);
2143+
client
2144+
.mock_auths(&[MockAuth {
2145+
address: &admin,
2146+
invoke: &MockAuthInvoke {
2147+
contract: &contract_id,
2148+
fn_name: "admin_force_rebalance",
2149+
args: (pid, actual_balances.clone()).into_val(&env),
2150+
sub_invokes: &[],
2151+
},
2152+
}])
2153+
.admin_force_rebalance(&pid, &actual_balances);
2154+
}
2155+
20922156
#[test]
20932157
fn test_portfolio_invariants_helper_rejects_invalid_allocations() {
20942158
let env = Env::default();
@@ -2262,6 +2326,74 @@ fn benchmark_deposit_gas() {
22622326
);
22632327
}
22642328

2329+
#[test]
2330+
fn benchmark_execute_rebalance_max_assets() {
2331+
let env = Env::default();
2332+
env.mock_all_auths();
2333+
env.budget().reset_unlimited();
2334+
2335+
let contract_id = env.register_contract(None, PortfolioRebalancer);
2336+
let client = PortfolioRebalancerClient::new(&env, &contract_id);
2337+
let reflector_id = env.register_contract(None, reflector_contract::MockReflector);
2338+
let admin = Address::generate(&env);
2339+
let user = Address::generate(&env);
2340+
let _ = client.initialize(&admin, &reflector_id);
2341+
2342+
let mut allocations = Map::new(&env);
2343+
for _ in 0..MAX_PORTFOLIO_ASSETS {
2344+
allocations.set(Address::generate(&env), ALLOCATION_DENOMINATOR / MAX_PORTFOLIO_ASSETS);
2345+
}
2346+
let pid = create_portfolio_with_defaults(&env, &client, &user, &allocations, 5, 50);
2347+
2348+
env.ledger().with_mut(|li| {
2349+
li.timestamp = 15_000;
2350+
});
2351+
2352+
env.budget().reset_tracker();
2353+
let _ = client.execute_rebalance(&pid, &Map::new(&env));
2354+
2355+
std::println!("CPU used for max assets: {}", env.budget().cpu_instruction_cost());
2356+
std::println!("MEM used for max assets: {}", env.budget().memory_bytes_cost());
2357+
2358+
assert_cost_within_tolerance(
2359+
"execute_rebalance_max_assets",
2360+
env.budget().cpu_instruction_cost(),
2361+
env.budget().memory_bytes_cost(),
2362+
BASELINE_EXECUTE_REBALANCE_MAX_ASSETS_CPU,
2363+
BASELINE_EXECUTE_REBALANCE_MAX_ASSETS_MEM,
2364+
);
2365+
}
2366+
2367+
#[test]
2368+
fn test_execute_rebalance_max_assets_plus_one_rejected() {
2369+
let env = Env::default();
2370+
env.mock_all_auths();
2371+
2372+
let contract_id = env.register_contract(None, PortfolioRebalancer);
2373+
let client = PortfolioRebalancerClient::new(&env, &contract_id);
2374+
let reflector_id = env.register_contract(None, reflector_contract::MockReflector);
2375+
let admin = Address::generate(&env);
2376+
let user = Address::generate(&env);
2377+
let _ = client.initialize(&admin, &reflector_id);
2378+
2379+
let mut too_many_allocations = Map::new(&env);
2380+
for _ in 0..(MAX_PORTFOLIO_ASSETS + 1) {
2381+
too_many_allocations.set(Address::generate(&env), ALLOCATION_DENOMINATOR / (MAX_PORTFOLIO_ASSETS + 1));
2382+
}
2383+
2384+
let too_many_decimals = allocation_decimals(&env, &too_many_allocations, DEFAULT_ASSET_DECIMALS);
2385+
2386+
let result = client.try_create_portfolio(
2387+
&user,
2388+
&too_many_allocations,
2389+
&too_many_decimals,
2390+
&5,
2391+
&50,
2392+
&CURRENT_SLIPPAGE_POLICY_VERSION,
2393+
);
2394+
assert_eq!(result, Err(Ok(Error::TooManyAssets)));
2395+
}
2396+
22652397
// ── Issue #861: rebalance validates allocation sum ──────────────────────
22662398

22672399
#[test]

0 commit comments

Comments
 (0)