Skip to content

Commit efe5e1a

Browse files
committed
fix(settlement): safe i128 balance updates and rename
1 parent 1d9946f commit efe5e1a

7 files changed

Lines changed: 42 additions & 9 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[workspace]
22
resolver = "2"
3-
members = ["contracts/vault", "contracts/revenue_pool"]
3+
members = ["contracts/vault", "contracts/settlement"]
44

55
[workspace.dependencies]
66
soroban-sdk = "22"

SECURITY.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Security Policy
2+
3+
## Checked Arithmetic
4+
5+
All smart contracts in this repository are developed with a "no silent wrap" policy for balance updates.
6+
7+
### Implementation
8+
9+
- We use `checked_add` and `checked_sub` for all `i128` balance mutations.
10+
- In the event of an overflow or underflow, the contract will immediately panic with a descriptive message (e.g., `"balance overflow"`, `"total amount overflow"`), causing the transaction to revert.
11+
- The `overflow-checks = true` setting is enabled in `Cargo.toml` for both `dev` and `release` profiles as an additional safety layer, though explicit checked arithmetic is preferred for clarity and deterministic error messages.
12+
13+
### Affected Contracts
14+
15+
- **`callora-vault`**: `balance` increases during `deposit` and decreases during `deduct`.
16+
- **`callora-settlement`**: Handles distribution of revenue to developers.
17+
18+
## Reporting a Vulnerability
19+
20+
If you find a security issue, please do not open a public issue. Instead, contact the maintainers at security@callora.org.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "callora-revenue-pool"
2+
name = "callora-settlement"
33
version = "0.0.1"
44
edition = "2021"
55
publish = false
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ const ADMIN_KEY: &str = "admin";
99
const USDC_KEY: &str = "usdc";
1010

1111
#[contract]
12-
pub struct RevenuePool;
12+
pub struct Settlement;
1313

1414
#[contractimpl]
15-
impl RevenuePool {
15+
impl Settlement {
1616
/// Initialize the revenue pool with an admin and the USDC token address.
1717
///
1818
/// # Arguments
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ fn create_usdc<'a>(
1515
(address, client, admin_client)
1616
}
1717

18-
fn create_pool(env: &Env) -> (Address, RevenuePoolClient<'_>) {
19-
let address = env.register(RevenuePool, ());
20-
let client = RevenuePoolClient::new(env, &address);
18+
fn create_pool(env: &Env) -> (Address, SettlementClient<'_>) {
19+
let address = env.register(Settlement, ());
20+
let client = SettlementClient::new(env, &address);
2121
(address, client)
2222
}
2323

contracts/vault/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ impl CalloraVault {
134134
);
135135

136136
let mut meta = Self::get_meta(env.clone());
137-
meta.balance += amount;
137+
meta.balance = meta.balance.checked_add(amount).expect("balance overflow");
138138
env.storage().instance().set(&StorageKey::Meta, &meta);
139139
meta.balance
140140
}
@@ -143,7 +143,7 @@ impl CalloraVault {
143143
pub fn deduct(env: Env, amount: i128) -> i128 {
144144
let mut meta = Self::get_meta(env.clone());
145145
assert!(meta.balance >= amount, "insufficient balance");
146-
meta.balance -= amount;
146+
meta.balance = meta.balance.checked_sub(amount).expect("balance underflow");
147147
env.storage().instance().set(&StorageKey::Meta, &meta);
148148
meta.balance
149149
}

contracts/vault/src/test.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,16 @@ fn deposit_after_depositor_cleared_is_rejected() {
189189
// Depositor should no longer be able to deposit
190190
client.deposit(&depositor, &50);
191191
}
192+
193+
#[test]
194+
#[should_panic(expected = "balance overflow")]
195+
fn deposit_overflow_panics() {
196+
let env = Env::default();
197+
let owner = Address::generate(&env);
198+
let contract_id = env.register(CalloraVault {}, ());
199+
let client = CalloraVaultClient::new(&env, &contract_id);
200+
201+
client.init(&owner, &Some(i128::MAX));
202+
env.mock_all_auths();
203+
client.deposit(&owner, &1);
204+
}

0 commit comments

Comments
 (0)