Closed code423n4 closed 1 year ago
chechu marked the issue as sponsor acknowledged
We can start auctions multiple times if there is a bad debt so even if there is staleness or all assets aren’t swapped then also we can cover the bad debt later
@chechu - I am not sure I am 100% following your response here. You acknowledge its an issue, but it sounds like you believe that the protocol can simply start another auction.
Protocol is loosing value due to auctioning off the debt for fraction of price, when reserves can be used.
chechu marked the issue as sponsor disputed
"Dispute validity" is more appropriate. The key point here is that in the auctions of the Shortfall we are not "selling" the bad debt, we are really "selling" the available risk fund (with a discount), accepting tokens of bad debt that we'll use to reduce it. In the example provided by the warden:
So, we're going to sell $4M, accept tokens of A, B, and C to cover the bad debt and start the auction with an initial bid of 360 bps ($3.6M in terms of bad debt). A potential winner could place a bid of 380 bps, for example. So, the winner sent to the Shortfall contract these tokens:
The bad debt is reduced to $7.2M (10 - 3.8).
And the winner will receive $4M (from the risk fund, in USDT or generally in RiskFund.convertibalBaseAsset tokens).
After this, there won't be an economic incentive to start a new auction, because there isn't available risk fund to "buy" with discount. Bidders will have to wait until someone authorized swaps the reserves in the RiskFund, getting convertibleBaseAsset tokens. At that moment, a new auction can be started, and the remaining $7.2M could be covered (or not yet, but that is not a problem).
In this model, the authorized accounts decide when they want to make available the risk fund for the auctions. That is the expected behavior.
Thank you for the additional context, closing.
0xean marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2023-05-venus/blob/8be784ed9752b80e6f1b8b781e2e6251748d0d7e/contracts/RiskFund/RiskFund.sol#L152 https://github.com/code-423n4/2023-05-venus/blob/8be784ed9752b80e6f1b8b781e2e6251748d0d7e/contracts/Shortfall/Shortfall.sol#L381
Vulnerability details
Vulnerability Details
When swapping Risk funds in a pool
swapPoolsAssets(address[],uint256[],address[][])
from one market underlying asset type toconvertibleBaseAsset
, only a limited selected markets are supplied as input parameter.But when auctioning off pool bad debts, every market’s bad debt in the pools are calculated to form
poolBadDebt
which is a total of all bad debts in the pool. Additionally, when auctioning off bad debt inShortfall
contract, there is no check for pool reserves staleness:This makes every auction using more or less stale pool reserves, which basically means looses for the protocol.
Impact
LARGE_POOL_DEBT
orLARGE_RISK_FUND
.Proof of Concept
swapPoolsAssets(address[],uint256[],address[][])
with market A and B as items in markets input. The Reserve is successfully calculated and converted with a pool reserve of 4M for the Risk fund to use to auction off bad debt on Pool Alpha.startAuction(address)
function on shortfall contract using Pool Alpha as the input param, and it calculates a total bad debts of pool Alpha to be 10M.LARGE_POOL_DEBT
type.Tools Used
Manual analysis
Recommended Mitigation Steps
All assets reserved from each market in a pool should be used when swapping to
convertibleBaseAsset
, and validation should check that all markets in the pool is available in the markets input. So also meaning a comptroller address input should be passed as input to check against the markets own comptroller address to make sure they of all same pool inswapPoolsAssets(address[],uint256[],address[][])
. Additionally, please consider adding stalessness check.Assessed type
Other