Platform: Code4rena
Start Date: 17/03/2022
Pot Size: $30,000 USDC
Total HM: 8
Participants: 43
Period: 3 days
Judge: gzeon
Total Solo HM: 5
Id: 100
League: ETH
Rank: 16/43
Findings: 2
Award: $217.87
π Selected for report: 0
π Solo Findings: 0
π Selected for report: defsec
Also found by: 0x1f8b, 0xDjango, 0xNazgul, 0xkatana, 0xwags, CertoraInc, Funen, GeekyLumberjack, GreyArt, IllIllI, Kenshin, Ruhum, TerrierLover, WatchPug, berndartmueller, bugwriter001, cccz, cmichel, csanuragjain, hake, kenta, kirk-baird, leastwood, minhquanym, oyc_109, peritoflores, rayn, remora, rfa, robee, saian, samruna, sorrynotsorry, wuwe1
51.8842 USDC - $51.88
_valueBefore
variable is wrapped by parenthesis but this is not needed.
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/Collateral.sol#L89
_shares = (_amountToDeposit * totalSupply()) / (_valueBefore);
_shares = (_amountToDeposit * totalSupply()) / _valueBefore;
#0 - ramenforbreakfast
2022-03-22T22:40:15Z
Valid claim, but lower severity to 0. Does not affect functionality and is a code style nit.
#1 - ramenforbreakfast
2022-03-23T02:43:20Z
Ignore mentions, accidentally referred to issue 19 when i meant 18 for duplicate issues.
165.9874 USDC - $165.99
mintLongShortTokens
function in PrePOMarket.sol
mintLongShortTokens
function in PrePOMarket.sol
can use unchecked directory.
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/PrePOMarket.sol#L122
require(_amount > _fee, "Minting amount too small"); _collateral.transferFrom(msg.sender, _treasury, _fee); _amount -= _fee;
It is obvious that _amount - _fee
will not be underflown since it has require(_amount > _fee, ...)
. Hence, can use unchecked directory,
require(_amount > _fee, "Minting amount too small"); _collateral.transferFrom(msg.sender, _treasury, _fee); unchecked { _amount -= _fee; }
Contract | Methods | Before | After | Change |
---|---|---|---|---|
PrePOMarket | mintLongShortTokens | 198115 | 198055 | -60 |
Contract | Before | After | Change |
---|---|---|---|
PrePOMarketFactory | 4182011 | 4180271 | -1740 |
redeem
function in PrePOMarket.sol
redeem
function in PrePOMarket.sol
can use unchecked directory.
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/PrePOMarket.sol#L169
require(_collateralOwed > _fee, "Redemption amount too small"); _collateral.transfer(_treasury, _fee); _collateralOwed -= _fee;
It is obvious that _collateralOwed - _fee
will not be underflown since it has require(_collateralOwed > _fee, ...)
. Hence, can use unchecked directory,
require(_collateralOwed > _fee, "Redemption amount too small"); _collateral.transfer(_treasury, _fee); unchecked { _collateralOwed -= _fee; }
Contract | Methods | Before | After | Change |
---|---|---|---|---|
PrePOMarket | mintLongShortTokens | 100708 | 100653 | -55 |
Contract | Before | After | Change |
---|---|---|---|
PrePOMarketFactory | 4182011 | 4180271 | -1740 |
Contract | Methods | Before | After | Change |
---|---|---|---|---|
PrePOMarket | extractRewards | 135652 | 131459 | -4193 |
Contract | Before | After | Change |
---|---|---|---|
ExecutorManager | 548814 | 536945 | -11869 |
deposit
function in Collateral.sol
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/Collateral.sol#L73
require(_amountToDeposit > _fee, "Deposit amount too small"); _baseToken.safeTransfer(_treasury, _fee); _amountToDeposit -= _fee;
_amountToDeposit - _fee
will not be underflown since require(_amountToDeposit > _fee, ...)
.
require(_amountToDeposit > _fee, "Deposit amount too small"); _baseToken.safeTransfer(_treasury, _fee); unchecked { _amountToDeposit -= _fee; }
Contract | Methods | Before | After | Change |
---|---|---|---|---|
PrePOMarket | extractRewards | 135652 | 131459 | -4193 |
Contract | Before | After | Change |
---|---|---|---|
ExecutorManager | 548814 | 536945 | -11869 |
uint256 _shares
does not need to be initialized with 0 at deposit
function in Collateral.sol
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/Collateral.sol#L81
uint256 _shares = 0;
uint256 _shares;
Contract | Methods | Before | After | Change |
---|---|---|---|---|
Collateral | deposit | 273176 | 273117 | -59 |
Contract | Before | After | Change |
---|---|---|---|
TestCollateral | 3383940 | 3382344 | -1596 |
withdraw
function at Collateral.sol
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/Collateral.sol#L171
require(_amountWithdrawn > _fee, "Withdrawal amount too small"); _baseToken.safeTransfer(_treasury, _fee); _amountWithdrawn -= _fee;
It is obvious that _amountWithdrawn - _fee
will not be underflown since it has require(_amountWithdrawn > _fee, ...)
.
require(_amountWithdrawn > _fee, "Withdrawal amount too small"); _baseToken.safeTransfer(_treasury, _fee); unchecked { _amountWithdrawn -= _fee; }
Contract | Methods | Before | After | Change |
---|---|---|---|---|
Collateral | withdraw | 162848 | 162788 | -60 |
Contract | Before | After | Change |
---|---|---|---|
TestCollateral | 3383940 | 3382200 | -1740 |
recordDeposit
function in CollateralDepositRecord.sol
require( _amount + _globalDepositAmount <= _globalDepositCap, "Global deposit cap exceeded" ); require( _amount + _accountToNetDeposit[_sender] <= _accountDepositCap, "Account deposit cap exceeded" ); _globalDepositAmount += _amount; _accountToNetDeposit[_sender] += _amount;
Both _globalDepositAmount + _amount
and _accountToNetDeposit[_sender] + _amount
will not be overflown because it checks _amount + _globalDepositAmount <= _globalDepositCap
and _amount + _accountToNetDeposit[_sender] <= _accountDepositCap
before.
require( _amount + _globalDepositAmount <= _globalDepositCap, "Global deposit cap exceeded" ); require( _amount + _accountToNetDeposit[_sender] <= _accountDepositCap, "Account deposit cap exceeded" ); unchecked { _globalDepositAmount += _amount; _accountToNetDeposit[_sender] += _amount; }
Contract | Methods | Before | After | Change |
---|---|---|---|---|
CollateralDepositRecord | recordDeposit | 66022 | 65298 | -724 |
Contract | Before | After | Change |
---|---|---|---|
CollateralDepositRecord | 750519 | 744047 | -6472 |
recordWithdrawal
function in CollateralDepositRecord.sol
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/CollateralDepositRecord.sol#L47 https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/CollateralDepositRecord.sol#L52
if (_globalDepositAmount > _amount) { _globalDepositAmount -= _amount; } else { _globalDepositAmount = 0; } if (_accountToNetDeposit[_sender] > _amount) { _accountToNetDeposit[_sender] -= _amount; } else { _accountToNetDeposit[_sender] = 0; }
_globalDepositAmount - _amount
and _accountToNetDeposit[_sender] - _amount
will not be underflown since they are wrapped by the if statement _globalDepositAmount > _amount
or _accountToNetDeposit[_sender] > _amount
.
if (_globalDepositAmount > _amount) { unchecked { _globalDepositAmount -= _amount; } } else { _globalDepositAmount = 0; } if (_accountToNetDeposit[_sender] > _amount) { unchecked { _accountToNetDeposit[_sender] -= _amount; } } else { _accountToNetDeposit[_sender] = 0; }
Contract | Methods | Before | After | Change |
---|---|---|---|---|
CollateralDepositRecord | recordWithdrawal | 33023 | 32895 | -128 |
Contract | Before | After | Change |
---|---|---|---|
CollateralDepositRecord | 750519 | 736492 | -14027 |
allowAccounts
function in AccountAccessController.sol
https://github.com/code-423n4/2022-03-prepo/blob/main/contracts/core/AccountAccessController.sol#L44
for (uint256 _i = 0; _i < _accounts.length; _i++) { _allowedAccounts[_allowedAccountsIndex][_accounts[_i]] = true; emit AccountAllowed(_accounts[_i]); }
for (uint256 _i = 0; _i < _accounts.length; ) { _allowedAccounts[_allowedAccountsIndex][_accounts[_i]] = true; emit AccountAllowed(_accounts[_i]); unchecked { _i++; } }
Contract | Methods | Before | After | Change |
---|---|---|---|---|
MockAccountAccessController | allowAccounts | 115094 | 114786 | -308 |
Contract | Before | After | Change |
---|---|---|---|
MockAccountAccessController | 948869 | 946721 | -2148 |
blockAccounts
function in AccountAccessController.sol
for (uint256 _i = 0; _i < _accounts.length; _i++) { _blockedAccounts[_blockedAccountsIndex][_accounts[_i]] = true; emit AccountBlocked(_accounts[_i]); }
for (uint256 _i = 0; _i < _accounts.length; ) { _blockedAccounts[_blockedAccountsIndex][_accounts[_i]] = true; emit AccountBlocked(_accounts[_i]); unchecked { _i++; } }
Contract | Methods | Before | After | Change |
---|---|---|---|---|
MockAccountAccessController | blockAccounts | 115120 | 114812 | -308 |
Contract | Before | After | Change |
---|---|---|---|
MockAccountAccessController | 948869 | 946721 | -2148 |
#0 - ramenforbreakfast
2022-03-22T22:39:33Z
Excellent submission, well documented and clearly outlines gas savings. This report and #5 will be referenced as the source submissions for common optimization duplicates.