-
Notifications
You must be signed in to change notification settings - Fork 27
Spike 1: Add Soroban Events for Indexer #69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: single-release-develop
Are you sure you want to change the base?
Changes from all commits
b70e8b6
74a68c6
c5ebfc9
34adb63
f034dad
b67b6fb
ac41203
cd94687
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| [package] | ||
| name = "Contract-Events-for-Indexer" | ||
| version = "0.0.0" | ||
| edition = "2021" | ||
| publish = false | ||
|
|
||
| [lib] | ||
| crate-type = ["cdylib"] | ||
|
|
||
| [dependencies] | ||
| soroban-sdk = { workspace = true } | ||
| soroban-token-sdk = { workspace = true } | ||
|
|
||
| [dev-dependencies] | ||
| soroban-sdk = { workspace = true, features = ["testutils"] } | ||
| soroban-token-sdk = { workspace = true } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # Spike 1 Findings: Adding Soroban Events | ||
|
|
||
| ## Overview | ||
|
|
||
| This spike focused on implementing comprehensive Soroban events for the Trustless Work Smart Escrow contract to enable better indexing and monitoring capabilities. The implementation adds structured events for all major contract operations including escrow creation, funding, milestone management, dispute handling, and fund releases. | ||
|
|
||
| ## Findings | ||
|
|
||
| - For each function that published an event, I needed to call a separate helper function to retrieve the current escrow state. | ||
| - Testing event publishing requires generating a contract ID. | ||
|
|
||
| ## Assumptions | ||
|
|
||
| - **Soroban SDK Compatibility**: Events use standard Soroban SDK event publishing methods | ||
| - **Data Type Compatibility**: All event data types (Address, i128, String) are compatible with Soroban events | ||
| - **Event Ordering**: Events are emitted after successful state changes to ensure consistency | ||
| - **Gas Efficiency**: Event data is optimized to minimize gas costs while providing necessary context | ||
| - **Indexer Compatibility**: Event structure follows Soroban indexing best practices | ||
|
|
||
| ## Recommendations | ||
|
|
||
| - **Add Error Event Handling**: Implement events for failed operations to help with debugging and monitoring | ||
| - **Event Validation**: Add tests specifically for event data structure and content validation | ||
| - **Event Documentation**: Create comprehensive documentation for indexers on event structure and data types | ||
| - **Event Versioning**: Consider adding event versioning for future contract upgrades | ||
| - **Event Filtering**: Implement event filtering capabilities for different use cases |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,195 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use soroban_sdk::{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contract, contractimpl, symbol_short, Address, BytesN, Env, String, Symbol, Val, Vec, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::core::{DisputeManager, EscrowManager, MilestoneManager}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::error::ContractError; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::storage::types::{AddressBalance, DataKey, Escrow}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[contract] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub struct EscrowContract; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[contractimpl] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| impl EscrowContract { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn __constructor(env: Env, admin: Address) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env.storage().instance().set(&DataKey::Admin, &admin); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn deploy( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: Env, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| deployer: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| wasm_hash: BytesN<32>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| salt: BytesN<32>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| init_fn: Symbol, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| init_args: Vec<Val>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| constructor_args: Vec<Val>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> (Address, Val) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if deployer != env.current_contract_address() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| deployer.require_auth(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let deployed_address = env | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .deployer() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .with_address(deployer, salt) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .deploy_v2(wasm_hash, constructor_args); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let res: Val = env.invoke_contract(&deployed_address, &init_fn, init_args); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (deployed_address, res) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //////////////////////// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Escrow ///// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //////////////////////// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn initialize_escrow(e: Env, escrow_properties: Escrow) -> Result<Escrow, ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let initialized_escrow = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EscrowManager::initialize_escrow(e.clone(), escrow_properties)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let escrow = initialized_escrow.clone(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.events().publish( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (symbol_short!("escrow"), symbol_short!("created")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (escrow.engagement_id, escrow.amount, escrow.roles.receiver) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(initialized_escrow) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn fund_escrow( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e: Env, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| signer: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| amount_to_deposit: i128, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<(), ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EscrowManager::fund_escrow(e.clone(), signer.clone(), amount_to_deposit)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let escrow = EscrowManager::get_escrow(e.clone())?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.events().publish( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (symbol_short!("escrow"), symbol_short!("funded")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (e.current_contract_address(), escrow.engagement_id, signer, amount_to_deposit) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn release_funds( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e: Env, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| release_signer: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| trustless_work_address: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<(), ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EscrowManager::release_funds( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| release_signer.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| trustless_work_address.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let escrow = EscrowManager::get_escrow(e.clone())?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.events().publish( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (symbol_short!("escrow"), symbol_short!("released")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (escrow.engagement_id, trustless_work_address) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn update_escrow( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e: Env, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| plataform_address: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| escrow_properties: Escrow, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<Escrow, ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let updated_escrow = EscrowManager::change_escrow_properties( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| plataform_address.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| escrow_properties.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(updated_escrow) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+87
to
+99
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. 🛠️ Refactor suggestion Add event emission for escrow updates The pub fn update_escrow(
e: Env,
- plataform_address: Address,
+ platform_address: Address,
escrow_properties: Escrow,
) -> Result<Escrow, ContractError> {
let updated_escrow = EscrowManager::change_escrow_properties(
e.clone(),
- plataform_address.clone(),
+ platform_address.clone(),
escrow_properties.clone(),
)?;
+ e.events().publish(
+ (symbol_short!("escrow"), symbol_short!("updated")),
+ (updated_escrow.engagement_id.clone(), platform_address)
+ );
Ok(updated_escrow)
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn get_escrow(e: Env) -> Result<Escrow, ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EscrowManager::get_escrow(e) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn get_escrow_by_contract_id( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e: Env, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contract_id: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<Escrow, ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EscrowManager::get_escrow_by_contract_id(e, &contract_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn get_multiple_escrow_balances( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e: Env, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| signer: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| addresses: Vec<Address>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<Vec<AddressBalance>, ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EscrowManager::get_multiple_escrow_balances(e, signer, addresses) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //////////////////////// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Milestones ///// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //////////////////////// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn change_milestone_status( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e: Env, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| milestone_index: i128, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new_status: String, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new_evidence: Option<String>, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| service_provider: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<(), ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MilestoneManager::change_milestone_status( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| milestone_index, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new_status.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new_evidence, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| service_provider, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let escrow = EscrowManager::get_escrow(e.clone())?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.events().publish( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (symbol_short!("escrow"), symbol_short!("marked")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (milestone_index, new_status, escrow.engagement_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn approve_milestone( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e: Env, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| milestone_index: i128, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new_flag: bool, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| approver: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<(), ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MilestoneManager::change_milestone_approved_flag(e.clone(), milestone_index, new_flag, approver)?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let escrow = EscrowManager::get_escrow(e.clone())?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.events().publish( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (symbol_short!("escrow"), symbol_short!("approved")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (milestone_index, new_flag, escrow.engagement_id)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //////////////////////// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Disputes ///// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //////////////////////// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn resolve_dispute( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e: Env, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dispute_resolver: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| approver_funds: i128, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| receiver_funds: i128, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| trustless_work_address: Address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Result<(), ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DisputeManager::resolve_dispute( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.clone(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dispute_resolver, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| approver_funds, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| receiver_funds, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| trustless_work_address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let escrow = EscrowManager::get_escrow(e.clone())?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.events().publish( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (symbol_short!("escrow"), symbol_short!("resolved")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (approver_funds, receiver_funds, escrow.engagement_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn dispute_escrow(e: Env, signer: Address) -> Result<(), ContractError> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DisputeManager::dispute_escrow(e.clone(), signer.clone())?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let escrow = EscrowManager::get_escrow(e.clone())?; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| e.events().publish( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (symbol_short!("escrow"), symbol_short!("raised")), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (signer, escrow.engagement_id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| use soroban_sdk::{Address, Env}; | ||
| use soroban_sdk::token::Client as TokenClient; | ||
|
|
||
| use crate::core::escrow::EscrowManager; | ||
| use crate::error::ContractError; | ||
| use crate::events::escrows_by_contract_id; | ||
| use crate::modules::{ | ||
| fee::{FeeCalculator, FeeCalculatorTrait}, | ||
| math::{BasicArithmetic, BasicMath}, | ||
| }; | ||
| use crate::storage::types::DataKey; | ||
|
|
||
| use super::validators::dispute::{ | ||
| validate_dispute_flag_change_conditions, validate_dispute_resolution_conditions, | ||
| }; | ||
|
|
||
| pub struct DisputeManager; | ||
|
|
||
| impl DisputeManager { | ||
| pub fn resolve_dispute( | ||
| e: Env, | ||
| dispute_resolver: Address, | ||
| approver_funds: i128, | ||
| receiver_funds: i128, | ||
| trustless_work_address: Address, | ||
| ) -> Result<(), ContractError> { | ||
| dispute_resolver.require_auth(); | ||
| let mut escrow = EscrowManager::get_escrow(e.clone())?; | ||
| let contract_address = e.current_contract_address(); | ||
|
|
||
| let token_client = TokenClient::new(&e, &escrow.trustline.address); | ||
|
|
||
| let total_funds = BasicMath::safe_add(approver_funds, receiver_funds)?; | ||
|
|
||
| if token_client.balance(&contract_address) < total_funds { | ||
| return Err(ContractError::InsufficientFundsForResolution); | ||
| } | ||
|
|
||
| let fee_result = FeeCalculator::calculate_dispute_fees( | ||
| approver_funds, | ||
| receiver_funds, | ||
| escrow.platform_fee as i128, | ||
| total_funds, | ||
| )?; | ||
|
|
||
| let current_balance = token_client.balance(&contract_address); | ||
| validate_dispute_resolution_conditions( | ||
| &escrow, | ||
| &dispute_resolver, | ||
| approver_funds, | ||
| receiver_funds, | ||
| total_funds, | ||
| &fee_result, | ||
| current_balance, | ||
| )?; | ||
|
|
||
| token_client.transfer(&contract_address, &trustless_work_address, &fee_result.trustless_work_fee); | ||
| token_client.transfer(&contract_address, &escrow.roles.platform_address, &fee_result.platform_fee); | ||
|
|
||
| if fee_result.net_approver_funds > 0 { | ||
| token_client.transfer(&contract_address, &escrow.roles.approver, &fee_result.net_approver_funds); | ||
| } | ||
|
|
||
| if fee_result.net_receiver_funds > 0 { | ||
| let receiver = EscrowManager::get_receiver(&escrow); | ||
| token_client.transfer(&contract_address, &receiver, &fee_result.net_receiver_funds); | ||
| } | ||
|
|
||
| escrow.flags.resolved = true; | ||
| escrow.flags.disputed = false; | ||
| e.storage().instance().set(&DataKey::Escrow, &escrow); | ||
|
|
||
| escrows_by_contract_id(&e, escrow.engagement_id.clone(), escrow); | ||
|
|
||
| Ok(()) | ||
| } | ||
|
|
||
| pub fn dispute_escrow(e: Env, signer: Address) -> Result<(), ContractError> { | ||
| signer.require_auth(); | ||
| let mut escrow = EscrowManager::get_escrow(e.clone())?; | ||
| validate_dispute_flag_change_conditions(&escrow, &signer)?; | ||
|
|
||
| escrow.flags.disputed = true; | ||
| e.storage().instance().set(&DataKey::Escrow, &escrow); | ||
|
|
||
| escrows_by_contract_id(&e, escrow.engagement_id.clone(), escrow); | ||
|
|
||
| Ok(()) | ||
| } | ||
| } |
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.
Fix typo in parameter name
The parameter name contains a typo: "plataform_address" should be "platform_address".
Also update the usage on line 94:
📝 Committable suggestion
🤖 Prompt for AI Agents