Open code423n4 opened 1 year ago
0xA5DF marked the issue as primary issue
The Frankencoin system was not designed to work with ERC777 tokens.
However, since it is possible to avoid this re-entrency issue without additional gas costs, I still tend to implement it just in case ERC777 gains popularity (which I doubt).
Given that ERC777 are out of the Frankencoin scope, this is low severity at most.
luziusmeisser marked the issue as disagree with severity
hansfriese changed the severity to QA (Quality Assurance)
hansfriese marked the issue as grade-b
Lines of code
https://github.com/code-423n4/2023-04-frankencoin/blob/1022cb106919fba963a89205d3b90bf62543f68f/contracts/MintingHub.sol#L211
Vulnerability details
Impact
If users set collateral as tokens to allow reentrant calls on transfer(e.g. ERC777 tokens) in a Challenge, their collateral could be stolen by other malicious users.
Proof of Concept
In
MintingHub.bid
, if thecollateral()
of Challenge is a token that allows reentrant calls on transfer, attacker could reentrybid
function to bid the same Challenge.To exploit this reentrancy, an attacker needs to launch a Challenge with the same collateral as he wants to steal. Then he could bid his own Challenge with enough
_bidAmountZCHF
to pass thechallenge.position.tryAvertChallenge
check and gets collateral. When he gets collateral, he could reenter thisbid
function and bid his own Challenge again to get the collateral again. Thechallenger
of the attacker's Challenge is attacker, so the_bidAmountZCHF
is all transferred to attacker himself. Attacker get both his origin collateral and the victim's collateral without any pay.EXP: Consider the following situation:
Alice is the victim and Bob is an attacker
MintingHub
is 300.MintingHub
is 300+300=600._bidAmountZCHF
, he could get collateral in second Challenge, and the_bidAmountZCHF
is transferred to Bob. The total amount of collateral inMintingHub
is 600-300=300.bid
function and bid his second Challenge again. Now he could get another 300 collateral fromMintingHub
, but the_bidAmountZCHF
is still transferred to Bob, because thechallenger
of second Challenge is Bob. Bob has 600 collateral but his ZCHF doesn't change. The total amount of collateral inMintingHub
is 300-300=0.TEST:
Add this test to
test/GeneralTest.t.sol
.Then change the
bid
function inGeneralTest.t.sol
, comment out last require, we don't care minBid here:To simulate the reentrancy, I also patch the code in
MintingHub.bid
. The call tobid
will bid the same challenge twice:Run
forge test -m testBidReentrancy -vv
to see the result.Tools Used
foundryup
Recommended Mitigation Steps
Add a ReentrancyGuard to
bid
function to prevent reentrancy