Skip to content
Closed
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
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ members = [
"contracts/sweep_controller",
"contracts/shared",
"contracts/reserve_contract",
"contracts/native_transfer",
]
31 changes: 25 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ Handles fund transfers:
- Handles multi-asset transfers
- Reclaims base reserves

### 3. ReserveContract
Stores and exposes the Stellar base reserve configuration:
- Admin-controlled base reserve amount (stored in stroops)
- Distinguishes user funds from network overhead in ephemeral accounts
- TTL management to prevent contract data archival
- Event emission for reserve updates and auditability

## Project Structure

contracts/
Expand All @@ -47,13 +54,22 @@ contracts/
│ ├── src/
│ │ ├── lib.rs
│ │ ├── authorization.rs
│ │ └── transfers.rs
│ │ ├── transfers.rs
│ │ ├── storage.rs # State management
│ │ └── errors.rs # Error types
│ └── Cargo.toml
├── reserve_contract/ # ← NEW
│ ├── src/
│ │ ├── lib.rs # Main contract
│ │ ├── storage.rs # State management
│ │ ├── events.rs # Event definitions
│ │ └── errors.rs # Error types
│ └── Cargo.toml
└── shared/
└── types.rs # Shared types

├── src/
│ ├── lib.rs
│ └── types.rs
└── Cargo.toml
## Prerequisites
```bash
# Install Rust
Expand Down Expand Up @@ -110,13 +126,16 @@ pub trait EphemeralAccountInterface {
fn record_payment(env: Env, amount: i128, asset: Address) -> Result<(), Error>;

// Execute sweep to permanent wallet
fn sweep(env: Env, destination: Address) -> Result<(), Error>;
fn sweep(env: Env, destination: Address, auth_signature: BytesN<64>) -> Result<(), Error>;

// Check if account is expired
fn is_expired(env: Env) -> bool;
}
```
> **⚠️ MVP:** **authorization is not yet enforced on-chain.
> **⚠️ MVP:** On-chain authorization is not enforced at the `EphemeralAccount` contract
> level. Calling `EphemeralAccount::sweep()` directly bypasses all signature verification.
> Authorization is only enforced when sweeps are routed through `SweepController`.
> Do not call `EphemeralAccount::sweep()` directly in production.

See [Bridgelet Documentation](https://github.com/bridgelet-org/bridgelet) for full API reference.

Expand Down Expand Up @@ -148,4 +167,4 @@ See [Security Audit Report](./docs/security-audit.md) (coming soon)

## License

MIT
MIT
9 changes: 6 additions & 3 deletions contracts/ephemeral_account/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,12 @@ impl EphemeralAccountContract {
_destination: &Address,
_signature: &BytesN<64>,
) -> Result<(), Error> {
// TODO: Implement proper signature verification
// For MVP, we rely on off-chain SDK to only call with valid auth
// Future: Verify signature against authorized signer
// ⚠️ MVP STUB: Signature verification is NOT enforced on-chain in this contract.
// Calling EphemeralAccount::sweep() directly bypasses all authorization checks.
// Authorization is only enforced when going through SweepController, which
// performs Ed25519 signature verification via authorization.rs.
// TODO: Implement on-chain signature verification against an authorized signer
// before production use.
Ok(())
}

Expand Down
28 changes: 28 additions & 0 deletions contracts/native_transfer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "native_transfer"
version = "0.1.0"
edition = "2021"

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

[dependencies]
soroban-sdk = "22.0.0"
bridgelet-shared = { path = "../shared", version = "0.1.0" }

[dev-dependencies]
soroban-sdk = { version = "22.0.0", features = ["testutils"] }

[profile.release]
opt-level = "z"
overflow-checks = true
debug = 0
strip = "symbols"
debug-assertions = false
panic = "abort"
codegen-units = 1
lto = true

[profile.release-with-logs]
inherits = "release"
debug-assertions = true
8 changes: 8 additions & 0 deletions contracts/native_transfer/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use soroban_sdk::contracterror;

#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[repr(u32)]
pub enum Error {
Placeholder = 1,
}
2 changes: 2 additions & 0 deletions contracts/native_transfer/src/events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Events for the native_transfer contract.
// Emitted during transfer lifecycle: initiated, completed, failed, etc.
14 changes: 14 additions & 0 deletions contracts/native_transfer/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#![no_std]

mod errors;
mod events;
#[cfg(test)]
mod test;

use soroban_sdk::{contract, contractimpl};

#[contract]
pub struct NativeTransferContract;

#[contractimpl]
impl NativeTransferContract {}
4 changes: 4 additions & 0 deletions contracts/native_transfer/src/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#[cfg(test)]
mod test {
// TODO: Add contract tests
}
9 changes: 4 additions & 5 deletions contracts/sweep_controller/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,16 @@ impl SweepController {
env: Env,
authorized_signer: BytesN<32>,
authorized_destination: Option<Address>,
creator: Address,
) -> Result<(), Error> {
// Check if already initialized
if storage::get_authorized_signer(&env).is_some() {
return Err(Error::AuthorizationFailed);
}

// Store the creator address
// In Soroban SDK 22.0.0, we need to pass creator as a parameter
// For now, we'll use the contract address as a placeholder
// TODO: Update to accept creator as parameter if needed
let creator = env.current_contract_address();

// Verify and store the creator address
creator.require_auth();
storage::set_creator(&env, &creator);

// Store the authorized signer public key
Expand Down
Loading