Platform: Code4rena
Start Date: 19/04/2022
Pot Size: $30,000 USDC
Total HM: 10
Participants: 43
Period: 3 days
Judges: moose-code, JasoonS
Total Solo HM: 7
Id: 90
League: ETH
Rank: 2/43
Findings: 4
Award: $4,962.00
🌟 Selected for report: 2
🚀 Solo Findings: 2
https://github.com/code-423n4/2022-04-phuture/blob/594459d0865fb6603ba388b53f3f01648f5bb6fb/contracts/IndexLogic.sol#L48 https://github.com/code-423n4/2022-04-phuture/blob/594459d0865fb6603ba388b53f3f01648f5bb6fb/contracts/IndexLogic.sol#L31
User can lose their fund
When users want to mint an index token, users need to transfer their assets to address(vToken) first, then call the mint()
function of IndexLogic.sol. If users make it into 2 transactions, miner can manipulate it/ After users transfer their token to address(vToken), miner can front-run, and call mint()
before users call mint()
, and of course, the index token will be minted to miner instead of users
==> User will lose their fund
manual review
Implement a contract to help users execute 2 actions (transfer to vToken + mint) into 1 transaction (like router in uniswapV2)
#0 - olivermehr
2022-05-02T20:30:18Z
Duplicate issue of #19
🌟 Selected for report: TrungOre
2022.9048 USDC - $2,022.90
https://github.com/code-423n4/2022-04-phuture/blob/594459d0865fb6603ba388b53f3f01648f5bb6fb/contracts/ManagedIndexReweightingLogic.sol#L32 https://github.com/code-423n4/2022-04-phuture/blob/594459d0865fb6603ba388b53f3f01648f5bb6fb/contracts/interfaces/IIndexRegistry.sol#L19
The list of assets won't be changed after reweight because of reverted tx
require(_updatedAssets.length <= IIndexRegistry(registry).maxComponents())
when reweight is not true, because as in the doc,
maxComponent
is the maximum assets for an index, but _updatedAssets
also contain the assets that you want to remove. So the comparision make no sense
manual review
Require assets.length() <= IIndexRegistry(registry).maxComponents()
at the end of function instead
🌟 Selected for report: TrungOre
Users can get the wrong amount of vToken => Make users lose their fund
Base on the code in function shareChange()
in vToken.sol
Assume that if oldShare = totalSupply > 0
,
newShares
= (_amountInAsset * (_totalSupply - oldShares)) / (_assetBalance - availableAssets);
= (_amountInAsset * (_totalSupply - _totalSupply)) / (_assetBalance - availableAssets);
= 0
It make no sense, because if amountInAsset >> availableAssets
, newShares
should be bigger than oldShares
, but in this case newShares = 0 < oldShares
manual review
Modify the line from if (_totalSupply > 0)
to if (_totalSupply - oldShares > 0)
#0 - jn-lp
2022-05-13T13:56:18Z
Such a case is considered impossible due to the fact that it can only work with a 0xdead address
#1 - moose-code
2022-05-24T13:40:23Z
Agree its not an issue as on initialization tokens are sent to the burn address making this unlikely.
However the orderer role could possibly burn the tokens held by the burn address causing this issue to happen
#2 - JasoonS
2022-05-25T19:49:28Z
Agree with mitigation step:
Modify the line from if (_totalSupply > 0) to if (_totalSupply - oldShares > 0)
If it were impossible for tokens to be burned from the 0xdead address then this wouldn't be a concern.
So although extremely unlikely, this is valid.
🌟 Selected for report: IllIllI
Also found by: 0v3rf10w, 0xDjango, 0xNazgul, 0xkatana, Dravee, Kenshin, MaratCerby, Tadashi, TerrierLover, Tomio, TrungOre, defsec, ellahi, fatherOfBlocks, fatima_naz, gzeon, joestakey, kenta, minhquanym, oyc_109, rayn, rfa, robee, simon135, slywaters, windhustler, z3s
31.3783 USDC - $31.38
decimals()
Affected code
newWeight != 0
instead of newWeight > 0
Affected code
_totalSupply != 0
instead of _totalSupply > 0
Affected code
uint _balance = oldShares
instead of uint _balance = _NAV.balanceOf[_account]
Affected code
Affected code
Proof of concept
maxCapitalization
is initialized with value _capitalization[0]
, so we don't need to check if _capitalizations[i] > maxCapitalization
if i == 0