Platform: Code4rena
Start Date: 12/04/2023
Pot Size: $60,500 USDC
Total HM: 21
Participants: 199
Period: 7 days
Judge: hansfriese
Total Solo HM: 5
Id: 231
League: ETH
Rank: 57/199
Findings: 2
Award: $82.94
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: __141345__
Also found by: Emmanuel, KIntern_NA, SaeedAlipoor01988, bin2chen, cccz, joestakey, ladboy233, peanuts, said
60.3367 USDC - $60.34
https://github.com/code-423n4/2023-04-frankencoin/blob/1022cb106919fba963a89205d3b90bf62543f68f/contracts/MintingHub.sol#L260 https://github.com/code-423n4/2023-04-frankencoin/blob/1022cb106919fba963a89205d3b90bf62543f68f/contracts/Position.sol#L352 https://github.com/code-423n4/2023-04-frankencoin/blob/1022cb106919fba963a89205d3b90bf62543f68f/contracts/Position.sol#L269
If the challenge.bidder is added to the USDC/USDT blacklist, call to the Position.sol#L268.internalWithdrawCollateral() function will get reverted and then MintingHub.sol#L252.end() does not work.
When the user makes calls to the MintingHub.sol#L252.end(), the contract will make a call to the Position.sol#L329.notifyChallengeSucceeded() to calculate the new _bid amount and _size amount if needed and then transfer _size amount of collateral to the challenge.bidder by Position.sol#L268.internalWithdrawCollateral() function.
*/ function notifyChallengeSucceeded(address _bidder, uint256 _bid, uint256 _size) external onlyHub returns (address, uint256, uint256, uint256, uint32) { challengedAmount -= _size; uint256 colBal = collateralBalance(); if (_size > colBal){ // Challenge is larger than the position. This can for example happen if there are multiple concurrent // challenges that exceed the collateral balance in size. In this case, we need to redimension the bid and // tell the caller that a part of the bid needs to be returned to the bidder. _bid = _divD18(_mulD18(_bid, colBal), _size); _size = colBal; } // Note that thanks to the collateral invariant, we know that // colBal * price >= minted * ONE_DEC18 // and that therefore // price >= minted / colbal * E18 // such that // volumeZCHF = price * size / E18 >= minted * size / colbal // So the owner cannot maliciously decrease the price to make volume fall below the proportionate repayment. uint256 volumeZCHF = _mulD18(price, _size); // How much could have minted with the challenged amount of the collateral // The owner does not have to repay (and burn) more than the owner actually minted. uint256 repayment = minted < volumeZCHF ? minted : volumeZCHF; // how much must be burned to make things even notifyRepaidInternal(repayment); // we assume the caller takes care of the actual repayment internalWithdrawCollateral(_bidder, _size); // transfer collateral to the bidder and emit update return (owner, _bid, volumeZCHF, repayment, reserveContribution); } */ function internalWithdrawCollateral(address target, uint256 amount) internal returns (uint256) { IERC20(collateral).transfer(target, amount); uint256 balance = collateralBalance(); if (balance < minimumCollateral){ cooldown = expiration; } emitUpdate(); return balance; }
Based on the comments from the project, it's possible that the user address gets blacklisted by collateral! https://github.com/code-423n4/2023-04-frankencoin/blob/1022cb106919fba963a89205d3b90bf62543f68f/contracts/MintingHub.sol#L247
So if a similar scenario gets to happen to the challenge.bidder, the contract cannot send the collateral asset to the challenge.bidder, and a call from MintingHub.sol#L252.end() to the Position.sol#L329.notifyChallengeSucceeded() will get reverted.
It's possible that with this scenario, collateral from the bidder and challenger gets locked in the contract.
Manually
maybe one solution is to add a pending balance to the challenge.bidder and challenge.bidder can withdraw his balance to any address.
#0 - c4-pre-sort
2023-04-19T20:59:07Z
0xA5DF marked the issue as duplicate of #675
#1 - c4-pre-sort
2023-04-28T12:43:07Z
0xA5DF marked the issue as duplicate of #680
#2 - c4-judge
2023-05-18T13:28:34Z
hansfriese marked the issue as satisfactory
#3 - c4-judge
2023-05-18T17:02:12Z
hansfriese changed the severity to 2 (Med Risk)