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: 6/199
Findings: 3
Award: $2,047.28
🌟 Selected for report: 1
🚀 Solo Findings: 1
🌟 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
restructureCapTable does not enumerate each addressToWipe
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Equity.sol#L313
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]; @> audit _burn(current, balanceOf(current)); } }
Recommendation
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[i]; _burn(current, balanceOf(current)); } }
#0 - c4-pre-sort
2023-04-20T14:25:28Z
0xA5DF marked the issue as duplicate of #941
#1 - c4-judge
2023-05-18T14:29:43Z
hansfriese marked the issue as satisfactory
#2 - c4-judge
2023-05-18T14:31:46Z
hansfriese changed the severity to 2 (Med Risk)
🌟 Selected for report: 0xWaitress
2024.6136 USDC - $2,024.61
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Frankencoin.sol#L280-L288
notifyLoss can be frontrun by redeem
notifyLoss immediately transfer zchf from reserve to the minter, reducing the amount of reserve and hence the equity and zchf to claim pershare.
While the deposit has 90 days cooldown before depositor can withdraw, current depositor that passed this cooldown can take advantage of a notifyLoss event by first frontrunning the notifyLoss by redeeming, then re-depositing into the protocol to take advantage of the reducedvalue per share.
notifyLoss can only be called by MintingHub::end, current depositor can bundle redeem + end + deposit
, when they see a challenge that is ending in loss for the reserve.
This is a re-current issue for most defi strategy to account loss in a mev-resistent way, a few possible solutions:
end
through private mempool.#0 - c4-pre-sort
2023-04-28T14:56:30Z
0xA5DF marked the issue as primary issue
#1 - 0xA5DF
2023-04-28T14:57:26Z
Will leave open for sponsor to comment, but it seems like an extremely unlikely scenario which makes it closer to a QA
#2 - luziusmeisser
2023-04-30T15:59:40Z
This is a valid concern and a weakness of the system. It remains to be seen whether this turns out to be a true problem in practice and then potentially be addressed in future versions.
#3 - c4-sponsor
2023-04-30T15:59:50Z
luziusmeisser marked the issue as sponsor acknowledged
#4 - c4-judge
2023-05-18T05:11:06Z
hansfriese marked the issue as selected for report
🌟 Selected for report: juancito
Also found by: 0xAgro, 0xNorman, 0xSmartContract, 0xStalin, 0xTheC0der, 0xWaitress, 0xhacksmithh, 0xnev, 3dgeville, 8olidity, Arz, Aymen0909, BGSecurity, BRONZEDISC, Bauchibred, Bauer, BenRai, ChainHunters, ChrisTina, CodeFoxInc, DedOhWale, DishWasher, EloiManuel, IceBear, Inspex, Jorgect, Kaysoft, LeoGold, LewisBroadhurst, Madalad, MiloTruck, MohammedRizwan, Nyx, Polaris_tow, RaymondFam, SaharDevep, SanketKogekar, Sathish9098, SolidityATL, Udsen, W0RR1O, aria, ayden, berlin-101, bin2chen, catellatech, codeslide, crc32, decade, descharre, evmboi32, eyexploit, fatherOfBlocks, georgits, giovannidisiena, joestakey, karanctf, kodyvim, ltyu, lukris02, m9800, matrix_0wl, mov, mrpathfindr, nadin, niser93, p0wd3r, parlayan_yildizlar_takimi, pavankv, pontifex, qpzm, ravikiranweb3, rbserver, santipu_, shealtielanz, slvDev, tnevler, wonjun, xmxanuel, yixxas
22.6007 USDC - $22.60
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Equity.sol#L249
emit Trade(msg.sender, int(shares), amount, price());
Recommendation
change it to from
emit Trade(from, int(shares), amount, price());
--- \n
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Equity.sol#L54-L59
* The minimum holding duration in blocks. You are not allowed to redeem your pool shares if you held them * for less than the minimum holding duration at average. For example, if you have two pool shares on your * address, one acquired 5 days ago and one acquired 105 days ago, you cannot redeem them as the average * holding duration of your shares is only 55 days < 90 days. */ uint256 public constant MIN_HOLDING_DURATION = 90*7200 << BLOCK_TIME_RESOLUTION_BITS; // Set to 5 for local testing
Recommendation: set it to a more precise block number
==== \n
function returnPostponedCollateral(address collateral, address target) external { uint256 amount = pendingReturns[collateral][msg.sender]; delete pendingReturns[collateral][msg.sender]; IERC20(collateral).transfer(target, amount); }
this restricts many gas stations or smart contract to collect postponedCollateral.
Recommendation
function returnPostponedCollateral(address collateral, address target, address from) external { uint256 amount = pendingReturns[collateral][from]; @>audit delete pendingReturns[collateral][from]; @>audit IERC20(collateral).transfer(target, amount); }
contract PositionFactory {
Recommendation
library PositionFactory {
#0 - hansfriese
2023-05-16T06:53:31Z
3 is not correct
#1 - c4-judge
2023-05-17T04:19:27Z
hansfriese marked the issue as grade-b