Skip to content

Commit 03d047d

Browse files
authored
Merge pull request #773 from OsejiFabian/pr/all-issues-implementation
Pr/all issues implementation
2 parents 1f4881b + c6767c8 commit 03d047d

File tree

6 files changed

+1838
-3
lines changed

6 files changed

+1838
-3
lines changed
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# Bidding Documentation
2+
3+
## Overview
4+
5+
This document describes the bidding mechanism in the QuickLendX protocol, focusing on bid validation rules and protocol minimum enforcement as implemented in issue #719.
6+
7+
## Bid Validation
8+
9+
### Bid Structure
10+
11+
A bid in QuickLendX contains the following key components:
12+
13+
```rust
14+
pub struct Bid {
15+
pub bid_id: BytesN<32>, // Unique identifier for the bid
16+
pub invoice_id: BytesN<32>, // Associated invoice
17+
pub investor: Address, // Investor address
18+
pub bid_amount: i128, // Amount being bid
19+
pub expected_return: i128, // Expected return for investor
20+
pub timestamp: u64, // Bid creation time
21+
pub expiration_timestamp: u64, // Bid expiration time
22+
pub status: BidStatus, // Current bid status
23+
}
24+
```
25+
26+
### Bid Status Lifecycle
27+
28+
```rust
29+
pub enum BidStatus {
30+
Placed, // Bid is active and can be accepted
31+
Withdrawn, // Bid was withdrawn by investor
32+
Accepted, // Bid was accepted and investment created
33+
Expired, // Bid expired without acceptance
34+
}
35+
```
36+
37+
## Protocol Minimum Enforcement
38+
39+
### Minimum Bid Calculation
40+
41+
The protocol enforces a minimum bid amount using both absolute and percentage-based constraints:
42+
43+
```rust
44+
let percent_min = invoice.amount
45+
.saturating_mul(limits.min_bid_bps as i128)
46+
.saturating_div(10_000);
47+
48+
let effective_min_bid = if percent_min > limits.min_bid_amount {
49+
percent_min // Use percentage minimum if higher
50+
} else {
51+
limits.min_bid_amount // Use absolute minimum otherwise
52+
};
53+
```
54+
55+
### Protocol Limits
56+
57+
The protocol maintains configurable minimum bid parameters:
58+
59+
```rust
60+
pub struct ProtocolLimits {
61+
pub min_bid_amount: i128, // Absolute minimum bid amount
62+
pub min_bid_bps: u32, // Minimum bid as percentage (basis points)
63+
// ... other limits
64+
}
65+
```
66+
67+
**Default Values:**
68+
- `min_bid_amount`: 10 (smallest unit)
69+
- `min_bid_bps`: 100 (1% of invoice amount)
70+
71+
### Validation Rules
72+
73+
#### 1. Amount Validation
74+
- **Non-zero**: Bid amount must be > 0
75+
- **Minimum Enforcement**: Must meet or exceed `effective_min_bid`
76+
- **Invoice Cap**: Cannot exceed total invoice amount
77+
78+
#### 2. Invoice Status Validation
79+
- **Verified Only**: Invoice must be in `Verified` status
80+
- **Not Expired**: Invoice due date must be in the future
81+
82+
#### 3. Ownership Validation
83+
- **No Self-Bidding**: Business cannot bid on own invoices
84+
- **Authorization**: Only verified investors can place bids
85+
86+
#### 4. Investor Capacity
87+
- **Investment Limits**: Total active bids cannot exceed investor's verified limit
88+
- **Risk Assessment**: Bid amount considered against investor's risk profile
89+
90+
#### 5. Bid Protection
91+
- **Single Active Bid**: One investor cannot have multiple active bids on same invoice
92+
- **Expiration Handling**: Expired bids are automatically cleaned up
93+
94+
## Bid Placement Flow
95+
96+
### 1. Pre-Validation
97+
```rust
98+
validate_bid(env, invoice, bid_amount, expected_return, investor)?;
99+
```
100+
101+
### 2. Bid Creation
102+
```rust
103+
let bid_id = BidStorage::generate_unique_bid_id(env);
104+
let bid = Bid {
105+
bid_id,
106+
invoice_id,
107+
investor,
108+
bid_amount,
109+
expected_return,
110+
timestamp: env.ledger().timestamp(),
111+
expiration_timestamp: env.ledger().timestamp() + bid_ttl_seconds,
112+
status: BidStatus::Placed,
113+
};
114+
```
115+
116+
### 3. Storage
117+
```rust
118+
BidStorage::store_bid(env, &bid);
119+
BidStorage::add_bid_to_invoice_index(env, &invoice_id, &bid_id);
120+
BidStorage::add_bid_to_investor_index(env, &investor, &bid_id);
121+
```
122+
123+
## Bid Selection and Ranking
124+
125+
### Best Bid Selection
126+
The protocol selects the best bid based on:
127+
128+
1. **Profit Priority**: Higher expected return (profit = expected_return - bid_amount)
129+
2. **Return Amount**: Higher expected return if profit equal
130+
3. **Bid Amount**: Higher bid amount if profit and return equal
131+
4. **Timestamp**: Newer bids preferred (deterministic tiebreaker)
132+
5. **Bid ID**: Final stable tiebreaker
133+
134+
### Ranking Algorithm
135+
```rust
136+
pub fn compare_bids(bid1: &Bid, bid2: &Bid) -> Ordering {
137+
let profit1 = bid1.expected_return.saturating_sub(bid1.bid_amount);
138+
let profit2 = bid2.expected_return.saturating_sub(bid2.bid_amount);
139+
140+
// Compare by profit, then return, then amount, then timestamp, then bid_id
141+
// This ensures reproducible ranking across all validators
142+
}
143+
```
144+
145+
## Security Considerations
146+
147+
### Reentrancy Protection
148+
- All bid modifications require proper authorization
149+
- State transitions are atomic
150+
- External calls minimized during validation
151+
152+
### Access Control
153+
- **Investor Authorization**: `investor.require_auth()` for bid placement
154+
- **Business Authorization**: `business.require_auth()` for invoice operations
155+
- **Admin Authorization**: `AdminStorage::require_admin()` for protocol changes
156+
157+
### Input Validation
158+
- **Amount Bounds**: Prevents overflow and underflow
159+
- **Timestamp Validation**: Ensures logical time progression
160+
- **Address Validation**: Prevents invalid address usage
161+
162+
## Gas Optimization
163+
164+
### Efficient Storage
165+
- **Indexed Storage**: Fast lookup by invoice, investor, and status
166+
- **Batch Operations**: Multiple bids processed in single transaction
167+
- **Cleanup Routines**: Automatic removal of expired bids
168+
169+
### Minimal Computations
170+
- **Saturating Arithmetic**: Prevents overflow without expensive checks
171+
- **Lazy Evaluation**: Calculations deferred until needed
172+
- **Constants**: Pre-computed values where possible
173+
174+
## Testing Coverage
175+
176+
### Unit Tests
177+
- **Validation Logic**: All validation rules tested
178+
- **Edge Cases**: Boundary conditions and error scenarios
179+
- **Protocol Limits**: Custom limit configurations tested
180+
- **Integration Tests**: End-to-end bid placement flows
181+
182+
### Test Coverage Requirements
183+
- **95% Coverage**: All bid validation paths tested
184+
- **Error Paths**: All error conditions validated
185+
- **Success Paths**: All valid bid scenarios covered
186+
- **Edge Cases**: Boundary values and special conditions
187+
188+
## Event Emission
189+
190+
### Bid Events
191+
```rust
192+
// Events emitted during bid lifecycle
193+
emit_bid_placed(env, &bid_id, &invoice_id, &investor, bid_amount);
194+
emit_bid_accepted(env, &bid_id, &invoice_id, &investor, bid_amount);
195+
emit_bid_withdrawn(env, &bid_id, &invoice_id, &investor, bid_amount);
196+
emit_bid_expired(env, &bid_id, &invoice_id, &investor, bid_amount);
197+
```
198+
199+
### Audit Trail
200+
- All bid state transitions are logged
201+
- Timestamps recorded for all operations
202+
- Authorization verified for all state changes
203+
204+
## Configuration
205+
206+
### Bid TTL (Time-To-Live)
207+
- **Default**: 7 days from placement
208+
- **Configuration**: Set by admin via `set_bid_ttl`
209+
- **Cleanup**: Automatic expiration and status updates
210+
211+
### Maximum Active Bids
212+
- **Default**: 10 per investor
213+
- **Purpose**: Prevents spam and manages risk
214+
- **Enforcement**: Checked during bid placement
215+
216+
## Migration Notes
217+
218+
### Backward Compatibility
219+
- Existing bids remain valid under previous rules
220+
- New protocol limits apply to future bids
221+
- Storage format unchanged for existing data
222+
223+
### Upgrade Path
224+
- Protocol limits can be updated by admin
225+
- Bid validation logic can be enhanced without breaking changes
226+
- New bid statuses can be added via enum extension
227+
228+
## Best Practices
229+
230+
### For Investors
231+
- **Due Diligence**: Verify invoice details before bidding
232+
- **Risk Management**: Don't exceed investment capacity
233+
- **Timing**: Place bids well before expiration
234+
- **Monitoring**: Track active bids and their status
235+
236+
### For Businesses
237+
- **Verification**: Ensure invoice is verified before expecting bids
238+
- **Terms**: Clear payment terms and due dates
239+
- **Communication**: Respond to appropriate bids promptly
240+
241+
### For Protocol Developers
242+
- **Validation**: Centralize bid validation logic
243+
- **Testing**: Comprehensive test coverage for all scenarios
244+
- **Documentation**: Clear NatSpec comments for all functions
245+
- **Security**: Regular security audits of bid logic

0 commit comments

Comments
 (0)