Putty contest - saian'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: 106/133

Findings: 1

Award: $21.24

🌟 Selected for report: 0

🚀 Solo Findings: 0

Unused order.expiration

position expiration value is calculated by adding block.timestamp and duration, order's expiration value is not used

Proof of concept

positionExpirations[order.isLong ? uint256(orderHash) : positionId] = block.timestamp + order.duration;

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

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

constant variables can be changed to private

constant variable can be changed from public to internal visibility to avoid getter function

Proof of concept

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

bytes32 public constant ERC721ASSET_TYPE_HASH = keccak256(abi.encodePacked("ERC721Asset(address token,uint256 tokenId)"));

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

bytes32 public constant ERC20ASSET_TYPE_HASH = keccak256(abi.encodePacked("ERC20Asset(address token,uint256 tokenAmount)"));

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

bytes32 public constant ORDER_TYPE_HASH

Re-order require statements

require statements can be reordered to save gas on revert

Proof of concept

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

isLong condition can be placed on the top

bytes32 orderHash = hashOrder(order); // check user owns the position require(ownerOf(uint256(orderHash)) == msg.sender, "Not owner"); // check position is long require(order.isLong, "Can only exercise long positions");

Re-order conditions in require statements

Conditions in require statement can be re-ordered so that if position is exercised it consumes less gas

Proof of concept

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");

can be changed to

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

Optimize for loops

variables initialization with default values(0) can be avoided as it already contains default values, order length can be cached in a variables and re-used instead of querying length in every iteration, post-increment can be replaced with pre-increment ++i and unchecked can be added to save gas

Proof of concept

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

L556: for (uint256 i = 0; i < orders.length; i++) { L594: for (uint256 i = 0; i < assets.length; i++) { L611: for (uint256 i = 0; i < assets.length; i++) { L627: for (uint256 i = 0; i < floorTokens.length; i++) { L637: for (uint256 i = 0; i < assets.length; i++) { L647: for (uint256 i = 0; i < floorTokens.length; i++) { L658: for (uint256 i = 0; i < floorTokens.length; i++) { L670: for (uint256 i = 0; i < whitelist.length; i++) { L728: for (uint256 i = 0; i < arr.length; i++) { L742: for (uint256 i = 0; i < arr.length; i++) {

Public function can be external

Public functions that are not called inside the contract can be converted to external

Proof of concept

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

function domainSeparatorV4() public view returns (bytes32) { return _domainSeparatorV4(); }

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

function tokenURI(uint256 id) public view override returns (string memory) {
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