Skip to content

docs: Fix typo in "lock time" in Zk Proof Update settlement.md#3

Open
famouswizard wants to merge 1 commit into0gfoundation:mainfrom
famouswizard:patch-1
Open

docs: Fix typo in "lock time" in Zk Proof Update settlement.md#3
famouswizard wants to merge 1 commit into0gfoundation:mainfrom
famouswizard:patch-1

Conversation

@famouswizard
Copy link

Description:

I’ve noticed a small typo in the section Zk Proof on the Provider Side where "lock time" was written without a hyphen. The correct format should be "lock-time" as it’s commonly used as a compound adjective to describe lock time, and adding the hyphen enhances readability.

Here’s the fix:

  • lock-time: Lock-time

Ravenyjh added a commit that referenced this pull request Feb 9, 2026
Standardize deliverable ID validation logic between FineTuningAccount
and FineTuningVerifier to ensure consistency:

Problem:
- FineTuningAccount.sol: checks both empty (length == 0) and too long
- FineTuningVerifier.sol: only checks too long, allows empty ID
- Different error names: DeliverableIdInvalidLength vs DeliverableIdTooLong
- Inconsistent validation could lead to confusing error messages

Changes:
1. Rename error: DeliverableIdTooLong → DeliverableIdInvalidLength
2. Add empty ID check in FineTuningVerifier
3. Update validation logic to match FineTuningAccount

Before:
```solidity
// FineTuningVerifier.sol
if (bytes(input.id).length > MAX_DELIVERABLE_ID_LENGTH) {
    revert DeliverableIdTooLong(bytes(input.id).length);
}
// Allows empty ID (length == 0)
```

After:
```solidity
// FineTuningVerifier.sol
uint256 idLength = bytes(input.id).length;
if (idLength == 0 || idLength > MAX_DELIVERABLE_ID_LENGTH) {
    revert DeliverableIdInvalidLength(idLength);
}
// Rejects empty ID, consistent with FineTuningAccount
```

Benefits:
- Consistent validation across all contracts
- Unified error naming convention
- Better error messages for developers
- Prevents settlement with empty deliverable ID

Impact:
- Empty deliverable IDs now rejected earlier (at signature verification)
- Error message more informative (includes actual length)
- No breaking changes (empty IDs would fail later anyway)

Addresses: Issue #3 (LOW - ID validation inconsistency)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Ravenyjh added a commit that referenced this pull request Feb 10, 2026
* fix: prevent double settlement of the same deliverable

Add 'settled' flag to Deliverable struct to prevent a deliverable
from being settled multiple times. This prevents the scenario where
a compromised or malicious TEE could sign multiple settlement
requests for the same deliverable, causing users to be charged
multiple times.

Changes:
- Add `settled` bool field to Deliverable struct (new storage slot)
- Check `settled` flag before processing settlement in settleFees()
- Set `settled = true` after successful settlement
- Initialize `settled = false` when creating new deliverables

Storage layout: Safe - new field appended at end of struct,
occupies new slot. Existing deliverables default to false (correct).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: prevent acknowledging deliverables after settlement

Add validation to prevent users from acknowledging deliverables
after they have been settled. This maintains state consistency and
prevents misleading state where a deliverable appears acknowledged
but was actually settled with penalty.

Changes:
- Add CannotAcknowledgeSettledDeliverable error
- Check deliverable.settled before allowing acknowledgement
- Ensures deliverables can only be acknowledged before settlement

Rationale:
While this doesn't cause financial loss (settlement is irreversible),
it prevents state confusion where:
1. Provider settles with penalty (acknowledged=false)
2. User later acknowledges (acknowledged=true)
3. State shows acknowledged but penalty was already charged

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat: add events for deliverable and fee settlement tracking

Add comprehensive event emissions for off-chain monitoring:

- Add DeliverableAdded event in addDeliverable()
- Add DeliverableAcknowledged event in acknowledgeDeliverable()
- Add FeesSettled event in settleFees() with detailed settlement info
- Add RefundRequested event in requestRefundAll()

