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: 16/199
Findings: 3
Award: $569.32
🌟 Selected for report: 1
🚀 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#L313
In Equity.sol
, restructureCapTable()
only burn the balance of addressToWipe[0]
and not the remaining addresses.
During a crisis where the Frankencoin's equity is < 1000 ZCHF, FPS holders could try to save the Frankencoin system with new ZCHF investment, in exchange for 100% FPS shares.
However, the issue with restructureCapTable()
will prevent these FPS holders from getting 100% FPS shares as the balances of existing FPS holders will not be fully burned, leading them to lose a portion of their shares to the unburned addresses.
In the for loop, current
is always assigned addressesToWipe[0]
, causing the _burn()
to only wipe the balance of of the first item in addressesToWipe[]
, and not the remaining addresses.
function restructureCapTable(address[] calldata helpers, address[] calldata addressesToWipe) public { require(zchf.equity() < MINIMUM_EQUITY); checkQualified(msg.sender, helpers); for (uint256 i = 0; i<addressesToWipe.length; i++){ address current = addressesToWipe[0]; _burn(current, balanceOf(current)); } }
Change Equity.sol#L313
,
address current = addressesToWipe[0];
to
address current = addressesToWipe[i];
#0 - c4-pre-sort
2023-04-20T14:27:38Z
0xA5DF marked the issue as duplicate of #941
#1 - c4-judge
2023-05-18T14:26:10Z
hansfriese marked the issue as satisfactory
#2 - c4-judge
2023-05-18T14:32:28Z
hansfriese changed the severity to 2 (Med Risk)
546.6457 USDC - $546.65
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Equity.sol#L173
When deploying to Optimism, Equity.anchorTime() will not be accurate due to the use of block.number.
function anchorTime() internal view returns (uint64){ return uint64(block.number << BLOCK_TIME_RESOLUTION_BITS); }
The inaccuracy of block.number will affect the computation of the holding duration for the votes. That will affect redeem() as the issue will cause it to deviate from the intended design of 90 days minimum holding duration (stated in comments).
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Equity.sol#L54-L59
Noted that the devs have mentioned that it is conceivable that Frankencoin will be deployed on other evm chains. So it is worth reviewing the use of block.number, such that it is compatible with other chains like Optimism.
On Optimism, the block.number
is not a reliable source of timing information and the time between each block is also different from Ethereum. This is because each transaction on L2 is placed in a separate block and blocks are not produce at a constant rate. This will cause the holding duration computation using anchorTime()
to fluctuate. (see Optimism docs https://community.optimism.io/docs/developers/build/differences/#block-numbers-and-timestamps)
Consider using block.timestamp instead of block.number for more accurate measurement of time.
#0 - c4-pre-sort
2023-04-27T16:00:52Z
0xA5DF marked the issue as primary issue
#1 - luziusmeisser
2023-04-29T21:11:08Z
I guess I should switch from block number to timestamp.
#2 - c4-sponsor
2023-04-29T21:11:13Z
luziusmeisser marked the issue as sponsor confirmed
#3 - c4-judge
2023-05-04T06:02:09Z
hansfriese marked the issue as satisfactory
#4 - c4-judge
2023-05-18T17:00:45Z
hansfriese marked the issue as selected for report