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
Rank: 10/133
Findings: 8
Award: $1,728.45
๐ Selected for report: 1
๐ Solo Findings: 0
๐ Selected for report: IllIllI
Also found by: 0x29A, 0xDjango, 0xc0ffEE, AmitN, BowTiedWardens, StErMi, auditor0517, berndartmueller, cccz, danb, dipp, dirk_y, hansfriese, horsefacts, hyh, kirk-baird, oyc_109, peritoflores, rfa, sseefried, swit, xiaoming90, zzzitron
5.5216 USDC - $5.52
https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L322-L340 https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L348-L364 https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L425-L437
The fillOrder
and exercise
functions are payable
and will accept and wrap native ETH as WETH if the order's baseAsset
is WETH and the caller provides native ETH:
// transfer premium to whoever is short from whomever is long if (order.isLong) { ERC20(order.baseAsset).safeTransferFrom(order.maker, msg.sender, order.premium); } else { // handle the case where the user uses native ETH instead of WETH to pay the premium if (weth == order.baseAsset && msg.value > 0) { // check enough ETH was sent to cover the premium require(msg.value == order.premium, "Incorrect ETH amount sent"); // convert ETH to WETH and send premium to maker // converting to WETH instead of forwarding native ETH to the maker has two benefits; // 1) active market makers will mostly be using WETH not native ETH // 2) attack surface for re-entrancy is reduced IWETH(weth).deposit{value: msg.value}(); IWETH(weth).transfer(order.maker, msg.value); } else { ERC20(order.baseAsset).safeTransferFrom(msg.sender, order.maker, order.premium); } }
// filling long put: transfer strike from taker to contract if (order.isLong && !order.isCall) { // handle the case where the taker uses native ETH instead of WETH to deposit the strike if (weth == order.baseAsset && msg.value > 0) { // check enough ETH was sent to cover the strike require(msg.value == order.strike, "Incorrect ETH amount sent"); // convert ETH to WETH // we convert the strike ETH to WETH so that the logic in exercise() works // - because exercise() assumes an ERC20 interface on the base asset. IWETH(weth).deposit{value: msg.value}(); } else { ERC20(order.baseAsset).safeTransferFrom(msg.sender, address(this), order.strike); } return positionId; }
// transfer strike from exerciser to putty // handle the case where the taker uses native ETH instead of WETH to pay the strike if (weth == order.baseAsset && msg.value > 0) { // check enough ETH was sent to cover the strike require(msg.value == order.strike, "Incorrect ETH amount sent"); // convert ETH to WETH // we convert the strike ETH to WETH so that the logic in withdraw() works // - because withdraw() assumes an ERC20 interface on the base asset. IWETH(weth).deposit{value: msg.value}(); } else { ERC20(order.baseAsset).safeTransferFrom(msg.sender, address(this), order.strike); }
However, users may intentionally or accidentally send native ETH to these functions even when the baseAsset
is not WETH. In these cases, both the ERC20 baseAsset
and native ETH will be transferred to the contract. Any native ETH sent will be locked in the contract. This scenario requires user error, but it's possible to prevent altogether.
Impact: Any native ETH accidentally provided with an ERC20 order will be locked in the contract.
Recommendation: Add a check to ensure that the order's baseAsset
must be WETH if the caller sends native ETH to payable
functions. This will prevent callers from sending (and losing) native ETH under any other conditions.
// check that baseAsset is WETH if caller provided native ETH if(msg.value > 0) require(order.baseAsset == weth, "baseAsset is not WETH");
Test case:
function testNativeETHCanBeSentWithERC20Orders() public { // arrange PuttyV2.Order memory order = defaultOrder(); order.baseAsset = address(link); order.isLong = false; bytes memory signature = signOrder(babePrivateKey, order); deal(address(this), order.premium); deal(address(link), address(this), order.premium); link.approve(address(p), order.premium); uint256 contractETHBalanceBefore = address(p).balance; uint256 takerETHBalanceBefore = address(this).balance; uint256 takerLinkBalanceBefore = link.balanceOf(address(this)); uint256 makerLinkBalanceBefore = link.balanceOf(order.maker); // act p.fillOrder{value: order.premium}(order, signature, floorAssetTokenIds); // assert // ETH deducted from caller balance assertEq( takerETHBalanceBefore - address(this).balance, order.premium, "Should have transferred ETH from taker to contract" ); // ETH balance stuck in contract assertEq( address(p).balance, order.premium, "Should have transferred ETH from taker to contract" ); // LINK transferred from taker assertEq( takerLinkBalanceBefore - link.balanceOf(address(this)), order.premium, "Should have transferred LINK from taker" ); // LINK transferred to maker assertEq( link.balanceOf(order.maker) - makerLinkBalanceBefore, order.premium, "Should have transferred LINK to maker" ); }
#0 - rotcivegaf
2022-07-04T23:32:29Z
Duplicate of #226
#1 - outdoteth
2022-07-07T14:28:52Z
Duplicate: Native ETH can be lost if itโs not utilised in exercise and fillOrder: https://github.com/code-423n4/2022-06-putty-findings/issues/226
๐ Selected for report: 0xc0ffEE
Also found by: horsefacts, pedroais, unforgiven
420.5209 USDC - $420.52
https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L324 https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L344
Tokens whose market value is related to some stateful property may be manipulated in certain scenarios during order execution. This requires a number of specific assumptions, and it's not really possible to implement contract-level safeguards against it, but I think it's worth considering the scenario, documenting it for your end users, and watching out for it in the wild.
Scenario:
baseAsset
. (For example, an ERC777 or nonstandard ERC20). She signs her order from a smart contract that can recieve the before transfer callback.fillOrder
to fill Eve's order and collects the premium. Before Eve's tokens are transferred, her contract recieves the transfer callback. In the callback hook, Eve claims the unclaimed airdrop related to her token. Without the associated tokens, the fair market value of the token is now 10 ETH.exercise
and exercises her option. She has received 15 ETH from the option, plus 5 ETH from the airdrop claim, minus the 0.1 ETH premium, or 19.9 ETH total. Bob can only recoup 10 ETH of the 15 ETH strike on the open market.Impact: Malicious makers may trick takers into writing options at above market strike prices for certain stateful tokens.
Recommendation: There is not really a reasonable fix here at the contract level. Instead, I recommend clearly documenting the risks of writing options on tokens with stateful properties for your end users, and keeping an eye out for this behavior in production.
#0 - outdoteth
2022-07-06T19:32:45Z
Duplicate: Itโs possible to flashloan all assets in the contract without paying a protocol fee: https://github.com/code-423n4/2022-06-putty-findings/issues/377
#1 - HickupHH3
2022-07-13T06:38:06Z
Scenario described is something I've seen with $APE token and flashloaning from NFTX.
๐ Selected for report: horsefacts
Also found by: 0xc0ffEE, IllIllI, Picodes, Sm4rty, berndartmueller, csanuragjain, shenwilly, unforgiven
35.1904 USDC - $35.19
https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L302-L308 https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2Nft.sol#L11-L18
Putty uses ERC721 safeTransfer
and safeTransferFrom
throughout the codebase to ensure that ERC721 tokens are not transferred to non ERC721 receivers. However, the initial position mint in fillOrder
uses _mint
rather than _safeMint
and does not check that the receiver accepts ERC721 token transfers:
// create long/short position for maker _mint(order.maker, uint256(orderHash)); // create opposite long/short position for taker bytes32 oppositeOrderHash = hashOppositeOrder(order); positionId = uint256(oppositeOrderHash); _mint(msg.sender, positionId);
function _mint(address to, uint256 id) internal override { require(to != address(0), "INVALID_RECIPIENT"); require(_ownerOf[id] == address(0), "ALREADY_MINTED"); _ownerOf[id] = to; emit Transfer(address(0), to, id); }
Impact: If a maker or taker are a contract unable to receive ERC721 tokens, their options positions may be locked and nontransferable. If the receiving contract does not provide a mechanism for interacting with Putty, they will be unable to exercise their position or withdraw assets.
Recommendation: Consider implementing the require
check in Solmate's ERC721#_safeMint
in your own mint function:
function _safeMint(address to, uint256 id) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); }
However, note that calling _safeMint
introduces a reentrancy opportunity! If you make this change, ensure that the mint is treated as an interaction rather than an effect, and consider adding a reentrancy guard:
/* ~~~ EFFECTS ~~~ */ // create opposite long/short position for taker bytes32 oppositeOrderHash = hashOppositeOrder(order); positionId = uint256(oppositeOrderHash); // save floorAssetTokenIds if filling a long call order if (order.isLong && order.isCall) { positionFloorAssetTokenIds[uint256(orderHash)] = floorAssetTokenIds; } // save the long position expiration positionExpirations[order.isLong ? uint256(orderHash) : positionId] = block.timestamp + order.duration; emit FilledOrder(orderHash, floorAssetTokenIds, order); /* ~~~ INTERACTIONS ~~~ */ _safeMint(order.maker, uint256(orderHash)); _safeMint(msg.sender, positionId);
Alternatively, document the design decision to use _mint
and the associated risk for end users.
#0 - outdoteth
2022-07-06T19:36:47Z
Pasting from another issue:
It's unlikely a contract will have all the setup required to interact with PuttyV2 but not be able to handle ERC721 tokens. Adding a check via safeMint adds a gas overhead as well as another re-entrancy attack vector so there is a tradeoff (as noted in the issue report^^).
#1 - outdoteth
2022-07-08T13:34:32Z
Report: Contracts that canโt handle ERC721 tokens will lose their Putty ERC721 position tokens
#2 - HickupHH3
2022-07-13T12:09:25Z
In addition, some contracts may have custom logic in their onERC721Received()
implementation that is triggered only by the safe methods and not their "unsafe" counterparts.
๐ Selected for report: codexploder
Also found by: ACai, Critical, cccz, horsefacts, ignacio, shenwilly, unforgiven, xiaoming90
110.3615 USDC - $110.36
Judge has assessed an item in Issue #330 as Medium risk. The relevant finding follows:
#0 - HickupHH3
2022-07-15T14:19:59Z
Options can be written with zero duration
Duplicate: Orders with low durations can be easily DOSโd and prevent possibility of exercise: https://github.com/code-423n4/2022-06-putty-findings/issues/265
๐ Selected for report: xiaoming90
Also found by: 0x1f8b, 0x29A, 0x52, 0xDjango, 0xNazgul, 0xNineDec, 0xSolus, 0xf15ers, 0xsanson, AmitN, Bnke0x0, BowTiedWardens, Chom, David_, ElKu, Funen, GalloDaSballo, GimelSec, Hawkeye, IllIllI, JC, JohnSmith, Kaiziron, Kenshin, Lambda, Limbooo, MadWookie, Metatron, MiloTruck, Nethermind, Picodes, ReyAdmirado, Sneakyninja0129, StErMi, TomJ, Treasure-Seeker, TrungOre, Waze, Yiko, _Adam, __141345__, antonttc, async, aysha, catchup, cccz, cryptphi, csanuragjain, danb, datapunk, defsec, delfin454000, dirk_y, doddle0x, durianSausage, exd0tpy, fatherOfBlocks, gogo, hake, hansfriese, horsefacts, hubble, itsmeSTYJ, joestakey, oyc_109, pedroais, peritoflores, rajatbeladiya, reassor, robee, rokinot, samruna, saneryee, sashik_eth, shenwilly, shung, simon135, sseefried, unforgiven, zer0dot, zzzitron
47.238 USDC - $47.24
Since the tokens Putty uses to represent positions are themselves ERC721s, it's possible to open and fill orders that use Putty position tokens as the underlying asset.
Here's an example order and fill on Rinkeby that use a Putty token as the underlying.
I don't see a clear exploit path here, but this is potentially unintentional behavior that could lead to unexpected results.
Recommendation: Check that the underlying asset in a Putty order is not a Putty position token.
The contract owner can observe and frontrun calls to withdraw
to extract the maximum protocol fee.
Scenario:
fee
parameter is set to 0.5%.withdraw
in the mempool.setFee
to set fees to the maximum value of 3%.Recommendation: This finding is already significantly mitigated by limiting the maximum fee and emitting an event. However, it's possible to further limit the owner's ability to make unexpected changes by ensuring the contract owner is a timelock proxy with a waiting period for parameter changes.
It's possible for users to accidentally submit zero duration orders. If filled, the taker would collect the strike price, but the option would be immediately expired. Consider requiring both a minimum and maximum order duration.
Solidity versions 0.8.13 and 0.8.14 are vulnerable to a recently reported optimizer bug related to inline assembly. Solidity 0.8.15 has been released with a fix.
This bug only occurs under very specific conditions: the legacy optimizer must be enabled rather than the IR pipeline (true for the current project configuration), and the affected assembly blocks must not refer to any local Solidity variables. The Solmate and OpenZeppelin libraries used in this project make use of inline assembly, but do not appear vulnerable. However, it's worth being aware of this vulnerability. Consider upgrading to Solidity 0.8.15.
ORDER_TYPE_HASH
refers to ERC721Asset
rather than Order
#0 - outdoteth
2022-07-07T18:34:38Z
Contract owner can frontrun withdrawals
Duplicate: Admin can change fee at any time for existing orders: https://github.com/code-423n4/2022-06-putty-findings/issues/422
Options can be written with zero duration
Duplicate: Orders with low durations can be easily DOSโd and prevent possibility of exercise: https://github.com/code-423n4/2022-06-putty-findings/issues/265
Optimizer bug in Solidity 0.8.13 and 0.8.14
Duplicate: Use of solidity 0.8.13 with known issues in ABI encoding and memory side effects: https://github.com/code-423n4/2022-06-putty-findings/issues/348
๐ Selected for report: GalloDaSballo
Also found by: 0v3rf10w, 0x1f8b, 0xA5DF, 0xDjango, 0xHarry, 0xKitsune, 0xNazgul, 0xNineDec, 0xc0ffEE, 0xf15ers, 0xkatana, 0xsanson, ACai, Aymen0909, Bnke0x0, BowTiedWardens, Chom, ElKu, Fitraldys, Funen, Haruxe, Hawkeye, IllIllI, JC, JohnSmith, Kaiziron, Kenshin, Lambda, Limbooo, MadWookie, Metatron, MiloTruck, Picodes, PwnedNoMore, Randyyy, RedOneN, ReyAdmirado, Ruhum, Sm4rty, StErMi, StyxRave, TerrierLover, TomJ, Tomio, UnusualTurtle, Waze, Yiko, _Adam, __141345__, ajtra, ak1, apostle0x01, asutorufos, c3phas, cRat1st0s, catchup, codetilda, cryptphi, datapunk, defsec, delfin454000, durianSausage, exd0tpy, fatherOfBlocks, gogo, grrwahrr, hake, hansfriese, horsefacts, ignacio, jayfromthe13th, joestakey, ladboy233, m_Rassska, mektigboy, minhquanym, mrpathfindr, natzuu, oyc_109, rajatbeladiya, reassor, rfa, robee, rokinot, sach1r0, saian, sashik_eth, simon135, slywaters, swit, z3s, zeesaw, zer0dot
21.1707 USDC - $21.17
The positionExpirations
and exercisedPositions
mappings may be packed into a single mapping using a struct, if you're willing to use a smaller integer type to represent expiration timestamps.
/** @notice The current expiration timestamp of a position. Maps from positionId to an expiration unix timestamp. */ mapping(uint256 => uint256) public positionExpirations; /** @notice Whether or not a position has been exercised. Maps from positionId to isExercised. */ mapping(uint256 => bool) public exercisedPositions;
For example, something like:
struct Position { uint128 expiration; bool exercised; } mapping(uint256 => Position) public positions;
This will save gas on exercise
and withdraw
, but slightly increase the cost of fillOrder
.
Gas report before:
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโโฎ โ src/PuttyV2.sol:PuttyV2 contract โ โ โ โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโชโโโโโโโโโโโโโโโโโโชโโโโโโโโโชโโโโโโโโโชโโโโโโโโโชโโโโโโโโโโก โ Deployment Cost โ Deployment Size โ โ โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ 4774898 โ 25230 โ โ โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ Function Name โ min โ avg โ median โ max โ # calls โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ baseURI โ 1321 โ 1321 โ 1321 โ 1321 โ 1 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ cancel โ 3075 โ 26509 โ 34321 โ 34321 โ 4 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ cancelledOrders โ 550 โ 550 โ 550 โ 550 โ 1 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ exercise โ 5759 โ 55920 โ 68002 โ 133534 โ 18 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ exercisedPositions โ 528 โ 528 โ 528 โ 528 โ 1 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ fee โ 406 โ 406 โ 406 โ 406 โ 1 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ fillOrder โ 10014 โ 106851 โ 115891 โ 203785 โ 51 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ hashOrder โ 5206 โ 5484 โ 5206 โ 7782 โ 62 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ onERC721Received โ 815 โ 815 โ 815 โ 815 โ 14 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ ownerOf โ 554 โ 554 โ 554 โ 554 โ 4 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ positionExpirations โ 526 โ 526 โ 526 โ 526 โ 1 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ positionFloorAssetTokenIds โ 734 โ 734 โ 734 โ 734 โ 3 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ setBaseURI โ 2853 โ 9153 โ 12303 โ 12303 โ 3 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ setFee โ 2498 โ 14052 โ 14057 โ 25597 โ 4 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ tokenURI โ 2606 โ 24547 โ 24547 โ 46489 โ 2 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ transferFrom โ 5255 โ 5255 โ 5255 โ 5255 โ 1 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ withdraw โ 3075 โ 27840 โ 24545 โ 71168 โ 10 โ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโดโโโโโโโโโดโโโโโโโโโดโโโโโโโโโดโโโโโโโโโโฏ
Gas report after:
โญโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโฌโโโโโโโโโโฎ โ src/PuttyV2.sol:PuttyV2 contract โ โ โ โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโชโโโโโโโโโโโโโโโโโโชโโโโโโโโโชโโโโโโโโโชโโโโโโโโโชโโโโโโโโโโก โ Deployment Cost โ Deployment Size โ โ โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ 4808352 โ 25397 โ โ โ โ โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ Function Name โ min โ avg โ median โ max โ # calls โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ baseURI โ 1321 โ 1321 โ 1321 โ 1321 โ 1 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ cancel โ 3075 โ 26509 โ 34321 โ 34321 โ 4 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ cancelledOrders โ 550 โ 550 โ 550 โ 550 โ 1 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ exercise โ 5759 โ 42542 โ 46108 โ 116019 โ 18 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ fee โ 361 โ 361 โ 361 โ 361 โ 1 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ fillOrder โ 10014 โ 106892 โ 115942 โ 203836 โ 51 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ hashOrder โ 5206 โ 5484 โ 5206 โ 7782 โ 62 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ onERC721Received โ 815 โ 815 โ 815 โ 815 โ 14 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ ownerOf โ 554 โ 554 โ 554 โ 554 โ 4 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ positionFloorAssetTokenIds โ 734 โ 734 โ 734 โ 734 โ 3 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ positions โ 590 โ 590 โ 590 โ 590 โ 2 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ setBaseURI โ 2853 โ 9153 โ 12303 โ 12303 โ 3 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ setFee โ 2498 โ 14052 โ 14057 โ 25597 โ 4 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ tokenURI โ 2606 โ 24547 โ 24547 โ 46489 โ 2 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ transferFrom โ 5255 โ 5255 โ 5255 โ 5255 โ 1 โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโค โ withdraw โ 3075 โ 26879 โ 23693 โ 70722 โ 10 โ โฐโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโดโโโโโโโโโดโโโโโโโโโดโโโโโโโโโดโโโโโโโโโโฏ