A block-based auction system for Silo Protocol liquidation rights using WETH.
This project implements a competitive auction system for Silo Protocol liquidations. Users bid for the exclusive right to liquidate underwater positions, with each auction running for approximately 20 minutes (100 blocks). The highest bidder from the previous auction becomes the authorized liquidator for borrowers in the current period.
- Per-borrower auction system (each borrower has a separate auction)
- Block-based auction periods (100 blocks ≈ 20 minutes)
- Immediate refunds when outbid
- Prevention of self-bidding (borrowers cannot bid on their own liquidation)
- Integration with Silo Protocol via hook interface
/contracts
: Smart contract implementationLiquidationAuctionHook.sol
: Main auction contract/errors
: Custom error definitions
/test
: Comprehensive test suiteLiquidationAuctionHookArbitrumTest.t.sol
: Main test file/common
: Shared testing utilities
- Foundry
- Node.js and npm
git clone https://github.com/your-username/silo-liquidation-auction-hook.git
cd silo-liquidation-auction-hook
forge install
forge test
- Auction Periods: Each auction runs for 100 blocks (approximately 20 minutes).
- Bidding: Users bid with WETH for the right to liquidate a specific borrower.
- Winning: The highest bidder at the end of an auction becomes the authorized liquidator for the next period.
- Liquidation: Only the authorized liquidator can perform liquidations for a borrower.
- No Winner Case: If an auction has no bids, anyone can liquidate in the following period.
See CONTRACT_DOCS.md for detailed contract documentation.
See TEST_DOCS.md for details on the test suite and coverage.
MIT
A block-based auction system for Silo Protocol liquidation rights using WETH.
Initializable
: Prevents multiple initializationsReentrancyGuard
: Prevents re-entrancy attacksOwnable2Step
: Secure two-step ownership transferBaseHookReceiver
: Base functionality for Silo hooksPartialLiquidation
: Support for partial liquidations in Silo
AUCTION_BLOCKS
: Number of blocks per auction (100 blocks ≈ 20 minutes)
borrowerAuctions
: Mapping of borrower => auction number => auction detailsfeeReceiver
: Address that receives fees (set on initialization)weth
: WETH token used for bidding
BidPlaced
: Emitted when a bid is placedRefundIssued
: Emitted when a previous bidder is refundedLiquidationExecuted
: Emitted when a liquidation is executedFeesCollected
: Emitted when fees are collected
BidTooLow
: Thrown when a bid is not higher than the current highest bidUnauthorizedLiquidator
: Thrown when an unauthorized address attempts liquidationSelfBiddingNotAllowed
: Thrown when a borrower tries to bid on their own liquidation
getCurrentAuctionNumber()
: Returns the current auction number based on block numbergetBlocksRemaining()
: Returns the number of blocks remaining in the current auctiongetAuthorizedLiquidator(address _borrower)
: Returns the authorized liquidator for a borrowergetCurrentBidder(address _borrower)
: Returns the current highest bidder for a borrower
initialize(ISiloConfig _siloConfig, bytes calldata _data)
: Initializes the contractplaceBid(address _borrower, uint256 bidAmount)
: Places a bid for liquidation rightscollectFees()
: Collects fees (not supported in the simplified model)
beforeAction(address _silo, uint256 _action, bytes calldata _input)
: Hook called before an actionafterAction(address _silo, uint256 _action, bytes calldata _inputAndOutput)
: Hook called after an actionhookReceiverConfig(address _silo)
: Returns the hook configuration for a silo
_configureHooks()
: Configures hooks for liquidation actions on both silos
- ReentrancyGuard is used for all state-changing external functions
- Ownable2Step is used for secure ownership transfers
- SafeERC20 is used for secure token transfers
- Zero-address checks are performed during initialization
Comprehensive test suite for the LiquidationAuctionHook contract using an Arbitrum fork.
- Bidding Tests: Verify basic and edge case bidding scenarios
- Auction Lifecycle Tests: Test auction progression and state transitions
- Hook Integration Tests: Verify correct interaction with Silo Protocol
- Refund Tests: Ensure bid refunds work correctly
- Security Tests: Verify contract security features
testMinimumBidAmount()
: Tests minimum bid amounts (1 wei)testMaximumBidAmount()
: Tests maximum possible bid amountstestSelfOutbid()
: Tests bidder outbidding themselvestestSelfBiddingReverts()
: Tests prevention of borrowers bidding on their own liquidationtestPlaceBidAndRefund()
: Tests automatic refunds when outbidtestBidTooLow()
: Tests rejection of bids lower than current highest
testAuctionNumberProgress()
: Tests auction number incrementationtestBlocksRemainingCalculation()
: Tests blocks remaining calculationtestAuthorizedLiquidator()
: Tests authorized liquidator determinationtestAuctionHistoryPersistence()
: Tests auction history across multiple periodstestAuctionBoundaryBehavior()
: Tests behavior at auction period boundaries
testBeforeActionAuthorized()
: Tests authorized liquidator can liquidatetestBeforeActionUnauthorized()
: Tests unauthorized liquidators are preventedtestHookConfigurationWithMultipleActions()
: Tests hook configuration with multiple actions
testMultipleBorrowerAuctions()
: Tests multiple simultaneous borrower auctionstestNoAuthorizedLiquidator()
: Tests behavior with no authorized liquidator
testGasUsageMultipleBidders()
: Tests gas usage with multiple bidderstestExtremeRefundScenarios()
: Tests refunds with extreme value differencestestInsufficientWethBalance()
: Tests behavior with insufficient token balancetestZeroAddressHandling()
: Tests handling of zero address inputstestIncrementalBidding()
: Tests many small incremental bidstestLiquidationAfterEmptyAuctions()
: Tests liquidation after empty auctions
testCollectFeesReverts()
: Tests fee collection reversiontestOwnershipTransfer()
: Tests two-step ownership transfertestReinitializationPrevention()
: Tests prevention of reinitialization
setUp()
: Sets up the test environment with Arbitrum fork_getHookAddress()
: Helper to retrieve the hook address from configuration
The testGasUsageMultipleBidders()
test measures and logs gas usage for different bidding scenarios to help optimize the contract.