Description
RWAOracleStorage contains a last_timestamp: u64 field that is written on every set_asset_price call but is never read by any public or private function in the contract.
Current state (storage.rs:17, contract.rs:315-318):
```rust
pub struct RWAOracleStorage {
pub assets: Vec,
pub base: Asset,
pub decimals: u32,
pub resolution: u32,
pub last_timestamp: u64, // ← written but never read
pub rwa_metadata: Map<Symbol, RWAMetadata>,
pub asset_types: Map<Asset, RWAAssetType>,
pub max_staleness: u64,
}
// In set_asset_price_internal — the only usage:
let mut state = RWAOracleStorage::get(env);
state.last_timestamp = timestamp; // ← only write, no reads anywhere
RWAOracleStorage::set(env, &state);
```
No function in the contract reads state.last_timestamp. The per-asset last timestamp is retrieved correctly via IsSep40::lastprice() which reads from persistent storage (DataKey::Prices), not from this field.
Why this is a problem:
- Every
set_asset_price call reads the full RWAOracleStorage struct from instance storage, updates last_timestamp, and writes it back — a wasted read + write for an unused value
- Instance storage has size limits; removing a field reduces the storage footprint for every deployed oracle
- The field misleads readers into thinking there is a meaningful global "last updated" concept, when the actual per-asset timestamp lives in
DataKey::Prices
Requirements
- Remove
last_timestamp: u64 from RWAOracleStorage
- Remove the
last_timestamp assignment in set_asset_price_internal
- Remove the entire second
RWAOracleStorage::get / RWAOracleStorage::set block from set_asset_price_internal — it only existed to update this field
- Update
RWAOracleStorage::new to not initialize the field
- Write unit tests for the cases listed below
Acceptance Criteria
Files to Change
stellar-contracts/rwa-oracle/src/common/storage.rs — remove field from struct and new()
stellar-contracts/rwa-oracle/src/contract.rs — remove update block in set_asset_price_internal
Required Tests
| Test Name |
Scenario |
Expected Result |
test_lastprice_correct_after_multiple_updates |
Set 3 prices at t1, t2, t3 for the same asset |
lastprice() returns price at t3 |
test_lastprice_independent_per_asset |
Set price for NVDA at t1, TSLA at t2 |
Each lastprice() returns its own latest |
Test structure hint:
```rust
#[test]
fn test_lastprice_correct_after_multiple_updates() {
let e = Env::default();
e.mock_all_auths();
set_ledger_timestamp(&e, 2_000_000_000);
let oracle = create_rwa_oracle_contract(&e);
let asset = Asset::Other(Symbol::new(&e, "NVDA"));
oracle.set_asset_price(&asset, &100, &2_000_000_001);
oracle.set_asset_price(&asset, &200, &2_000_000_002);
oracle.set_asset_price(&asset, &300, &2_000_000_003);
let latest = oracle.lastprice(&asset).unwrap();
assert_eq!(latest.price, 300);
assert_eq!(latest.timestamp, 2_000_000_003);
}
#[test]
fn test_lastprice_independent_per_asset() {
let e = Env::default();
e.mock_all_auths();
set_ledger_timestamp(&e, 2_000_000_000);
let oracle = create_rwa_oracle_contract(&e);
let nvda = Asset::Other(Symbol::new(&e, "NVDA"));
let tsla = Asset::Other(Symbol::new(&e, "TSLA"));
oracle.set_asset_price(&nvda, &500, &2_000_000_001);
oracle.set_asset_price(&tsla, &999, &2_000_000_002);
assert_eq!(oracle.lastprice(&nvda).unwrap().price, 500);
assert_eq!(oracle.lastprice(&tsla).unwrap().price, 999);
}
```
Implementation Hint
```rust
// storage.rs — remove field and initialization:
pub struct RWAOracleStorage {
pub assets: Vec,
pub base: Asset,
pub decimals: u32,
pub resolution: u32,
// remove: pub last_timestamp: u64,
pub rwa_metadata: Map<Symbol, RWAMetadata>,
pub asset_types: Map<Asset, RWAAssetType>,
pub max_staleness: u64,
}
// contract.rs — remove from set_asset_price_internal:
fn set_asset_price_internal(env: &Env, asset_id: Asset, price: i128, timestamp: u64) {
// ... validation and persistent storage unchanged ...
// REMOVE these 4 lines:
// let mut state = RWAOracleStorage::get(env);
// state.last_timestamp = timestamp;
// RWAOracleStorage::set(env, &state);
Admin::extend_instance_ttl(env);
Self::extend_persistent_ttl(env, &DataKey::Prices(asset_id));
}
```
Verification
```bash
cd stellar-contracts
cargo test --package rwa-oracle
cargo build --package rwa-oracle --target wasm32v1-none --release
```
Thank you for taking this issue! You are helping us make RWAs consumer friendly on Stellar.
Description
RWAOracleStoragecontains alast_timestamp: u64field that is written on everyset_asset_pricecall but is never read by any public or private function in the contract.Current state (
storage.rs:17,contract.rs:315-318):```rust
pub struct RWAOracleStorage {
pub assets: Vec,
pub base: Asset,
pub decimals: u32,
pub resolution: u32,
pub last_timestamp: u64, // ← written but never read
pub rwa_metadata: Map<Symbol, RWAMetadata>,
pub asset_types: Map<Asset, RWAAssetType>,
pub max_staleness: u64,
}
// In set_asset_price_internal — the only usage:
let mut state = RWAOracleStorage::get(env);
state.last_timestamp = timestamp; // ← only write, no reads anywhere
RWAOracleStorage::set(env, &state);
```
No function in the contract reads
state.last_timestamp. The per-asset last timestamp is retrieved correctly viaIsSep40::lastprice()which reads from persistent storage (DataKey::Prices), not from this field.Why this is a problem:
set_asset_pricecall reads the fullRWAOracleStoragestruct from instance storage, updateslast_timestamp, and writes it back — a wasted read + write for an unused valueDataKey::PricesRequirements
last_timestamp: u64fromRWAOracleStoragelast_timestampassignment inset_asset_price_internalRWAOracleStorage::get/RWAOracleStorage::setblock fromset_asset_price_internal— it only existed to update this fieldRWAOracleStorage::newto not initialize the fieldAcceptance Criteria
last_timestampfield removed fromRWAOracleStoragestructRWAOracleStorage::newno longer setslast_timestampset_asset_price_internalno longer reads/writesRWAOracleStoragefor the timestamp updateset_asset_pricestill correctly stores prices in persistent storagelastprice()still returns the correct latest price after the refactorFiles to Change
stellar-contracts/rwa-oracle/src/common/storage.rs— remove field from struct andnew()stellar-contracts/rwa-oracle/src/contract.rs— remove update block inset_asset_price_internalRequired Tests
test_lastprice_correct_after_multiple_updateslastprice()returns price at t3test_lastprice_independent_per_assetlastprice()returns its own latestTest structure hint:
```rust
#[test]
fn test_lastprice_correct_after_multiple_updates() {
let e = Env::default();
e.mock_all_auths();
set_ledger_timestamp(&e, 2_000_000_000);
let oracle = create_rwa_oracle_contract(&e);
let asset = Asset::Other(Symbol::new(&e, "NVDA"));
}
#[test]
fn test_lastprice_independent_per_asset() {
let e = Env::default();
e.mock_all_auths();
set_ledger_timestamp(&e, 2_000_000_000);
let oracle = create_rwa_oracle_contract(&e);
let nvda = Asset::Other(Symbol::new(&e, "NVDA"));
let tsla = Asset::Other(Symbol::new(&e, "TSLA"));
}
```
Implementation Hint
```rust
// storage.rs — remove field and initialization:
pub struct RWAOracleStorage {
pub assets: Vec,
pub base: Asset,
pub decimals: u32,
pub resolution: u32,
// remove: pub last_timestamp: u64,
pub rwa_metadata: Map<Symbol, RWAMetadata>,
pub asset_types: Map<Asset, RWAAssetType>,
pub max_staleness: u64,
}
// contract.rs — remove from set_asset_price_internal:
fn set_asset_price_internal(env: &Env, asset_id: Asset, price: i128, timestamp: u64) {
// ... validation and persistent storage unchanged ...
}
```
Verification
```bash
cd stellar-contracts
cargo test --package rwa-oracle
cargo build --package rwa-oracle --target wasm32v1-none --release
```
Thank you for taking this issue! You are helping us make RWAs consumer friendly on Stellar.