2.6. Collateral-Pegged Escrow
The Collateral-Pegged Escrow model forms the economic backbone of the Fhenix-FairMarket protocol. Traditional sealed-bid auctions suffer from sybil bidding, ghost participants, and seller manipulation, which degrade market efficiency and waste network resources.
Version 2.0 resolves this through a Dummy Ceiling Deposit architecture combined with encrypted solvency gates and automated penalty routing. Bidders must publicly lock a maximum spending ceiling before submitting encrypted bids, while sellers face strict financial penalties for premature cancellation. This ensures that every participant has verifiable capital backing their actions, without ever exposing their actual bid intentions or final settlement prices until cryptographic resolution.
Core Design Principles
| Principle | Technical Implementation |
|---|---|
| Dummy Ceiling Deposit | Participants invoke lockEscrow() to deposit a publicly visible maximum ceiling (e.g., 5 ETH). This amount acts as the upper bound for all encrypted bid validations. |
| Encrypted Solvency Gate | FHE.lte(encryptedBid, FHE.asEuint32(escrowBalances[msg.sender])) runs on-chain at submission. Bids exceeding the public ceiling revert instantly without revealing the true bid value. |
| Seller Accountability Penalties | If a seller invokes cancelAuction() during the ACTIVE phase, their entire sellerDeposit is confiscated and routed to SlashedPot.sol for pro-rata bidder compensation. |
| Zero Platform Extraction | The protocol takes 0% cut from cancellation penalties. 100% of confiscated seller deposits are distributed to affected bidders as gas/time compensation. |
| NFT Asset Locking | NFTGuard.sol atomically transfers and locks the seller’s asset during ACTIVE state. Transfer is mathematically blocked until FINALIZED, CANCELLED, or VOIDED. |
️ Technical Implementation
1. Public Escrow Lock & Solvency Validation
The escrow system decouples public capital commitment from private bid execution. Users lock funds once, then submit multiple encrypted bids against that balance without repeated transactions.
// packages/contracts/core/FhenixFairMarket.sol
/**
* @notice Locks public ceiling deposit for encrypted bidding
* @dev Non-reentrant, supports ETH/WETH
*/
function lockEscrow(uint256 auctionId) external payable nonReentrant {
require(auctions[auctionId].state == AuctionState.ACTIVE, "Auction not active");
require(msg.value > 0, "Zero deposit");
escrowBalances[auctionId][msg.sender] += msg.value;
lastBlockTimestamp = block.timestamp;
emit EscrowLocked(auctionId, msg.sender, msg.value);
}
/**
* @notice Encrypted bid submission with solvency gate
* @dev Reverts if encryptedBid > public escrow balance
*/
function placeBid(uint256 auctionId, InEuint32 calldata encryptedBid) external {
require(auctions[auctionId].state == AuctionState.ACTIVE, "Invalid state");
require(block.timestamp < auctions[auctionId].endTime, "Expired");
// Cryptographic solvency check (Zero plaintext leak)
FHE.lte(encryptedBid, FHE.asEuint32(escrowBalances[auctionId][msg.sender]));
bytes32 bidHash = keccak256(abi.encode(encryptedBid));
auctions[auctionId].ciphertextHashes.push(bidHash);
emit BidPlaced(auctionId, msg.sender, bidHash);
}2. Cancellation Penalty & Pro-Rata Distribution
When a seller aborts an active auction, the protocol enforces economic accountability. The confiscated deposit bypasses direct transfers and enters SlashedPot.sol for equitable distribution.
// packages/contracts/settlement/SlashedPot.sol
/**
* @notice Distributes seller cancellation penalty pro-rata to participants
* @dev Platform takes 0% cut. Funds go entirely to bidders.
*/
function distributePenalty(uint256 auctionId, address[] calldata bidders) external {
require(msg.sender == address(fairMarket), "Unauthorized");
uint256 penaltyAmount = auctions[auctionId].sellerDeposit;
uint256 participantCount = bidders.length;
require(participantCount > 0, "No bidders to compensate");
uint256 sharePerBidder = penaltyAmount / participantCount;
uint256 remainder = penaltyAmount % participantCount;
for (uint256 i = 0; i < participantCount; i++) {
uint256 payout = sharePerBidder + (i == 0 ? remainder : 0);
escrowBalances[auctionId][bidders[i]] += payout;
}
}3. NFT Asset Locking (NFTGuard.sol)
To prevent seller rug-pulls or double-spending, the NFT is transferred to a guarded vault upon auction creation.
function lockAsset(uint256 auctionId, address nftContract, uint256 tokenId) internal {
require(IERC721(nftContract).ownerOf(tokenId) == msg.sender, "Not owner");
IERC721(nftContract).safeTransferFrom(msg.sender, address(this), tokenId);
// NFT remains locked until state transitions to FINALIZED/CANCELLED/VOIDED
emit AssetLocked(auctionId, nftContract, tokenId);
}️ Security & Economic Alignment
| Threat Vector | Attack Mechanism | Escrow Protocol Mitigation |
|---|---|---|
| Sybil Bidding / Ghost Participants | Fake accounts spamming bids to manipulate perceived demand | lockEscrow() requires upfront capital; empty wallets cannot participate |
| Seller Rug-Pull / Double-Sell | Seller transfers NFT away after auction starts | NFTGuard.sol atomically locks asset; IERC721 approval checks enforce custody |
| Bid Overextension / Insolvency | User submits encrypted bid > actual wallet balance | FHE.lte solvency gate reverts instantly; no gas wasted on invalid bids |
| Seller Manipulation (Shill Bidding) | Seller artificially inflates price via fake bids | Cancellation penalty (100% deposit to bidders) makes manipulation economically irrational |
| Fund Trapping on Cancellation | Seller cancels, protocol holds deposits hostage | SlashedPot pro-rata distribution unlocks immediately; 0% platform fee ensures fairness |
Architectural Impact
| Metric | Traditional Escrow Model | Fhenix-FairMarket Collateral-Pegged |
|---|---|---|
| Capital Commitment | Full bid amount locked per transaction | Single ceiling deposit funds multiple encrypted bids |
| Seller Accountability | Often lacks financial disincentives for cancellation | 100% deposit penalty routed to bidders via SlashedPot |
| Platform Fee Extraction | Often takes 2-5% cut from penalties/refunds | 0% platform cut on cancellations; aligns protocol with user trust |
| Solvency Verification | Requires plaintext balance checks or oracle feeds | Encrypted FHE.lte validates capacity without exposing financial position |
| Asset Security | NFT held in standard escrow, vulnerable to proxy exploits | NFTGuard.sol + state-locked transfers prevents premature movement |
Audit Gate Compliance (P0)
The protocol enforces strict escrow and penalty verification gates. Progression to subsequent phases is blocked until all P0 items pass:
- [] Encrypted Solvency Enforcement:
FHE.lte(encryptedBid, escrowBalances)reverts any bid exceeding the public ceiling; no bypass paths exist. - [] Zero Platform Penalty Cut:
SlashedPot.soldistributes 100% of seller cancellation deposits to participants; administrative fees are strictly excluded. - [] NFT Atomic Locking:
createAuction()fails ifIERC721approval or transfer does not complete; asset custody is mathematically guaranteed. - [] Pro-Rata Distribution Integrity: Penalty shares are calculated deterministically; remainder logic prevents fractional ETH dust loss.
- [] State-Gated Refund Unlock:
claimRefund()only activates afterFINALIZED,CANCELLED, orVOIDED; premature withdrawals revert. - [] Zero Plaintext Leakage: Escrow balances and bid solvency checks execute without emitting or storing plaintext bid values.
Next Steps
- Proceed to 3. Market Mechanics to explore how escrow-backed bids enable sealed-bid workflows, Vickrey pricing, and MEV protection.
- Review Technical Components → SlashedPot.sol for compensation routing, remainder handling, and payout mapping.
- Explore Security Model → Threat Matrix for sybil bidding, seller manipulation, and capital trap mitigations.