-
-
Notifications
You must be signed in to change notification settings - Fork 8
provide investment information #20
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| use soroban_sdk::{Address, Env, Symbol, Vec}; | ||
|
|
||
| use crate::{AuctionData, ReserveConfig}; | ||
| use soroban_sdk::{Address, Env, Symbol}; | ||
|
|
||
| pub struct PoolEvents {} | ||
|
|
||
|
|
@@ -373,4 +374,26 @@ impl PoolEvents { | |
| let topics = (Symbol::new(&e, "delete_auction"), auction_type, user); | ||
| e.events().publish(topics, ()); | ||
| } | ||
|
|
||
| pub fn investment_made(e: &Env, lender: &Address, amount: i128, timestamp: u64) { | ||
| // Topic: ("InvestmentMade", lender) | ||
| e.events().publish( | ||
| (Symbol::short("InvestmentMade"), lender.clone()), | ||
| (amount, timestamp), | ||
| ); | ||
| } | ||
|
|
||
| pub fn rewards_distributed(e: &Env, lender: &Address, amount: i128) { | ||
| e.events().publish( | ||
| (Symbol::short("RewardsDistributed"), lender.clone()), | ||
| amount, | ||
| ); | ||
| } | ||
|
|
||
| pub fn withdrawal_made(e: &Env, lender: &Address, amount: i128, timestamp: u64) { | ||
| e.events().publish( | ||
| (Symbol::short("WithdrawalMade"), lender.clone()), | ||
| (amount, timestamp), | ||
| ); | ||
| } | ||
|
Comment on lines
+378
to
+398
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace
π€ Prompt for AI Agents |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,15 @@ const LEDGER_BUMP_USER: u32 = LEDGER_THRESHOLD_USER + 20 * ONE_DAY_LEDGERS; // ~ | |
|
|
||
| /********** Storage Types **********/ | ||
|
|
||
| #[derive(Clone, Debug)] | ||
| #[contracttype] // Important for Soroban storage serialization | ||
| pub struct Investment { | ||
| pub amount: i128, // Supplied amount | ||
| pub timestamp: u64, // Block timestamp when investment was made | ||
| pub returns: i128, // Accumulated rewards/earnings | ||
| pub status: u32, // 0 = active, 1 = withdrawn | ||
| } | ||
|
|
||
| /// The pool's config | ||
| #[derive(Clone)] | ||
| #[contracttype] | ||
|
|
@@ -659,3 +668,75 @@ pub fn del_auction(e: &Env, auction_type: &u32, user: &Address) { | |
| }); | ||
| e.storage().temporary().remove(&key); | ||
| } | ||
|
|
||
| //investment | ||
| // Storage key prefix symbols | ||
| const KEY_LENDER_INVESTMENTS: Symbol = Symbol::short("lender_invs"); // (lender -> Vec<Investment>) | ||
| const KEY_LENDER_TOTAL_BAL: Symbol = Symbol::short("lender_bal"); // (lender -> i128) | ||
| const KEY_LENDER_TOTAL_REW: Symbol = Symbol::short("lender_rew"); // (lender -> i128) | ||
|
|
||
| /// Return the investments vec for a lender (or an empty Vec if not set). | ||
| pub fn get_lender_investments(e: &Env, lender: &Address) -> Vec<Investment> { | ||
| let key = (KEY_LENDER_INVESTMENTS.clone(), lender.clone()); | ||
| e.storage() | ||
| .instance() | ||
| .get(&key) | ||
| .unwrap_or_else(|_| Vec::new(e)) | ||
| } | ||
|
|
||
| /// Persist the investments vec for a lender. | ||
| pub fn set_lender_investments(e: &Env, lender: &Address, invs: &Vec<Investment>) { | ||
| let key = (KEY_LENDER_INVESTMENTS.clone(), lender.clone()); | ||
| e.storage().instance().set(&key, invs); | ||
| } | ||
|
|
||
| /// Append a new investment to a lender's investment vector and persist. | ||
| pub fn add_lender_investment(e: &Env, lender: &Address, inv: &Investment) { | ||
| let mut vec = get_lender_investments(e, lender); | ||
| vec.push_back(inv.clone()); | ||
| set_lender_investments(e, lender, &vec); | ||
| } | ||
|
|
||
| /// Get lender total balance (aggregated active amounts). Returns 0 if none. | ||
| pub fn get_lender_total_balance(e: &Env, lender: &Address) -> i128 { | ||
| let key = (KEY_LENDER_TOTAL_BAL.clone(), lender.clone()); | ||
| e.storage() | ||
| .instance() | ||
| .get(&key) | ||
| .unwrap_or(Ok(0i128)) | ||
| .unwrap() | ||
| } | ||
|
|
||
| /// Set lender total balance. | ||
| pub fn set_lender_total_balance(e: &Env, lender: &Address, bal: &i128) { | ||
| let key = (KEY_LENDER_TOTAL_BAL.clone(), lender.clone()); | ||
| e.storage().instance().set(&key, bal); | ||
| } | ||
|
|
||
| /// Increase lender total balance by delta (can be negative to decrease). | ||
| pub fn inc_lender_total_balance(e: &Env, lender: &Address, delta: i128) { | ||
| let cur = get_lender_total_balance(e, lender); | ||
| set_lender_total_balance(e, lender, &(cur + delta)); | ||
| } | ||
|
|
||
| /// Get lender total rewards (aggregated). Returns 0 if none. | ||
| pub fn get_lender_total_rewards(e: &Env, lender: &Address) -> i128 { | ||
| let key = (KEY_LENDER_TOTAL_REW.clone(), lender.clone()); | ||
| e.storage() | ||
| .instance() | ||
| .get(&key) | ||
| .unwrap_or(Ok(0i128)) | ||
| .unwrap() | ||
| } | ||
|
|
||
| /// Set lender total rewards. | ||
| pub fn set_lender_total_rewards(e: &Env, lender: &Address, rew: &i128) { | ||
| let key = (KEY_LENDER_TOTAL_REW.clone(), lender.clone()); | ||
| e.storage().instance().set(&key, rew); | ||
| } | ||
|
|
||
| /// Increase lender total rewards by delta. | ||
| pub fn inc_lender_total_rewards(e: &Env, lender: &Address, delta: i128) { | ||
| let cur = get_lender_total_rewards(e, lender); | ||
| set_lender_total_rewards(e, lender, &(cur + delta)); | ||
| } | ||
|
Comment on lines
+674
to
+742
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
π€ Prompt for AI Agents |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Investment mutators need authentication or non-public exposure
record_investment,add_rewards, andwithdraw_investmentare now in the publicPooltrait (Lines 620-699), so anyone can invoke them directly. None of them callrequire_auth, which lets an attacker (1) credit themselves arbitrary balances viarecord_investment, (2) mint rewards withadd_rewards, or (3) zero out another lenderβs position usingwithdraw_investment. This is a critical authorization hole. Either keep these helpers internal (remove from the trait) or gate them with the appropriaterequire_authchecks aligned with the supply/reward flows.