These events improve observability for:
- Users monitoring when providers complete tasks
- Providers tracking user acknowledgements
- Off-chain systems distinguishing fee settlements from balance changes
- Refund request monitoring

Benefits:
- Better UX through real-time notifications
- Accurate settlement history tracking with deliverableId, fee, nonce
- Consistent with Inference contract event patterns

Gas impact: <1% per operation (~5-7k gas per emit)

Fixes: #4, #5, #6, #7 (MEDIUM priority issues)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: correct event parameter naming and add DeliverableEvicted event

Fix event parameter naming issues and add missing eviction tracking:

1. Fix ServiceUpdated and ServiceRemoved event parameter naming
   - Change parameter name from 'user' to 'provider' to match actual semantics
   - These events are emitted with msg.sender (provider) as first parameter
   - Improves code readability and consistency with other provider events

2. Add DeliverableEvicted event for FIFO eviction tracking
   - Emitted when deliverable array is full (20 items) and oldest is evicted
   - Includes evicted deliverable ID and new deliverable ID
   - Enables off-chain monitoring of deliverable lifecycle

3. Modify addDeliverable() to return eviction status
   - Returns (bool evicted, string memory evictedId)
   - Allows FineTuningServing to emit DeliverableEvicted event

Changes maintain consistency with Inference contract patterns:
- Keep (user, provider) parameter order for account operations
- Use 'provider' naming for service-related operations

