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: 100/199
Findings: 2
Award: $22.67
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: decade
Also found by: 0x3b, 0xDACA, 0xWaitress, 0xWeiss, 0xkaju, Arz, Aymen0909, BPZ, EloiManuel, HaCk0, J4de, Jerry0x, Jiamin, John, Juntao, Kek, Lalanda, MiloTruck, Mukund, PNS, RedTiger, Ruhum, Satyam_Sharma, ToonVH, Tricko, Udsen, ak1, anodaram, bin2chen, carrotsmuggler, cccz, circlelooper, deadrxsezzz, giovannidisiena, jasonxiale, joestakey, juancito, karanctf, kenta, kodyvim, ladboy233, lil_eth, lukino, markus_ether, marwen, mrpathfindr, nobody2018, parlayan_yildizlar_takimi, peakbolt, ravikiranweb3, rbserver, rvierdiiev, silviaxyz, volodya, zhuXKET, zzebra83
0.0748 USDC - $0.07
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Equity.sol#L309-L316
Mistake in the writing of restructureCapTable()
prevents donators who rescued the system from total failure to gain full control over FPS shares. This makes the function nearly useless, and makes the brave souls, who brought is back from the dead, share it with the other passive holders.
/** * If there is less than 1000 ZCHF in equity left (maybe even negative), the system is at risk * and we should allow qualified FPS holders to restructure the system. */
The statement above describes how if the system is near failure or passed it there is a function that when called will donate some capital, and make the donators the only shareholders, but here as we can see in the function bellow that is partly possible. The donators will make the donation, but the wiping procedure wont be able to wipe all of the addresses.
309 function restructureCapTable(address[] calldata helpers, address[] calldata addressesToWipe) public { 310 require(zchf.equity() < MINIMUM_EQUITY); 311 checkQualified(msg.sender, helpers); 312 for (uint256 i = 0; i<addressesToWipe.length; i++){ 313 address current = addressesToWipe[0]; 314 _burn(current, balanceOf(current)); 315 } 316 }
That is because in line 313 address current = addressesToWipe[0];
the wiping procedure will wipe only the first address in the loop. Meaning if there are 500 addresses added to be wiped clean, this function will try to wipe addressesToWipe[0]
of the loop 500 times. This is extremely intense in gas usage and will basically do nothing in terms of functionality. The only current way to wipe the addresses is if 1 by they are inputted and ran, meaning that checkQualified(msg.sender, helpers)
will need to check the helper as many times as the function is called, bringing enormous gas costs, and because of these cost one will be sufficient to think that this is unnecessary and it is better to bare to cost of owning only part of the shares instead of wasting money on function calls. This makes the function useless.
Foundry
#0 - c4-pre-sort
2023-04-20T14:23:49Z
0xA5DF marked the issue as duplicate of #941
#1 - c4-judge
2023-05-18T14:28:14Z
hansfriese marked the issue as satisfactory