Platform: Code4rena
Start Date: 10/03/2022
Pot Size: $75,000 USDT
Total HM: 25
Participants: 54
Period: 7 days
Judge: pauliax
Total Solo HM: 10
Id: 97
League: ETH
Rank: 7/54
Findings: 5
Award: $2,164.78
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: hickuphh3
Also found by: 0v3rf10w, 0x1f8b, 0xDjango, 0xNazgul, 0xngndev, 0xwags, Cantor_Dust, CertoraInc, Dravee, IllIllI, PPrieditis, Ruhum, TerrierLover, WatchPug, XDms, benk10, berndartmueller, bitbopper, catchup, cmichel, cryptphi, csanuragjain, danb, defsec, gzeon, hagrid, hubble, jayjonah8, kenta, kyliek, minhquanym, rfa, robee, saian, samruna, throttle, ye0lde, z3s
156.1294 USDT - $156.13
Recommended to upgrade to latest Solidity 0.8.12
https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/metatx/ERC2771Context.sol to https://github.com/OpenZeppelin/openzeppelin-contracts/blob/52eeebecda140ebaf4ec8752ed119d8288287fac/contracts/metatx/ERC2771Context.sol
https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/metatx/ERC2771ContextUpgradeable.sol to https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/blob/3dec82093ea4a490d63aab3e925fed4f692909e8/contracts/metatx/ERC2771ContextUpgradeable.sol
Consider adding caps to fee parameters to reduce rug risk https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/token/TokenManager.sol#L44
" ERR_ARRAY_LENGTH_MISMATCH"
Consider make them public for easier external consumption https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L68 https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L19-20
setLpToken
functionOwner can call setLpToken to change the value of lpToken in WhitelistPeriodManager, which will make all onlyLpNft
function revert
https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/WhitelistPeriodManager#L170-176
function _setLpToken(address _lpToken) internal { lpToken = ILPToken(_lpToken); } function setLpToken(address _lpToken) external onlyOwner { _setLpToken(_lpToken); }
setLiquidityProviders
functionOwner can call setLpToken to change the value of lpToken in WhitelistPeriodManager, which will make all onlyLiquidityPool
function revert
https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/WhitelistPeriodManager#L162-168
function _setLiquidityProviders(address _liquidityProviders) internal { liquidityProviders = ILiquidityProviders(_liquidityProviders); } function setLiquidityProviders(address _liquidityProviders) external onlyOwner { _setLiquidityProviders(_liquidityProviders); }
#0 - pauliax
2022-05-12T16:46:56Z
"No cap on fee parameters" should be upgraded to Medium: https://github.com/code-423n4/2022-03-biconomy-findings/issues/8#issuecomment-1114023886
#1 - pauliax
2022-05-12T16:47:20Z
"Consider remove setLpToken function" is similar to: #51
#2 - pauliax
2022-05-12T16:47:38Z
"Consider remove setLiquidityProviders function" is similar to #52
🌟 Selected for report: Dravee
Also found by: 0v3rf10w, 0x1f8b, 0xDjango, 0xNazgul, 0xngndev, 0xwags, Cantor_Dust, CertoraInc, IllIllI, Jujic, Kenshin, Kiep, PPrieditis, TerrierLover, Tomio, WatchPug, antonttc, benk10, berndartmueller, bitbopper, csanuragjain, defsec, gzeon, hagrid, hickuphh3, kenta, minhquanym, oyc_109, pedroais, peritoflores, rfa, robee, saian, samruna, sirhashalot, throttle, wuwe1, z3s
60.5492 USDT - $60.55
Solidity ^0.8.4 allow the use of custom errors to optimize gas usage. https://blog.soliditylang.org/2021/04/21/custom-errors/
> 0
is less efficient than != 0
for uint in require conditionRef: https://twitter.com/GalloDaSballo/status/1485430908165443590
./contracts/hyphen/LiquidityProviders.sol:239: require(_amount > 0, "ERR__AMOUNT_IS_0"); ./contracts/hyphen/LiquidityProviders.sol:283: require(_amount > 0, "ERR__AMOUNT_IS_0"); ./contracts/hyphen/LiquidityProviders.sol:410: require(lpFeeAccumulated > 0, "ERR__NO_REWARDS_TO_CLAIM");
https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/metatx/ERC2771Context.sol#L11 (contract out of scope but inherited by other contract in scope)
address internal immutable _trustedForwarder;
struct NFTInfo { address payable staker; bool isStaked; uint256 rewardDebt; uint256 unpaidRewards; }
Use uint(1) instead of bool(true) to save gas since evm work with 256-bits word
contracts/hyphen/ExecutorManager.sol:10: mapping(address => bool) internal executorStatus; contracts/hyphen/WhitelistPeriodManager.sol:23: mapping(address => bool) public isExcludedAddress; contracts/hyphen/LiquidityPool.sol:37: mapping(bytes32 => bool) public processedHash;
We can use the following function to save gas on float multiplications
// out = x * y unchecked{/} z function fmul(uint256 x, uint256 y, uint256 z) internal pure returns(uint256 out){ assembly{ if iszero(eq(div(mul(x,y),x),y)) {revert(0,0)} out := div(mul(x,y),z) } }
https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityFarming.sol#L163 https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L318 https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L324 https://github.com/code-423n4/2022-03-biconomy/blob/04751283f85c9fc94fb644ff2b489ec339cd9ffc/contracts/hyphen/LiquidityPool.sol#L326
Instead of
for (uint256 i = 1; i <= something; ++i){...}
we can do
for (uint256 i = 1; i <= something; ){...unchecked{++i;}}
contracts/hyphen/token/TokenManager.sol:78: for (uint256 index = 0; index < tokenConfig.length; ++index) { contracts/hyphen/token/LPToken.sol:77: for (uint256 i = 0; i < nftIds.length; ++i) { contracts/hyphen/token/svg-helpers/SvgHelperBase.sol:31: ++count; contracts/hyphen/token/svg-helpers/SvgHelperBase.sol:45: for (uint256 i = 0; i < _length; ++i) { contracts/hyphen/ExecutorManager.sol:31: for (uint256 i = 0; i < executorArray.length; ++i) { contracts/hyphen/ExecutorManager.sol:47: for (uint256 i = 0; i < executorArray.length; ++i) { contracts/hyphen/LiquidityFarming.sol:233: for (index = 0; index < nftsStakedLength; ++index) { contracts/hyphen/WhitelistPeriodManager.sol:180: for (uint256 i = 0; i < _addresses.length; ++i) { contracts/hyphen/WhitelistPeriodManager.sol:228: for (uint256 i = 0; i < _tokens.length; ++i) { contracts/hyphen/WhitelistPeriodManager.sol:248: for (uint256 i = 1; i <= totalSupply; ++i) {
nftIdsStaked[msgSender][index] = nftIdsStaked[msgSender][nftsStakedLength - 1];
unchecked{ totalSharesStaked[baseToken] -= amount; }
function addLPFee(address _token, uint256 _amount) external onlyLiquidityPool tokenChecks(_token) whenNotPaused { totalReserve[_token] += _amount; unchecked{ // fee should always be less than reserve totalLPFees[_token] += _amount; } emit FeeAdded(_token, _amount); }
totalLPFees[_tokenAddress] -= lpFeeAccumulated; unchecked{ // fee should always be less than reserve totalReserve[_tokenAddress] -= lpFeeAccumulated; } totalSharesMinted[_tokenAddress] -= lpSharesRepresentingFee;
totalLiquidity[_token] += _amount; unchecked{ totalLiquidityByLp[_token][_lp] += _amount; }
totalLiquidityByLp[_token][_lp] -= _amount; unchecked{ totalLiquidity[_token] -= _amount; }
if(nftSuppliedLiquidity >= eligibleLiquidity) { lpFeeAccumulated = 0; } else { unchecked { lpFeeAccumulated = eligibleLiquidity - nftSuppliedLiquidity; } }
#0 - ankurdubey521
2022-04-01T09:54:39Z
The Float multiplication optimization is a great catch!