Frankencoin - lil_eth's results

A decentralized and fully collateralized stablecoin.

General Information

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

Frankencoin

Findings Distribution

Researcher Performance

Rank: 69/199

Findings: 3

Award: $50.95

🌟 Selected for report: 0

🚀 Solo Findings: 0

Lines of code

Equity.sol#restructureCapTable:https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Equity.sol#L309-L316

Vulnerability details

Impact

RestructureCaptable is a function to use in case of disaster like scenario where there are less than 1000 zchf in equity left. The idea of this function is for a small group of FPS holders to "save" the project. But this function is malformed and would hurt a single user or revert in case he/she would not own enough amount of zchf

Proof of Concept

function restructureCapTable(address[] calldata helpers, address[] calldata addressesToWipe) public {
    require(zchf.equity() < MINIMUM_EQUITY);
    checkQualified(msg.sender, helpers);  // check 3%
    for (uint256 i = 0; i<addressesToWipe.length; i++){
        address current = addressesToWipe[0]; //@audit-issue replace to addressToWipe[i]
        _burn(current, balanceOf(current));
    }
}

Tools Used

VS Code

Replace the code

function restructureCapTable(address[] calldata helpers, address[] calldata addressesToWipe) public {
    require(zchf.equity() < MINIMUM_EQUITY);
    checkQualified(msg.sender, helpers);  // check 3%
    for (uint256 i = 0; i<addressesToWipe.length; i++){
+       address current = addressesToWipe[i]; 
-       address current = addressesToWipe[0];
        _burn(current, balanceOf(current));
    }
}

#0 - c4-pre-sort

2023-04-20T14:27:19Z

0xA5DF marked the issue as duplicate of #941

#1 - c4-judge

2023-05-18T14:25:37Z

hansfriese marked the issue as satisfactory

Findings Information

🌟 Selected for report: Josiah

Also found by: 0xDACA, Diana, Emmanuel, Kumpa, Nyx, RaymondFam, Ruhum, __141345__, bin2chen, carlitox477, lil_eth, nobody2018, rbserver

Labels

bug
2 (Med Risk)
low quality report
satisfactory
duplicate-932

Awards

28.2764 USDC - $28.28

External Links

Lines of code

Position.sol#reduceLimitForClone : https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/Position.sol#L97-L101

Vulnerability details

Impact

Line 89 and line 90 of Position.sol it is written as a comment :

“Adjust this position's limit to give away half of the remaining limit to the clone. Invariant: global limit stays the same. “

But it’s false, I will explain why.

When cloning a position (which seems to be the easiest way to acquire a position), the limit of zchf that can be minted by the primary position is affected, here is the process :

  1. Cloner call clonePosition() from MintingHub.sol
  2. mintingHub calcul the limit for cloning position by calling primary position function reduceLimitForClone : uint256 limit = existing.reduceLimitForClone(_initialMint);
  3. This function will affect the limit of the current position regarding how much minter has already minted in an incoherent way
  4. Example : a. userA creates a positionA with a limit of 20000, he currently minted only 1000 zchf b. userB wants to clone a position to mint 2000 zchf , he creates it by cloning positionA, the calcul is like this in position.sol#reduceLimitForClone(uint256 _minimum) :
        uint256 reduction = (limit - minted - _minimum)/2;
        limit -= reduction + _minimum; // new limit for positionA = 9500
        return reduction + _minimum; // limit for clone = 18 000
| limitA | 20000 | | --- | --- | | currentMintA | 1000 | | minimumB | 2000 | | reduction | 8500 | | newlimitA | 9500 | | limitCloneB | 18000 |

⇒ UserA who deposited a collateral according to its mintingMaximum capacity to not be challenged even if he/she reach the limit will have it’s new limit hugely reduced (by more than average in this example)

⇒ UserB who will deposit according to it’s _initialMint amount will have a limit hugely higher than wanted ( more than 8x in example) and is at risk to be challenged because its collaretal is not in accordance with it’s cloning position limit

To conclude it can be dangerous if userB mints more than he wanted at the beginning, its position is valid as he clones a valid one but he can mint a lot more than intended at the beginning, userA will have to creates another positon and repay fees to mint the amount he wanted at the beginning

Proof of Concept

Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.

Tools Used

VS Code

Add a parameter in the MintingHub.sol#clonePosition that ask cloner which limit he wants to reach, do your calculs and if limitwanted < existing.reduceLimitForClone(_initialMint); , clone the position with limitWanted as a limit and only reduce the limit of limitPositionA - limitwanted

#0 - c4-pre-sort

2023-04-22T14:48:24Z

0xA5DF marked the issue as duplicate of #932

#1 - 0xA5DF

2023-04-22T14:48:28Z

Didn't fully identify the impact

#2 - c4-pre-sort

2023-04-22T14:48:37Z

0xA5DF marked the issue as low quality report

#3 - c4-judge

2023-05-18T14:00:09Z

hansfriese marked the issue as satisfactory

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter