Skip to content
Merged
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
19 changes: 19 additions & 0 deletions contract/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog

All notable changes to this Soroban workspace are documented here.

## 0.1.1

### Changed

- Workspace crate versions aligned to **0.1.1**.
- **`soroban-sdk`** workspace dependency updated to **21.7.7** (from 21.7.0), with `Cargo.lock` kept in sync.

### Fixed

- **myfans-token**: Temporary allowance TTL is extended so entries remain readable through `expiration_ledger + 1`, allowing `transfer_from` to return `AllowanceExpired` instead of `NoAllowance` after Soroban 21.7 TTL behavior; TTL is refreshed after partial `transfer_from` and `clear_allowance`.
- **Tests**: Adjusted for SDK/host semantics (contract-scoped event emission, ledger jumps vs instance TTL, `WithdrawEvent` decoding, empty auths via `mock_auths(&[])` / `set_auths`, and related integration cases).

### Tooling

- `scripts/release-check.sh` asserts the workspace `soroban-sdk` pin in `Cargo.toml` (update the script when bumping the SDK).
24 changes: 12 additions & 12 deletions contract/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions contract/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ members = [
]

[workspace.package]
version = "0.1.0"
version = "0.1.1"
edition = "2021"
# Minimum Supported Rust Version (MSRV).
# soroban-sdk 21.x requires at least 1.74 (curve25519-dalek 4.x lower bound).
Expand All @@ -29,7 +29,7 @@ description = "MyFans Soroban smart contracts."
publish = false

[workspace.dependencies]
soroban-sdk = "21.7.0"
soroban-sdk = "21.7.7"

