Putty contest - Funen's results

An order-book based american options market for NFTs and ERC20s.

General Information

Platform: Code4rena

Start Date: 29/06/2022

Pot Size: $50,000 USDC

Total HM: 20

Participants: 133

Period: 5 days

Judge: hickuphh3

Total Solo HM: 1

Id: 142

League: ETH

Putty

Findings Distribution

Researcher Performance

Rank: 65/133

Findings: 2

Award: $68.82

🌟 Selected for report: 0

🚀 Solo Findings: 0

  1. Block.timestamp would do missbehavior

block.timestamp is a value that keeps growing. It's the timestamp of the EVM, so it's increasing by the seconds. checking positionExpirations[uint256(orderHash)] will throw error that "Position has expired".

https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L401

require(block.timestamp < positionExpirations[uint256(orderHash)], "Position has expired");

but in this case, checking block.timestamp > positionExpirations[longPositionId] || isExercised would throw and error that should be "Must not be exercised or expired" either.

https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L481

require(block.timestamp > positionExpirations[longPositionId] || isExercised, "Must be exercised or expired");

it should be check if less than "<" positionExpirations[longPositionId] || isExercised

  1. constants can be used than using numbers

1.) File : PuttyV2.sol Line.241

require(_fee < 30, "fee must be less than 3%");

2.) File : PuttyV2.sol Line.287

require(order.duration < 10_000 days, "Duration too long");

3.) File : PuttyV2.sol Line.499

feeAmount = (order.strike * fee) / 1000;
  1. Reorder ERC20Asset and ERC721Asset typehash for better

https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L86-L96

Since usually ERC20 was the first being put in order it can be changed into ERC20Asset first then ERC721Asset typehash for better code readibility and use.

  1. Comment & Reason string consistency

https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L286-L287

// check duration is valid require(order.duration < 10_000 days, "Duration too long");

Since it was for check if order.duration less than 10_000 days, and the comment said that check duration is valid. Reason string can be changed if it wasn't intended to not valid Duration.

  1. changed using ++i than i++ for cost less gas

Using i++ instead ++i for all the loops, the variable i is incremented using i++. It is known that implementation by using ++i costs less gas per iteration than i++.

/contracts/src/PuttyV2.sol#L556 for (uint256 i = 0; i < orders.length; i++) { /contracts/src/PuttyV2.sol#L611 for (uint256 i = 0; i < assets.length; i++) { /contracts/src/PuttyV2.sol#L627 for (uint256 i = 0; i < assets.length; i++) { /contracts/src/PuttyV2.sol#L637 for (uint256 i = 0; i < floorTokens.length; i++) { /contracts/src/PuttyV2.sol#L647 for (uint256 i = 0; i < assets.length; i++) /contracts/src/PuttyV2.sol#L658 for (uint256 i = 0; i < floorTokens.length; i++) { /contracts/src/PuttyV2.sol#L670 for (uint256 i = 0; i < whitelist.length; i++) { /contracts/src/PuttyV2.sol#L728 for (uint256 i = 0; i < arr.length; i++) { /contracts/src/PuttyV2.sol#L742 for (uint256 i = 0; i < arr.length; i++) {
  1. short reason string can be used for saving more gas

Every reason string takes at least 32 bytes. Use short reason strings that fits in 32 bytes or it will become more expensive.

/contracts/src/PuttyV2.sol#L297 "Wrong amount of floor tokenIds" /contracts/src/PuttyV2.sol#L298 "Invalid floor tokens length" /contracts/src/PuttyV2.sol#L405 "Wrong amount of floor tokenIds" /contracts/src/PuttyV2.sol#L406 "Invalid floor tokens length" /contracts/src/PuttyV2.sol#L481 "Must be exercised or expired" /contracts/src/PuttyV2.sol#L765 "URI query for NOT_MINTED token"
  1. Saving gas by removing = 0

This implementation code can be saving more gas by removing = 0, it because If a variable was not set/initialized, it is assumed to have default value to 0

/contracts/src/PuttyV2.sol#L497 uint256 feeAmount = 0;
  1. change uint256 i = 0 into uint i for saving more gas

using this implementation can saving more gas for each loops.

/contracts/src/PuttyV2.sol#L556 for (uint256 i = 0; i < orders.length; i++) { /contracts/src/PuttyV2.sol#L611 for (uint256 i = 0; i < assets.length; i++) { /contracts/src/PuttyV2.sol#L627 for (uint256 i = 0; i < assets.length; i++) { /contracts/src/PuttyV2.sol#L637 for (uint256 i = 0; i < floorTokens.length; i++) { /contracts/src/PuttyV2.sol#L647 for (uint256 i = 0; i < assets.length; i++) /contracts/src/PuttyV2.sol#L658 for (uint256 i = 0; i < floorTokens.length; i++) { /contracts/src/PuttyV2.sol#L670 for (uint256 i = 0; i < whitelist.length; i++) { /contracts/src/PuttyV2.sol#L728 for (uint256 i = 0; i < arr.length; i++) { /contracts/src/PuttyV2.sol#L742 for (uint256 i = 0; i < arr.length; i++) {
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