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: 28/199
Findings: 2
Award: $304.87
🌟 Selected for report: 0
🚀 Solo Findings: 0
283.8353 USDC - $283.84
https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/MintingHub.sol#L92-L106 https://github.com/code-423n4/2023-04-frankencoin/blob/main/contracts/PositionFactory.sol#L17
Exploiting involving Stealing of funds.
The openPosition
function deploys a new position contract using the create, where the address derivation depends only on the arguments passed.
At the same time, some of the chains (Polygon, Optimism, Arbitrum) to which the MintingHub
will be deployed are suspicious of the reorg attack.
File: PositionFactory 17: return address(new Position(_owner, msg.sender, _zchf, _collateral, 18: _minCollateral, _initialLimit, initPeriod, _duration, 19: _challengePeriod, _mintingFeePPM, _liqPrice, _reserve));
Even more, the reorg can be couple of minutes long. So, it is quite enough to create the position and transfer funds to that address, especially when someone uses a script, and not doing it by hand.
Optimistic rollups (Optimism/Arbitrum) are also suspect to reorgs since if someone finds a fraud the blocks will be reverted, even though the user receives a confirmation and already created a position.
If Alice creates a new position by deploying a position, and then sends funds to it. Bob sees that the network block reorg happens and calls openPosition. Thus, it creates position with an address to which Alice sends funds. Then Alices' transactions are executed and Alice transfers funds to Bob's controlled position.
VS Code
Deploy the position contract via create2
with salt
.
#0 - c4-pre-sort
2023-04-20T12:19:11Z
0xA5DF marked the issue as duplicate of #155
#1 - c4-judge
2023-05-18T10:49:22Z
hansfriese marked the issue as satisfactory
🌟 Selected for report: c3phas
Also found by: 0xDACA, 0xRB, 0xSmartContract, 0xhacksmithh, 0xnev, Aymen0909, BenRai, Breeje, DishWasher, Erko, EvanW, JCN, MohammedRizwan, NoamYakov, Polaris_tow, Proxy, Rageur, Raihan, RaymondFam, ReyAdmirado, SAAJ, Sathish9098, Satyam_Sharma, Udsen, __141345__, aria, codeslide, decade, fatherOfBlocks, hunter_w3b, karanctf, matrix_0wl, nadin, naman1778, niser93, pavankv, petrichor, pfapostol, sebghatullah, slvDev, trysam2003, xmxanuel
21.0255 USDC - $21.03
Count | Explanation | Instances |
---|---|---|
[GAS-01] | Use unchecked keyword for few calculations | 4 |
[GAS-02] | Unnecessary function declared | 1 |
There are instances when their is a required check above the calculation which makes it impossible to underflow or overflow. Such calculations should be marked unchecked to save gas. These are the instances which the Bot missed:
Instance (4):
File: ERC20.sol 132: _approve(sender, msg.sender, currentAllowance - amount); 156: _balances[sender] -= amount; 157: _balances[recipient] += amount;
File: Frankencoin.sol 286: _mint(msg.sender, _amount - reserveLeft);
In Ownable.sol
, there is a onlyOwner
modifier which is used at many places in Position.sol
. The modifier makes an unnecessary call to requireOwner
function which costs more gas. Instead, the one line logic of requireOwner
should be placed inline in onlyOwner
modifier to save gas for jumping to the function everytime.
File: Ownable.sol function requireOwner(address sender) internal view { if (owner != sender) revert NotOwner(); } modifier onlyOwner() { requireOwner(msg.sender); _; }
#0 - c4-judge
2023-05-16T13:56:20Z
hansfriese marked the issue as grade-b