Platform: Code4rena
Start Date: 26/07/2022
Pot Size: $75,000 USDC
Total HM: 29
Participants: 179
Period: 6 days
Judge: LSDan
Total Solo HM: 6
Id: 148
League: ETH
Rank: 170/179
Findings: 2
Award: $0.15
🌟 Selected for report: 1
🚀 Solo Findings: 0
🌟 Selected for report: cloudjunky
Also found by: 0x1f8b, 0x4non, 0x52, 0xDjango, 0xHarry, 0xNazgul, 0xNineDec, 0xf15ers, 0xsanson, 0xsolstars, 8olidity, Bnke0x0, CertoraInc, Chom, Deivitto, Dravee, GalloDaSballo, GimelSec, IllIllI, Jmaxmanblue, JohnSmith, Jujic, Kenshin, Krow10, Lambda, MEP, Noah3o6, RedOneN, Ruhum, StErMi, StyxRave, TomJ, Treasure-Seeker, TrungOre, _Adam, __141345__, arcoun, asutorufos, bardamu, bearonbike, bin2chen, brgltd, bulej93, c3phas, cRat1st0s, carlitox477, cccz, codexploder, cryptonue, cryptphi, cthulhu_cult, dharma09, dipp, djxploit, durianSausage, ellahi, giovannidisiena, hansfriese, horsefacts, hyh, immeas, indijanc, jayjonah8, jayphbee, joestakey, kenzo, kyteg, ladboy233, minhquanym, navinavu, obront, oyc_109, peritoflores, rbserver, reassor, rokinot, rotcivegaf, saian, scaraven, shenwilly, simon135, sseefried, teddav, zzzitron
0.0048 USDC - $0.00
https://github.com/code-423n4/2022-07-golom/blob/main/contracts/core/GolomTrader.sol#L154
L154 in GolomTrader.sol uses .transfer()
to send ether to other addresses. There are a number of issues with using .transfer()
, as it can fail for a number of reasons (specified in the Proof of Concept).
payable
function or it implements a payable
function but that function uses more than 2300 gas units.payable
fallback
function or it implements a payable
fallback
function but that function uses more than 2300 gas units..transfer()
creates a hard dependency on 2300 gas units being appropriate now and into the future.Vim
Instead use the .call()
function to transfer ether and avoid some of the limitations of .transfer()
. This would be accomplished by changing payEther()
to something like;
(bool success, ) = payable(payAddress).call{value: payAmt}(""); // royalty transfer to royaltyaddress require(success, "Transfer failed.");
Gas units can also be passed to the .call()
function as a variable to accomodate any uses edge cases. Gas could be a mutable state variable that can be set by the contract owner.
#0 - 0xsaruman
2022-09-04T09:52:57Z
#1 - dmvt
2022-10-21T15:06:22Z
Given how many upgrades I'm making on this, I figured a comment on my reasoning was in order. In many contests, this would be considered low risk. While unlikely to occur without warning, it is well-documented and so very well might occur at some point in the foreseeable future. With Golom's implementation, the entire functionality of the protocol would break if the gas price were to rise, resulting in a need to relaunch/redeploy. The extreme nature of this disruption offsets the other factors normally considered and is why I consider it to be a medium risk in this contest.
🌟 Selected for report: TomJ
Also found by: 0x4non, 0x52, 0xDjango, 0xNazgul, 0xf15ers, 0xsanson, 8olidity, Bnke0x0, CertoraInc, Ch_301, Chom, Dravee, GalloDaSballo, GimelSec, JC, Jujic, Kenshin, Kumpa, Lambda, M0ndoHEHE, PaludoX0, RedOneN, Ruhum, Sm4rty, Treasure-Seeker, TrungOre, Twpony, Waze, _Adam, __141345__, apostle0x01, arcoun, benbaessler, bin2chen, brgltd, cccz, cloudjunky, cryptonue, djxploit, ellahi, erictee, hansfriese, i0001, minhquanym, oyc_109, peritoflores, rbserver, reassor, rokinot, rotcivegaf, saian, shenwilly, sseefried
0.1513 USDC - $0.15
https://github.com/code-423n4/2022-07-golom/blob/main/contracts/core/GolomTrader.sol#L236 https://github.com/code-423n4/2022-07-golom/blob/main/contracts/core/GolomTrader.sol#L301
L236 and L301 in GolomTrader.sol use .transfer()
to send ERC721 tokens to recipients that could be an Externally Owned Address or Smart Contract. If the destination of a token transfer is a smart contract that has implemented onERC721Received
it will not be triggered by .transferFrom()
. This would break functionality for ERC721 transfers for other contracts or exchanges bidding on items in Golom and then wanting to execute onERC721Received
when receiving the token. In the worst case scenario it could result in ERC721 tokens being sent to a contract that doesn’t have functionality to support that token and can’t forward them anywhere else, locking them in the contract.
This could effect other marketplaces leveraging Golom for their order book. An example such as;
onERC721Received
and being compliant with the ERC721 Standard the function is not called and custom logic (which might revert the transaction) for dealing with NFT transfers is not executed.A second example involves the situation where a smart contract fills an ask but doesn’t implement functionality like onERC721Received
or other functionality to deal with tokens being transferred to it. With .transferFrom()
tokens could still be send to the contract and be locked within it. However with .safeTransferFrom()
if the contract doesn’t implement onERC721Received
then the transfer will be reverted.
Vim
Use .safeTransferFrom()
instead of .transferFrom()
for all ERC721 token transfers. This can be accomplished by extending the interface for ERC721 in GolomTrader.sol;
interface ERC721 { - function transferFrom( - address from, - address to, - uint256 tokenId - ) external; + function safeTransferFrom( + address from, + address to, + uint256 tokenId + ) external; }
And then changing L236 and L301 to use .safeTransferFrom()
instead of .transferFrom()
for example;
L236 ERC721(o.collection).safeTransferFrom(o.signer, receiver, o.tokenId); L301 nftcontract.safeTransferFrom(msg.sender, o.signer, o.tokenId);
#0 - KenzoAgada
2022-08-03T15:13:21Z
Duplicate of #342