Golom contest - MEP'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: 18/179

Findings: 7

Award: $676.85

🌟 Selected for report: 0

🚀 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/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/vote-escrow/VoteEscrowDelegation.sol#L101

Vulnerability details

In VoteEscrowDelegation.sol in the function delegate when nCheckpoint = 0, which is the case for every account that has not delegated yet, the function _writeCheckpoint is called. However, this function computes (nCheckpoints - 1) L101 which thus causes an underflow. Contracts are compiled in 8.11.0 so underflow reverts, and no one is then able to delegate his voting power.

Suggested fix: the function _writeCheckpoint should check if nCheckpoints is zero and behave accordingly.

#0 - KenzoAgada

2022-08-02T09:05:28Z

Duplicate of #630

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/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/vote-escrow/VoteEscrowDelegation.sol#L32

Vulnerability details

The mapping delegates in VoteEscrowDelegation can be misleading (it is not updated when a delegation is removed). If someone is relying on this value (not the case here, because this mapping is never used in the contracts (?), but we can assume that it has / will have / should have a purpose).

Suggested fix: update the mapping when a delegation is removed.

#0 - KenzoAgada

2022-08-02T12:11:52Z

Duplicate of #169

Findings Information

🌟 Selected for report: CertoraInc

Also found by: 0xA5DF, 0xsanson, Bahurum, GalloDaSballo, MEP, TrungOre, carlitox477, cryptphi, kenzo

Labels

bug
duplicate
3 (High Risk)

Awards

280.8379 USDC - $280.84

External Links

Lines of code

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

Vulnerability details

In VoteEscrowDelegation.sol L242, the function removeDelegation is called externally (with the syntax this.), but that external call changes the msg.sender. So in the function removeDelegation, msg.sender will be the contract itself, not the user. But this function requires that the owner of the NFT is msg.sender, that will always be false for NFTs owned by the user.

Sggested fix: call removeDelegation internally (so make this function public instead of external).

#0 - KenzoAgada

2022-08-02T05:52:03Z

Duplicate of #377

Findings Information

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/e5efa8f9d6dda92a90b8b2c4902320acf0c26816/contracts/vote-escrow/VoteEscrowDelegation.sol#L210

Vulnerability details

When a delegation is created (with the function delegate, the ID of its NFT (tokenId) is added in the array checkpoints[toTokenId][nCheckpoints - 1]; where toTokenId is the ID of NFT the user delegates its NFT to.

When an user removes the delegation of his NFT (with the function removeDelegation L210), tokenId is removed from checkpoints[tokenId][nCheckpoints - 1] istead of checkpoints[toTokenId][nCheckpoints - 1].

toTokenId can be retrieved in removeDelegation through the mapping delegates, but be aware that this mapping is not accurate (reported as a Medium).

#0 - KenzoAgada

2022-08-02T08:22:58Z

Duplicate of #751

Lines of code

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

Vulnerability details

The payEther() of GolomTrader.sol uses tranfer() to send ether. An annoying person could create an appealing offer from an address that does not accept incoming eth (typically a solidity contract without fallback() nor receive()). Thus, fooled users will send transactions that will revert.

One could use send() instead, but this would prevent multisig from using this protocol, because of the lack of gas (capped to 23000, contrary to call()).

Suggested fix: use .call with a value, and do not revert in case of failure.

#0 - KenzoAgada

2022-08-03T14:03:03Z

Duplicate of #343

Findings Information

🌟 Selected for report: 0xDjango

Also found by: 0x52, 0xsanson, MEP, kenzo, simon135

Labels

bug
duplicate
2 (Med Risk)

Awards

214.0206 USDC - $214.02

External Links

Lines of code

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

Vulnerability details

A DoS is possible in VoteEscrowDelegation.sol, in the function delegate L99 : require(_delegatedTokenIds.length < 500, 'VVDelegation: Cannot stake more'); But delegating an NFT is cheap: it is possible to create_lock with as low as 1 wei of token and then to delegate the NFT. Thus an attacker could delegate 500 NFT paying pretty much nothing but gas fees. Then, it would not be possible for anyone to use the functiondelegate with the same target NFT.

#0 - 0xA5DF

2022-08-11T09:32:43Z

Warden has a point, however the attacker would have to spend a significant amount of gas (at least 1000 function calls), while this would only disable 1 token from being delegated to. The owner of the token attacked can simply create a new token that people would be delegating to instead.

Also, there's no recommended mitigation (increasing the array size doesn't make sense, maybe have a minimum golom tokens to lock?).

#1 - zeroexdead

2022-08-15T14:17:03Z

Duplicate of #707

  • In GolomTrader.sol, L177 should be removed to match the purpose of the function.
  • In GolomTrader.sol L45, the variable WETH should be set constant.
  • In the contract GolomTrader, the functions fillAsk, fillBid, cancelOrder and fillCriteriaBid should be set external instead of public.
  • In the file RewardDistributor.sol, an interface ERC20 is defined, with functions that usual ERC20 token do not implement (balanceOfNFTAt L26, that is never used in the code, and deposit). Consider creating a dinstinct interfaces for the WETH token (that implements the function deposit and that inherits from a classic IERC20 interface), and the rewardToken can implement a classic IERC20 interface.
  • In the contract RewardDistributor, consider using 1 days instad of defining a constant secsInDay.
  • The interface IVoteEscrow defined L12 of VoteEscrowDelegation.sol is never used.
  • In VoteEscrowDelegation.sol L68, template notice is left in commentary
  • In VoteEscrowDelegation.sol misspelling L227
  • In VoteEscrowCore.sol misspellings L526 & L688
  • In VoteEscrowCore.sol L1108, commentary about Vyper not deleted when copy pasted the code
  • In VoteEscrowCore.sol L8, the author is not Curve Finance, their contract is written in Vyper. Should precise that this contract is inspired by Curve Finance's Voting Escrow contract.
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