After extensive testing of the Polynance Protocol's Pool contract, I have identified a critical bug in the market initialization logic that prevents the borrow and repay functionality from working correctly. While the core financial logic appears sound, this implementation bug blocks all market operations.
- All supply functionality works correctly
- LP token minting, storage updates, and Aave integration function as expected
- Fee calculations and edge cases handled properly
- Only tests that expect reverts pass
- All positive test cases fail due to market initialization bug
- Core borrow/repay logic cannot be tested due to the blocker
src/Pool.sol:247
The market initialization check contains inverted logic:
// CURRENT (BUGGY) CODE:
if (isMarketActive[marketId]) revert PolynanceEE.MarketNotActive();This code reverts with "MarketNotActive" when the market IS active, which is the opposite of the intended behavior.
// CORRECTED CODE:
if (!isMarketActive[marketId]) revert PolynanceEE.MarketNotActive();The check should revert when the market is NOT active.
- Market Initialization Blocked: Curators cannot initialize new markets as the function fails when trying to initialize an inactive market
- All Borrow Operations Fail: Since markets cannot be initialized, all borrow attempts fail
- All Repay Operations Fail: Repay functionality depends on having active borrows
- Protocol Unusable: The entire lending functionality of the protocol is blocked
During testing, I attempted several workarounds:
- Direct Storage Manipulation: Tried to bypass initialization by directly setting market data in storage
- Commenting Out Checks: The
_ensureMarketInitializedfunction body is already commented out (lines 266-270) - Alternative Initialization: Tried using
ReserveLogic.initializeMarketdirectly
None of these workarounds were sufficient because the bug is in the public initializeMarket function that curators must call.
- Clean Architecture: The Functional Core/Imperative Shell pattern is well-implemented
- Math Precision: Proper use of Ray (1e27) and Wad (1e18) precision
- Storage Separation: Clear separation between business logic and storage
- Comprehensive Events: Good event coverage for tracking operations
-
Incomplete Implementation:
_ensureMarketInitializedfunction body is commented out- Market initialization flow is broken
- Liquidation logic is stubbed (mentioned as V2 feature)
-
Testing Gaps:
- No integration tests for the complete flow
- Market initialization not properly tested
- Missing tests for edge cases in multi-market scenarios
- Fix the inverted logic in
Pool.sol:247 - Uncomment and properly implement
_ensureMarketInitializedchecks - Add comprehensive tests for market initialization
After fixing the bug, the following test coverage is recommended:
- Market initialization tests (single and multiple markets)
- Full integration tests (supply → borrow → repay → withdraw)
- Multi-user scenarios with concurrent operations
- Interest accrual over various time periods
- Edge cases around LTV limits and liquidation thresholds
- Add require statements to verify market initialization state
- Implement proper access control for market operations
- Add circuit breakers for emergency situations
- Complete the liquidation implementation
The Polynance Protocol demonstrates solid financial engineering with its dual-layer debt system and integration with Aave V3. The mathematical models for utilization-based spread rates and multi-level debt calculations appear correct. However, the implementation has a critical bug that must be fixed before the protocol can function.
Once the market initialization bug is resolved, the protocol should undergo comprehensive testing to ensure all functionality works as designed. The clean architecture and separation of concerns suggest that fixing this bug should not require extensive refactoring.