Benefits:
- Clear parameter naming reduces confusion
- Complete deliverable lifecycle tracking
- No breaking changes (parameter names don't affect ABI)

Fixes: Issue #11 (LOW - ServiceUpdated event parameter naming)
Fixes: Issue #12 (LOW - Missing DeliverableEvicted event)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: replace require with custom errors and reduce batch size limit

Replace require statements with gas-efficient custom errors and lower
batch query limit to prevent DoS attacks:

1. Replace require with custom errors
   - Add CallerNotLedger error in FineTuningServing.sol
   - Add BatchSizeTooLarge(size, maxSize) error in FineTuningAccount.sol
   - Replace require in onlyLedger modifier with revert CallerNotLedger()
   - Replace require in getBatchAccountsByUsers with revert BatchSizeTooLarge()

2. Reduce batch query limit (DoS prevention)
   - Lower getBatchAccountsByUsers limit: 500 → 50
   - Prevents RPC node DoS via expensive batch queries
   - Reduces gas cost per call by ~90% (from ~100k to ~10k gas)

Benefits:
- Gas savings: Custom errors use ~26 gas less than require strings
- Better error handling: Typed errors with parameters (size, maxSize)
- DoS prevention: 10x higher attack cost for batch queries
- Improved RPC performance: Lower per-query gas consumption

Breaking change: Callers using batch size > 50 must implement pagination

Gas impact:
- Custom errors: ~26 gas savings per error
- Batch limit: ~90% reduction in max query gas cost

Addresses: Issue #2 (MEDIUM - DoS via unbounded batch operations)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: prevent eviction of unsettled deliverables

Add settlement check before deliverable eviction to protect provider
settlement rights and prevent fund locking:

Problem:
- Deliverable array limit: 20 items (circular buffer)
- When adding 21st deliverable, oldest is evicted via FIFO
- Previous logic only checked 'acknowledged', not 'settled'
- If deliverable was acknowledged but not settled, eviction caused:
  * Provider permanently loses settlement rights
  * User balance locked (acknowledged = payment obligation exists)
  * No way to settle evicted deliverable (deleted from mapping)

Solution:
1. Add CannotEvictUnsettledDeliverable custom error
2. Check oldest.settled before eviction
3. Revert if attempting to evict unsettled deliverable
4. Force provider to settle old tasks before adding new ones

Eviction requirements (both must be true):
- acknowledged == true (guaranteed by serial task execution)
- settled == true (new check added)

Benefits:
- Protects provider settlement rights for acknowledged tasks
- Prevents user balance from being locked indefinitely
- Incentivizes providers to settle tasks promptly
- Maintains business logic: acknowledged task = settleable

Test updates:
- Modified "circular array strategy" test
- Now settles first 2 deliverables before adding 21st
- Ensures evicted deliverables are properly settled

Business impact:
- Providers must settle within 20-task window
- Recommended: settle every 5-10 tasks to avoid hitting limit
- Breaking change: cannot accumulate 20+ unsettled tasks

Gas impact: +~5k gas when eviction occurs (1 extra SLOAD for settled check)

Addresses: Issue #11 (MEDIUM - Unsettled deliverable eviction)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: unify deliverable ID validation across contracts

Standardize deliverable ID validation logic between FineTuningAccount
and FineTuningVerifier to ensure consistency:

Problem:
- FineTuningAccount.sol: checks both empty (length == 0) and too long
- FineTuningVerifier.sol: only checks too long, allows empty ID
- Different error names: DeliverableIdInvalidLength vs DeliverableIdTooLong
- Inconsistent validation could lead to confusing error messages

Changes:
1. Rename error: DeliverableIdTooLong → DeliverableIdInvalidLength
2. Add empty ID check in FineTuningVerifier
3. Update validation logic to match FineTuningAccount

Before:
```solidity
// FineTuningVerifier.sol
if (bytes(input.id).length > MAX_DELIVERABLE_ID_LENGTH) {
    revert DeliverableIdTooLong(bytes(input.id).length);
}
// Allows empty ID (length == 0)
```

After:
```solidity
// FineTuningVerifier.sol
uint256 idLength = bytes(input.id).length;
if (idLength == 0 || idLength > MAX_DELIVERABLE_ID_LENGTH) {
    revert DeliverableIdInvalidLength(idLength);
}
// Rejects empty ID, consistent with FineTuningAccount
```

Benefits:
- Consistent validation across all contracts
- Unified error naming convention
- Better error messages for developers
- Prevents settlement with empty deliverable ID

Impact:
- Empty deliverable IDs now rejected earlier (at signature verification)
- Error message more informative (includes actual length)
- No breaking changes (empty IDs would fail later anyway)

Addresses: Issue #3 (LOW - ID validation inconsistency)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: mark Refund.processed as deprecated field

Rename unused Refund.processed field to _deprecated_processed to clearly
indicate it's a legacy field kept only for storage layout compatibility:

Problem:
- Refund struct has 'processed' field that is never read or used
- Created with value 'false' in 4 locations but never accessed
- Wastes ~20k gas per refund for unused storage
- Misleading name suggests it has functionality
- Could confuse developers into thinking it's actively used

Changes:
1. Rename: processed → _deprecated_processed
2. Add inline comment: "Legacy field kept for storage layout compatibility, do not use"
3. Update documentation to reference new field name

Why keep the field:
- Solidity struct storage layout is fixed
- Removing field would shift storage slots of subsequent data
- Could cause data corruption during contract upgrades
- Better to mark as deprecated than risk storage conflicts

Storage layout (preserved):
```
Refund {
    uint index;                      // slot 0
    uint amount;                     // slot 1
    uint createdAt;                  // slot 2
    bool _deprecated_processed;      // slot 3 (packed)
}
```

Naming convention:
- _deprecated_ prefix clearly signals legacy field
- Prevents accidental usage by developers
- IDEs highlight underscore-prefixed fields
- Follows Solidity deprecation best practices

Field usage:
- Initialized to 'false' in 4 locations (lines 491, 495, 519, 523)
- Never read after creation
- No impact on business logic
- Pure storage overhead

Benefits:
- Clearer code intent and documentation
- Prevents developer confusion
- Maintains storage compatibility
- No functional changes
- All tests pass unchanged

Future considerations:
- Could reuse this storage slot for new data in upgrades
- Or remove entirely with proper migration strategy
- Current approach maximizes compatibility

Gas impact: None (field still initialized, just renamed)
Breaking changes: None (storage layout unchanged)

Addresses: Issue #8 (LOW - Unused Refund.processed field)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(fine-tuning): remove duplicate error definition DeliverableIdInvalidLength

* chore(fine-tuning): upgrade fine-tuning dev contract

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant