Platform: Code4rena
Start Date: 11/11/2022
Pot Size: $36,500 USDC
Total HM: 5
Participants: 62
Period: 3 days
Judge: berndartmueller
Id: 181
League: ETH
Rank: 33/62
Findings: 2
Award: $89.03
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: rotcivegaf
Also found by: 0x4non, 0xDecorativePineapple, 9svR6w, Trust, V_B, adriro, ajtra, aviggiano, brgltd, carlitox477, chaduke, codexploder, corerouter, joestakey, ladboy233, s3cunda, saian, wait
66.8068 USDC - $66.81
https://github.com/code-423n4/2022-11-non-fungible/blob/main/contracts/Exchange.sol#L216
Exchange._returnDust
does not check for transfer callStatus
success call, which may lead to user loss of funds.
A simple example is the following:
Exchange
. For some reason, her receive
payable external function reverts when receiving ether.execute
s an order on Exchange
and passes a msg.value
greater than the amount necessary for the order to be fulfilled.Exchange
execute
function in a different order, which is fulfilled. Bob gets Alice's ETH, as a result of _returnDust
VSCode
Check for callStatus
success and revert the transaction if false.
#0 - trust1995
2022-11-14T22:41:47Z
Dup of #185
#1 - c4-judge
2022-11-16T11:59:19Z
berndartmueller marked the issue as duplicate of #90
#2 - c4-judge
2022-11-16T11:59:24Z
berndartmueller marked the issue as satisfactory
#3 - c4-judge
2022-12-06T14:17:32Z
berndartmueller changed the severity to 2 (Med Risk)
🌟 Selected for report: ReyAdmirado
Also found by: 0x4non, 0xRoxas, 0xab00, Awesome, Aymen0909, Bnke0x0, Deivitto, Diana, IllIllI, Rahoz, RaymondFam, Rolezn, Sathish9098, ajtra, aphak5010, aviggiano, c3phas, carlitox477, ch0bu, cryptostellar5, erictee, lukris02, martin, rotcivegaf, saian, shark, trustindistrust, zaskoh
22.2155 USDC - $22.22
_whitelistedPolicies.length()
in PolicyManager.viewWhitelistedPolicies
diff --git a/contracts/PolicyManager.sol b/contracts/PolicyManager.sol index bcc7fc9..6d934a0 100644 --- a/contracts/PolicyManager.sol +++ b/contracts/PolicyManager.sol @@ -67,9 +67,10 @@ contract PolicyManager is IPolicyManager, Ownable { returns (address[] memory, uint256) { uint256 length = size; + uint256 setLength = _whitelistedPolicies.length(); - if (length > _whitelistedPolicies.length() - cursor) { - length = _whitelistedPolicies.length() - cursor; + if (length > setLength - cursor) { + length = setLength - cursor; } address[] memory whitelistedPolicies = new address[](length);
# before changes $ yarn test > gas1 # after changes $ yarn test > gas2 # get gas changes $ diff gas1 gas2 20c20 < | Exchange · execute · 252299 · 307513 · 273470 · 24 · - │ --- > | Exchange · execute · 252299 · 307513 · 273460 · 24 · - │ 68c68 < | PolicyManager · - · - · 580496 · 1.9 % · - │ --- > | PolicyManager · - · - · 578756 · 1.9 % · - │
uint256
instead of uint8
on for loopsdiff --git a/contracts/Exchange.sol b/contracts/Exchange.sol index ec27b1d..a9447e4 100644 --- a/contracts/Exchange.sol +++ b/contracts/Exchange.sol @@ -595,7 +595,7 @@ contract Exchange is IExchange, ReentrancyGuarded, EIP712, OwnableUpgradeable, U uint256 price ) internal returns (uint256) { uint256 totalFee = 0; - for (uint8 i = 0; i < fees.length; i++) { + for (uint256 i = 0; i < fees.length; i++) { uint256 fee = (price * fees[i].rate) / INVERSE_BASIS_POINT; _transferTo(paymentToken, from, fees[i].recipient, fee); totalFee += fee;
# before changes $ yarn test > gas1 # after changes $ yarn test > gas2 # get gas changes $ diff gas1 gas2 218c218 < | Exchange · bulkExecute · 796257 · 902099 · 852656 · 6 · - │ --- > | Exchange · bulkExecute · 796105 · 901909 · 852492 · 6 · - │ 226c226 < | Exchange · execute · 252299 · 307525 · 273464 · 24 · - │ --- > | Exchange · execute · 252268 · 307492 · 273428 · 24 · - │ 280c280 < | TestExchange · - · - · 3514198 · 11.7 % · - │ --- > | TestExchange · - · - · 3512278 · 11.7 % · - │
diff --git a/contracts/Exchange.sol b/contracts/Exchange.sol index ec27b1d..b2fa8e7 100644 --- a/contracts/Exchange.sol +++ b/contracts/Exchange.sol @@ -313,8 +313,7 @@ contract Exchange is IExchange, ReentrancyGuarded, EIP712, OwnableUpgradeable, U * @dev Cancel all current orders for a user, preventing them from being matched. Must be called by the trader of the order */ function incrementNonce() external { - nonces[msg.sender] += 1; - emit NonceIncremented(msg.sender, nonces[msg.sender]); + emit NonceIncremented(msg.sender, ++nonces[msg.sender]); }
# before changes $ yarn test > gas1 # after changes $ yarn test > gas2 # get gas changes $ diff gas1 gas2 226c226 < | Exchange · execute · 252299 · 307525 · 273464 · 24 · - │ --- > | Exchange · execute · 252299 · 307542 · 273469 · 24 · - │ 228c228 < | Exchange · incrementNonce · 32939 · 50039 · 41489 · 8 · - │ --- > | Exchange · incrementNonce · 32740 · 49840 · 41290 · 8 · - │ 280c280 < | TestExchange · - · - · 3514198 · 11.7 % · - │ --- > | TestExchange · - · - · 3509234 · 11.7 % · - │
#0 - c4-judge
2022-11-17T14:34:33Z
berndartmueller marked the issue as grade-b