restructureCapTable() facilitates the ease of removing holders no longer interested in a devastated system by a small group of brave souls. However, this specific function does not have a proper guard that could have any ill feeling and qualified holder to erase anyone at ease.
Proof of Concept
As shown in the function below, the for loop can be started when the equity has dropped below the minimum of 1000 Frankencoin and called by someone holding more than or equal to 3% of the total FPS shares. A discussion might have been underway trying to rescue the system but ended up thwarted because the caller chooses to eradicate everyone else except himself.
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));
}
}
Recommended Mitigation Steps
It is recommended the function mandates sending in to the contract a minimum amount of Frankencoin via zchf.transferAndCall() at the end of the erasing loop, as a form of commitment to the protocol, in order for the transaction to gracefully succeed.
Lines of code
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Equity.sol#L309-L316
Vulnerability details
Impact
restructureCapTable()
facilitates the ease of removing holders no longer interested in a devastated system by a small group of brave souls. However, this specific function does not have a proper guard that could have any ill feeling and qualified holder to erase anyone at ease.Proof of Concept
As shown in the function below, the for loop can be started when the equity has dropped below the minimum of 1000 Frankencoin and called by someone holding more than or equal to 3% of the total FPS shares. A discussion might have been underway trying to rescue the system but ended up thwarted because the caller chooses to eradicate everyone else except himself.
Equity.sol#L309-L316
Recommended Mitigation Steps
It is recommended the function mandates sending in to the contract a minimum amount of Frankencoin via zchf.
transferAndCall()
at the end of the erasing loop, as a form of commitment to the protocol, in order for the transaction to gracefully succeed.