[profile.release]
opt-level = "z"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#[cfg(test)]
mod content_query_tests {
use crate::{ContentAccess, ContentAccessClient};
use soroban_sdk::{testutils::Address as _, Address, Env};
use soroban_sdk::{testutils::Address as _, testutils::Ledger, Address, Env};

fn setup() -> (Env, Address) {
let env = Env::default();
Expand Down
16 changes: 9 additions & 7 deletions contract/contracts/content-access/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,13 @@ mod test {
use super::*;
use soroban_sdk::{
testutils::{Address as _, Events, Ledger},
vec, Address, Env, Error as SorobanError, IntoVal, Symbol, TryIntoVal,
vec,
xdr::SorobanAuthorizationEntry,
Address, Env, Error as SorobanError, IntoVal, Symbol, TryIntoVal,
};

const EMPTY_AUTHS: &[SorobanAuthorizationEntry] = &[];

// Mock token contract for testing
#[contract]
pub struct MockToken;
Expand Down Expand Up @@ -727,11 +731,9 @@ mod test {
env.mock_all_auths();
client.initialize(&admin, &token_id);

let env2 = Env::default();
let client2 = ContentAccessClient::new(&env2, &contract_id);

let creator = Address::generate(&env2);
client2.set_content_price(&creator, &1, &100);
let creator = Address::generate(&env);
env.set_auths(EMPTY_AUTHS);
client.set_content_price(&creator, &1, &100);
}

#[test]
Expand All @@ -743,7 +745,7 @@ mod test {

let admin = Address::generate(&env);
let invalid_token_contract = env.register_contract(None, ContentAccess);
let invalid_token_address: Address = invalid_token_contract.into();
let invalid_token_address = invalid_token_contract;

let contract_id = env.register_contract(None, ContentAccess);
let client = ContentAccessClient::new(&env, &contract_id);
Expand Down
2 changes: 1 addition & 1 deletion contract/contracts/creator-deposits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ mod test {
client.deposit(&creator, &token, &1000);

// Verify transfer was called with correct fee (50)
assert!(env.auths().len() > 0);
assert!(!env.auths().is_empty());
}

#[test]
Expand Down
47 changes: 25 additions & 22 deletions contract/contracts/creator-earnings/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![cfg(test)]

use super::*;
use soroban_sdk::token::{Client as TokenClient, StellarAssetClient};
use soroban_sdk::{
Expand Down Expand Up @@ -182,28 +180,33 @@ fn withdraw_emits_event() {
client.deposit(&depositor, &creator, &500);
client.withdraw(&creator, &200);

// events().all() returns Vec<(contract_addr, topics: Vec<Val>, data: Val)>
let events = env.events().all();
let withdraw_event = events.iter().find(|e| {
// e.1 = topics, e.2 = data
e.1.first().map_or(false, |t| {
t.try_into_val(&env).ok() == Some(Symbol::new(&env, "withdraw"))
})
});

assert!(withdraw_event.is_some(), "withdraw event not emitted");

let event = withdraw_event.unwrap();
let all_events = env.events().all();
let mut withdraw_event: Option<(
Address,
soroban_sdk::Vec<soroban_sdk::Val>,
soroban_sdk::Val,
)> = None;
for i in 0..all_events.len() {
let evt = all_events.get(i).unwrap();
let (id, topics, _data) = &evt;
if *id != client.address {
continue;
}
let t0: Option<Symbol> = topics.get(0).and_then(|v| v.try_into_val(&env).ok());
if t0 == Some(Symbol::new(&env, "withdraw")) {
withdraw_event = Some(evt);
break;
}
}

let event = withdraw_event.expect("withdraw event not emitted");

// Assert topics: single symbol "withdraw"
assert_eq!(event.1.len(), 1);
let topic_symbol: Symbol = event.1.first().unwrap().try_into_val(&env).unwrap();
let topic_symbol: Symbol = event.1.get(0).unwrap().try_into_val(&env).unwrap();
assert_eq!(topic_symbol, Symbol::new(&env, "withdraw"));

// Assert data: (creator, amount, token)
let (event_creator, event_amount, event_token): (Address, i128, Address) =
event.2.try_into_val(&env).unwrap();
assert_eq!(event_creator, creator);
assert_eq!(event_amount, 200);
assert_eq!(event_token, token_address);
let withdraw_data: WithdrawEvent = event.2.try_into_val(&env).unwrap();
assert_eq!(withdraw_data.creator, creator);
assert_eq!(withdraw_data.amount, 200);
assert_eq!(withdraw_data.token, token_address);
}
3 changes: 2 additions & 1 deletion contract/contracts/creator-registry/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![no_std]

use soroban_sdk::{
contract, contracterror, contractimpl, contracttype, panic_with_error, Address, Env, Symbol,
contract, contracterror, contractimpl, contracttype, panic_with_error, Address, Env,
};

use soroban_sdk::token::Client;
Expand Down Expand Up @@ -173,4 +173,5 @@ impl CreatorRegistryContract {
}
}

#[cfg(test)]
mod test;
80 changes: 6 additions & 74 deletions contract/contracts/creator-registry/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![cfg(test)]

use super::Error as ContractError;
use super::*;
use soroban_sdk::{
Expand Down Expand Up @@ -178,75 +176,6 @@ fn test_registration_ledger_key_helper_keeps_legacy_variant() {
);
}

#[test]
fn test_update_creator_id_authorized() {
let env = Env::default();
env.mock_all_auths();

let contract_id = env.register_contract(None, CreatorRegistryContract);
let client = CreatorRegistryContractClient::new(&env, &contract_id);
let admin = Address::generate(&env);
let creator = Address::generate(&env);

client.initialize(&admin);
client.register_creator(&creator, &creator, &111);

client.update_creator_id(&creator, &creator, &222);

assert_eq!(client.get_creator_id(&creator), Some(222));

let events = env.events().all();
let found = events.iter().any(|event| {
let topic: soroban_sdk::Symbol = event.1.get(0).unwrap().try_into_val(&env).unwrap();
topic == soroban_sdk::Symbol::new(&env, "creator_updated")
});
assert!(found, "creator_updated event not emitted");
}

#[test]
fn test_update_creator_id_unauthorized_fails() {
let env = Env::default();
env.mock_all_auths();

let contract_id = env.register_contract(None, CreatorRegistryContract);
let client = CreatorRegistryContractClient::new(&env, &contract_id);
let admin = Address::generate(&env);
let creator = Address::generate(&env);
let rando = Address::generate(&env);

client.initialize(&admin);
client.register_creator(&creator, &creator, &111);

let result = client.try_update_creator_id(&rando, &creator, &222);
assert_eq!(
result,
Err(Ok(SorobanError::from_contract_error(
Error::Unauthorized as u32,
)))
);
}

#[test]
fn test_update_creator_id_not_registered_fails() {
let env = Env::default();
env.mock_all_auths();

let contract_id = env.register_contract(None, CreatorRegistryContract);
let client = CreatorRegistryContractClient::new(&env, &contract_id);
let admin = Address::generate(&env);
let creator = Address::generate(&env);

client.initialize(&admin);

let result = client.try_update_creator_id(&admin, &creator, &222);
assert_eq!(
result,
Err(Ok(SorobanError::from_contract_error(
Error::NotRegistered as u32,
)))
);
}

// ─── Rate limit boundary tests (issue #320) ───────────────────────────────────

/// Advance the ledger sequence by `n` ledgers.
Expand Down Expand Up @@ -399,16 +328,19 @@ fn rate_limit_is_per_caller_not_global() {
fn first_registration_is_never_rate_limited() {
let env = Env::default();
env.mock_all_auths();

// High ledger must be set before instance storage is written: jumping here
// after initialize would exceed the entry TTL and archive keys (SDK 21.7+).
env.ledger().with_mut(|li| li.sequence_number = 99_999);

let contract_id = env.register_contract(None, CreatorRegistryContract);
let client = CreatorRegistryContractClient::new(&env, &contract_id);
let admin = Address::generate(&env);
let creator = Address::generate(&env);

client.initialize(&admin);

// Jump to a high ledger — no prior registration so limit cannot apply
env.ledger().with_mut(|li| li.sequence_number = 99_999);

// No prior registration for admin — rate limit cannot apply
client.register_creator(&admin, &creator, &99u64);

assert_eq!(
Expand Down
2 changes: 1 addition & 1 deletion contract/contracts/earnings/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description.workspace = true
publish.workspace = true

[lib]
crate-type = ["cdylib"]
crate-type = ["cdylib", "rlib"]

[dependencies]
soroban-sdk = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions contract/contracts/earnings/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,5 @@ impl Earnings {
}
}

#[cfg(test)]
mod test;
2 changes: 0 additions & 2 deletions contract/contracts/earnings/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#![cfg(test)]

use super::*;
use soroban_sdk::{
testutils::{Address as _, Events},
Expand Down
Loading
Loading