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: 54/199
Findings: 4
Award: $94.94
🌟 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
The function doesn't burn the funds of all the provided addresses. Subsequent depositors trying to bootstrap the system again will receive fewer shares than they expected since the total supply remains almost unchanged.
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)); } }
It only clears the funds of the address at index 0
.
none
Properly loop over all the 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[i]; _burn(current, balanceOf(current)); } }
#0 - c4-pre-sort
2023-04-20T14:23:22Z
0xA5DF marked the issue as duplicate of #941
#1 - c4-judge
2023-05-18T14:28:11Z
hansfriese marked the issue as satisfactory
🌟 Selected for report: Josiah
Also found by: 0xDACA, Diana, Emmanuel, Kumpa, Nyx, RaymondFam, Ruhum, __141345__, bin2chen, carlitox477, lil_eth, nobody2018, rbserver
28.2764 USDC - $28.28
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Position.sol#L97
When cloning a position you can use up the remaining minting limit of it. That will force the owner of that position to create a new one or clone one as well.
The reduceLimitForClone()
function is supposed to grant half of the position's mint limit to the clone:
/** * Adjust this position's limit to give away half of the remaining limit to the clone. * Invariant: global limit stays the same. * * Cloning a position is only allowed if the position is not challenged, not expired and not in cooldown. * * @param _minimum amount that clone wants to mint initially * @return limit for the clone */ function reduceLimitForClone(uint256 _minimum) external noChallenge noCooldown alive onlyHub returns (uint256) { uint256 reduction = (limit - minted - _minimum)/2; // this will fail with an underflow if minimum is too high limit -= reduction + _minimum; return reduction + _minimum; }
But, by setting _minimum
so that $minimum = limited - minimum$ you can set limit = minted
. Meaning, the position can't mint more ZCHF.
For that, the person cloning has to provide enough collateral to mint the whole amount at the time of cloning.
none
reduceLimitForClone()
should remove the _minimum
parameter and always decrease the limit by half. If that amount is not enough to fulfill the caller's initial mint, just revert. Force the user to clone a different position or create their own one.
#0 - c4-pre-sort
2023-04-20T09:46:07Z
0xA5DF marked the issue as duplicate of #932
#1 - c4-judge
2023-05-18T14:15:58Z
hansfriese marked the issue as satisfactory
43.9854 USDC - $43.99
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Frankencoin.sol#L152
The project is supposed to be self-governing. Token owners are able to suggest new minters and collateral. The auction mechanism allows participants to remove collateral from the system if it's deemed unhealthy. But, there's no way to remove a registered minter.
Why would you want to remove a registered minter? Because they can have bugs that could break the whole system. The current minter, MintingHub, for example, implements a novel auction mechanism to price collateral instead of choosing the industry standard Chainlink oracles. While I support the idea of having a fully decentralized system, it does add additional risk to the project. A risk that's taken not only by the protocol team but every ZCHF holder as well.
Obviously, these are just hypotheticals. But, the system is not equipped to handle a scenario where the minter malfunctions.
After a minter is suggested you have generally 10 days to deny it. After that, there's no way to remove it:
function denyMinter(address _minter, address[] calldata _helpers, string calldata _message) override external { if (block.timestamp > minters[_minter]) revert TooLate(); reserve.checkQualified(msg.sender, _helpers); delete minters[_minter]; emit MinterDenied(_minter, _message); }
none
Implement the ability for token holders to temporarily pause a minter as well as remove it altogether.
#0 - c4-pre-sort
2023-04-21T14:16:27Z
0xA5DF marked the issue as primary issue
#1 - luziusmeisser
2023-05-03T07:04:07Z
I have thought about the ability to remove old minters, but decided against it.
Instead, experimental minters should come with their own limits (time, pause function, volume limits, etc.). They are free to include that. Minters that do not include it, can be expected to be denied unless they have been really thoroughly audited.
#2 - luziusmeisser
2023-05-03T07:04:46Z
So in fact, it is possible to pause a minter assuming the mintuer supports that functionality.
#3 - c4-sponsor
2023-05-03T07:04:54Z
luziusmeisser marked the issue as sponsor disputed
#4 - c4-sponsor
2023-05-03T07:05:01Z
luziusmeisser marked the issue as sponsor acknowledged
#5 - c4-judge
2023-05-18T05:08:32Z
hansfriese marked the issue as selected for report