Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 32 additions & 44 deletions app/onchain/contracts/aid_escrow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use soroban_sdk::{

// --- Storage Keys ---
const KEY_ADMIN: Symbol = symbol_short!("admin");
const KEY_TOTAL_LOCKED: Symbol = symbol_short!("locked"); // Map<Address, i128>
const KEY_VERSION: Symbol = symbol_short!("version");
const KEY_PKG_COUNTER: Symbol = symbol_short!("pkg_cnt");
const KEY_CONFIG: Symbol = symbol_short!("config");
Expand Down Expand Up @@ -75,6 +74,15 @@ pub struct Config {
pub allowed_tokens: Vec<Address>,
}

/// Per-token instance-storage key for the locked amount.
/// Replaces the old `Map<Address, i128>` stored under KEY_TOTAL_LOCKED.
/// Each token has its own cell: `TotalLocked::Token(token_address) → i128`.
#[contracttype]
#[derive(Clone, Debug, PartialEq)]
pub enum TotalLocked {
Token(Address),
}

#[contracttype]
#[derive(Clone, Debug, PartialEq)]
pub struct Aggregates {
Expand Down Expand Up @@ -551,21 +559,14 @@ impl AidEscrow {
// --- SOLVENCY CHECK ---
let contract_balance = Self::token_balance(&env, &token, &env.current_contract_address())?;

let mut locked_map: Map<Address, i128> = env
.storage()
.instance()
.get(&KEY_TOTAL_LOCKED)
.unwrap_or(Map::new(&env));

let current_locked = locked_map.get(token.clone()).unwrap_or(0);
let current_locked = Self::get_locked(&env, &token);

if contract_balance < current_locked + amount {
return Err(Error::InsufficientFunds);
}

// --- STATE UPDATES ---
locked_map.set(token.clone(), current_locked + amount);
env.storage().instance().set(&KEY_TOTAL_LOCKED, &locked_map);
Self::set_locked(&env, &token, current_locked + amount);

let created_at = env.ledger().timestamp();
let claim_starts_at = Self::resolve_claim_starts_at(&env, &metadata, created_at)?;
Expand Down Expand Up @@ -651,12 +652,7 @@ impl AidEscrow {
let unit = 10i128.pow(decimals);
let contract_balance = Self::token_balance(&env, &token, &env.current_contract_address())?;

let mut locked_map: Map<Address, i128> = env
.storage()
.instance()
.get(&KEY_TOTAL_LOCKED)
.unwrap_or(Map::new(&env));
let mut current_locked = locked_map.get(token.clone()).unwrap_or(0);
let mut current_locked = Self::get_locked(&env, &token);

// Read the current package counter
let mut counter: u64 = env.storage().instance().get(&KEY_PKG_COUNTER).unwrap_or(0);
Expand Down Expand Up @@ -735,9 +731,8 @@ impl AidEscrow {
created_ids.push_back(id);
}

// Persist updated locked map, counter, and aggregation index
locked_map.set(token.clone(), current_locked);
env.storage().instance().set(&KEY_TOTAL_LOCKED, &locked_map);
// Persist updated locked amount, counter, and aggregation index
Self::set_locked(&env, &token, current_locked);
env.storage().instance().set(&KEY_PKG_COUNTER, &counter);
env.storage().instance().set(&KEY_PKG_IDX, &idx);

Expand Down Expand Up @@ -1128,12 +1123,7 @@ impl AidEscrow {
let contract_balance = Self::token_balance(&env, &token, &env.current_contract_address())?;

// 4. Get total locked amount for the token
let locked_map: Map<Address, i128> = env
.storage()
.instance()
.get(&KEY_TOTAL_LOCKED)
.unwrap_or(Map::new(&env));
let total_locked = locked_map.get(token.clone()).unwrap_or(0);
let total_locked = Self::get_locked(&env, &token);

// 5. Calculate available surplus and validate
let available_surplus = contract_balance - total_locked;
Expand Down Expand Up @@ -1186,21 +1176,24 @@ impl AidEscrow {
}

fn decrement_locked(env: &Env, token: &Address, amount: i128) {
let mut locked_map: Map<Address, i128> = env
.storage()
.instance()
.get(&KEY_TOTAL_LOCKED)
.unwrap_or(Map::new(env));
let current = Self::get_locked(env, token);
let new_locked = if current > amount { current - amount } else { 0 };
Self::set_locked(env, token, new_locked);
}

let current = locked_map.get(token.clone()).unwrap_or(0);
let new_locked = if current > amount {
current - amount
} else {
0
};
/// Returns the amount currently locked for a given token (single-cell read).
fn get_locked(env: &Env, token: &Address) -> i128 {
env.storage()
.instance()
.get(&TotalLocked::Token(token.clone()))
.unwrap_or(0)
}

locked_map.set(token.clone(), new_locked);
env.storage().instance().set(&KEY_TOTAL_LOCKED, &locked_map);
/// Persists the locked amount for a given token (single-cell write).
fn set_locked(env: &Env, token: &Address, amount: i128) {
env.storage()
.instance()
.set(&TotalLocked::Token(token.clone()), &amount);
}

fn validate_token(env: &Env, token: &Address) -> Result<u32, Error> {
Expand Down Expand Up @@ -1418,12 +1411,7 @@ impl AidEscrow {

/// Returns the total amount currently locked for a specific token.
pub fn get_total_locked(env: Env, token: Address) -> i128 {
let locked_map: Map<Address, i128> = env
.storage()
.instance()
.get(&KEY_TOTAL_LOCKED)
.unwrap_or(Map::new(&env));
locked_map.get(token).unwrap_or(0)
Self::get_locked(&env, &token)
}

/// Returns the cumulative amount ever claimed for a specific token.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -563,23 +563,6 @@
]
}
},
{
"key": {
"symbol": "locked"
},
"val": {
"map": [
{
"key": {
"address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF"
},
"val": {
"i128": "0"
}
}
]
}
},
{
"key": {
"symbol": "pkg_cnt"
Expand All @@ -603,6 +586,21 @@
"val": {
"u32": 1
}
},
{
"key": {
"vec": [
{
"symbol": "Token"
},
{
"address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF"
}
]
},
"val": {
"i128": "0"
}
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -582,23 +582,6 @@
]
}
},
{
"key": {
"symbol": "locked"
},
"val": {
"map": [
{
"key": {
"address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF"
},
"val": {
"i128": "0"
}
}
]
}
},
{
"key": {
"symbol": "pkg_cnt"
Expand All @@ -622,6 +605,21 @@
"val": {
"u32": 1
}
},
{
"key": {
"vec": [
{
"symbol": "Token"
},
{
"address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF"
}
]
},
"val": {
"i128": "0"
}
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,23 +528,6 @@
]
}
},
{
"key": {
"symbol": "locked"
},
"val": {
"map": [
{
"key": {
"address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF"
},
"val": {
"i128": "10000000"
}
}
]
}
},
{
"key": {
"symbol": "pkg_cnt"
Expand All @@ -568,6 +551,21 @@
"val": {
"u32": 1
}
},
{
"key": {
"vec": [
{
"symbol": "Token"
},
{
"address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF"
}
]
},
"val": {
"i128": "10000000"
}
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -546,23 +546,6 @@
]
}
},
{
"key": {
"symbol": "locked"
},
"val": {
"map": [
{
"key": {
"address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF"
},
"val": {
"i128": "10000000"
}
}
]
}
},
{
"key": {
"symbol": "pkg_cnt"
Expand All @@ -586,6 +569,21 @@
"val": {
"u32": 1
}
},
{
"key": {
"vec": [
{
"symbol": "Token"
},
{
"address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF"
}
]
},
"val": {
"i128": "10000000"
}
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -589,23 +589,6 @@
]
}
},
{
"key": {
"symbol": "locked"
},
"val": {
"map": [
{
"key": {
"address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF"
},
"val": {
"i128": "0"
}
}
]
}
},
{
"key": {
"symbol": "pkg_cnt"
Expand All @@ -629,6 +612,21 @@
"val": {
"u32": 1
}
},
{
"key": {
"vec": [
{
"symbol": "Token"
},
{
"address": "CBUSYNQKASUYFWYC3M2GUEDMX4AIVWPALDBYJPNK6554BREHTGZ2IUNF"
}
]
},
"val": {
"i128": "0"
}
}
]
}
Expand Down
Loading