Golom contest - Lambda's results

An NFT marketplace that offers the lowest industry fee, a publicly available order-book along with analytical tools.

General Information

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

Golom

Findings Distribution

Researcher Performance

Rank: 34/179

Findings: 9

Award: $373.55

🌟 Selected for report: 1

🚀 Solo Findings: 0

Awards

26.7695 USDC - $26.77

Labels

bug
duplicate
3 (High Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-07-golom/blob/8f198624b97addbbe9602a451c908ea51bd3357c/contracts/vote-escrow/VoteEscrowDelegation.sol#L85 https://github.com/code-423n4/2022-07-golom/blob/8f198624b97addbbe9602a451c908ea51bd3357c/contracts/vote-escrow/VoteEscrowDelegation.sol#L101

Vulnerability details

Impact

When numCheckpoints[toTokenId] is 0, delegate calls _writeCheckpoint(toTokenId, 0, [tokenId]). However, _writeCheckpoint performs a nCheckpoints - 1 calculation that will underflow in this case (when nCheckpoints is 0).

Handle the case nCheckpoints == 0 separately in _writeCheckpoint.

#0 - KenzoAgada

2022-08-02T09:07:42Z

Duplicate of #630

Findings Information

🌟 Selected for report: hyh

Also found by: 0x52, 0xSky, ElKu, Krow10, Lambda, Limbooo, RustyRabbit, auditor0517, kaden, obront, rbserver, rotcivegaf, scaraven, wastewa, zzzitron

Awards

93.2805 USDC - $93.28

Labels

bug
duplicate
3 (High Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/core/GolomTrader.sol#L381 https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/core/GolomTrader.sol#L391 https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/core/GolomTrader.sol#L397

Vulnerability details

Impact

In _settleBalances, the variable protocolfee is already multiplied by the amount. However, in line 391 or 397 (depending on if a refferer is used), it is multiplied by amount again. Because of that, too little ETH is transferred to the seller and the difference is stuck forever in the contract.

Proof Of Concept

Let's consider the simple example with o.totalAmt = 10_000 and amount = 100. We have protocolFee = ((10_000 * 50) / 10000) * 100 = 5_000. Let's say (for the sake of simplicity) that there is no referrer and that o.exchange.paymentAmt = 0, o.prePayment.paymentAmt = 0, p.paymentAmt = 0. Then, we have:

payEther((10_000 - 5_000) * 100, msg.sender) = payEther(500_000, msg.sender))

Therefore, to summarize:

  • o.totalAmt * amount = 1_000_000 was transferred from the bidder (o.signer) to GolomTrader.
  • protocolFee = 5_000 was transferred from GolomTrader to the distributor.
  • 500,000 was transferred to msg.sender, i.e. the seller.

The remaining 495,500 are stuck in GolomTrader.

Set the maximumSupply to 1 billion on the token itself such that the user can be sure that no more tokens will ever exist.

#0 - KenzoAgada

2022-08-02T06:31:30Z

Duplicate of #240

Awards

34.8003 USDC - $34.80

Labels

bug
3 (High Risk)
sponsor confirmed
selected-for-report

External Links

Lines of code

https://github.com/code-423n4/2022-07-golom/blob/8f198624b97addbbe9602a451c908ea51bd3357c/contracts/vote-escrow/VoteEscrowDelegation.sol#L80

Vulnerability details

Impact

In delegate, when a user delegates to a new tokenId, the tokenId is not removed from the current delegatee. Therefore, one user can easily multiply his voting power, which makes the toking useless for voting / governance decisions.

Proof Of Concept

Bob owns the token with ID 1 with a current balance of 1000. He also owns tokens 2, 3, 4, 5. Therefore, he calls delegate(1, 2), delegate(1, 3), delegate(1, 4), delegate(1, 5). Now, if there is a governance decision and getVotes is called, Bobs balance of 1000 is included in token 2, 3, 4, and 5. Therefore, he quadrupled the voting power of token 1.

Remove the entry in delegatedTokenIds of the old delegatee or simply call removeDelegation first.

Findings Information

Labels

bug
duplicate
3 (High Risk)

Awards

131.6127 USDC - $131.61

External Links

Lines of code

https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/rewards/RewardDistributor.sol#L100 https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/core/GolomTrader.sol#L242 https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/core/GolomTrader.sol#L384

Vulnerability details

Impact

When the reward token supply is larger than a billion, epochTotalFee is no longer updated. However, the fee is still transferred to the reward distributor. But because epochTotalFee is no longer updated for those epochs, calling multiStakerClaim with them will not result in any ETH. Therefore, those tokens are forever stuck in the RewardDistributor.

Still keep track of the accumulated fees, even if no new tokens are minted anymore.

#0 - KenzoAgada

2022-08-03T14:15:35Z

Duplicate of #320

Lines of code

https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/core/GolomTrader.sol#L154

Vulnerability details

Impact

The payEther function uses transfer which has only a 2300 gas stipend for transferring ETH. Depending on the logic of the retriever (e.g., a smart contract that performs some storage read and writes on receive, for instance a multi-sig), this may not be sufficient and the transfer can revert. See also https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/ for a discussion of this issue.

Use call instead, i.e.:

(bool success, ) = payable(payAddress).call{amount}(""); require(success, "Transfer failed.");

#0 - KenzoAgada

2022-08-03T14:08:18Z

Duplicate of #343

Lines of code

https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/core/GolomTrader.sol#L236 https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/core/GolomTrader.sol#L301 https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/core/GolomTrader.sol#L361

Vulnerability details

Impact

The implementation uses transferFrom instead of safeTranferFrom for transferring ERC721 tokens. This is discouraged according to the OpenZeppelin documentation. Furthermore, there are certain contracts (e.g., https://github.com/sz-piotr/eth-card-game/blob/master/src/ethereum/contracts/ERC721Market.sol#L20-L31) that have a logic in their onERC721Received function, which will not be triggered.

Use safeTransferFrom instead of transferFrom.

#0 - KenzoAgada

2022-08-03T15:08:47Z

Duplicate of #342

Findings Information

Labels

bug
duplicate
2 (Med Risk)

Awards

47.2456 USDC - $47.25

External Links

Lines of code

https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/vote-escrow/VoteEscrowCore.sol#L604

Vulnerability details

Impact

In the safeTransferFrom of VoteEscrowCore, the ERC721 check is wrong. It is only checked if the the contract reverts on the onERC721Received call (or does not implement the function), but not if the return value is equal to IERC721Receiver.onERC721Received.selector, which is the requirement of EIP-721. Therefore, every other protocol that uses these tokens might not work correctly or the token might introduce vulnerabilities there.

Check that retval == IERC721Receiver.onERC721Received.selector, see https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol#L402 for a correct implementation.

#0 - KenzoAgada

2022-08-04T02:01:48Z

Duplicate of #577

Awards

4.5163 USDC - $4.52

Labels

bug
duplicate
2 (Med Risk)

External Links

Lines of code

https://github.com/code-423n4/2022-07-golom/blob/70aa26c4deec218891d3f1baf162d8a5fe2bc5e8/contracts/rewards/RewardDistributor.sol#L135

Vulnerability details

Impact

If a user pays too much ETH when filling an ask, it is not reimbursed too him. Moreover, it is also not transferred to someone else (e.g., the seller), meaning it is stuck in GolomTrader and therefore lost forever.

Consider reimbursing the user when he pays too much ETH.

#0 - KenzoAgada

2022-08-04T15:26:15Z

Duplicate of #75

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter