A Sanctioned Address Can Directly Repay Debt via repay() and repayOutstandingDebt() in WildcatMarket #70
Labels
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
edited-by-warden
grade-b
primary issue
Highest quality submission among a set of duplicates
Q-15
QA (Quality Assurance)
Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
🤖_04_group
AI based duplicate group recommendation
sponsor disputed
Sponsor cannot duplicate the issue, or otherwise disagrees this is an issue
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2024-08-wildcat/blob/fe746cc0fbedc4447a981a50e6ba4c95f98b9fe1/src/market/WildcatMarket.sol#L202
Vulnerability details
Description
The WildcatMarket in its current implementation, contract allows sanctioned addresses to repay debt, violating the sponsor's invariant that sanctioned accounts should not modify the market state.
The
repay()
andrepayOutstandingDebt()
functions lacks a sanction check, contrary to other state-modifying functions likeborrow()
.Let's take a look at the
repay()
andrepayOutstandingDebt()
implementations fromWildcatMarket.sol
:Also in
repayOutstandingDebt()
:What matters is that sanctioned entities are not receiving or sending funds to the market, as this could put other lenders in a precarious legal situation. However, as seen in the implementation above, there is no restriction preventing sanctioned addresses from calling these functions and sending funds into the market directly.
Impact
The lack of restrictions allows sanctioned addresses to, in fact, interact with the market, modify its state, and essentially circumvent financial regulations. This violates the key invariant stated in the guidelines: "Accounts which are flagged as sanctioned on Chainalysis should never be able to successfully modify the state of the market unless the borrower specifically overrides their sanctioned status in the sentinel (other than token approvals, or through their tokens being withdrawn & escrowed in nukeFromOrbit and executeWithdrawal)."
Also worth noting is that this was completely missed in the v1 audit competition last year (though I did not participate in the contest).
Proof of Concept
Unlike the
deposit()
andborrow()
functions, which include the necessary check, a sanctioned address can bypass the sanction check by directly calling therepay()
orrepayOutstandingDebt()
functions.‹‹Test output logs›› :
Create a new NewTest.t.sol file under ./test to run the POC code below with
forge test --match-path test/NewTest.t.sol -vvvv
Tools used
Foundry
Recommendation:
Implement a sanction check in the
repay()
andrepayOutstandingDebt()
functions, similar to the check in the borrow function.Assessed type
Access Control
The text was updated successfully, but these errors were encountered: