Closed code423n4 closed 2 years ago
The warden is saying that:
PuttyV2
would not revertI believe both are questionable assumptions
Duplicate: Setting malicious or invalid erc721Assets, erc20Assets or floorTokens prevents the option from being exercised: https://github.com/code-423n4/2022-06-putty-findings/issues/50
Lines of code
https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2Nft.sol#L20-L37 https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L259-L380
Vulnerability details
Impact
by calling
fillOrder()
contract mint twoNFT
token position forLong
andShort
position formaker
andtaker
and also code transfers premium (which is based onorder.baseAsset
) fromLong
position owner toShort
position owner and transfers collaterals fromShort
position owner toPuttyV2
address soLong
positions owner can claim those collaterals by callingexercise()
and paying thestrike
price. all the address of tokens are defined in order object so Attacker can sign malicious order which look profitable but transfers NFT position token of caller to attacker (set NFT position token of caller as premium or collateral, the ID of caller NFT position token is calculable when attacker signs the order) and if any user tries to fill that order he will lose his funds. so the impact of this bug is that users would lose their funds by filling orders.Proof of Concept
To exploit this attacker have multiple choices, the real bug is that contract allows token address in
order
to be equal toPuttyV2
address, it means attacker can create and sign an order which look very good for filler but when someone callsfillOrder()
for that order, code would mint caller an NFT position token but transfer that NFT to attacker as premium or to contract as collateral(which attacker can claim later) and user would lose his funds. the detail steps of exploit is:PuttyV2
address.fillOrder()
for that order. (attacker can somehow trick users to click onfillOrder()
too by creating a lot of order)fillOrder
logic would mintNFT
positions for caller but in the line338
(ERC20(order.baseAsset).safeTransferFrom(msg.sender, order.maker, order.premium)
) code would transfer NFT position token of caller to the attacker address because: (order.baseAsset == PuttyV2
andmsg.sender == user
andorder.maker == attacker
andorder.premium == caller NFT position token ID
) and also code would transfer other user tokens that are specified in order as collateral.NFT
position token.The other thing that attacker do is in this steps:
PuttyV2
address.fillOrder()
for that order. (attacker can somehow trick users to click onfillOrder()
too by creating a lot of order)fillOrder
logic would mintNFT
positions for caller but in the line376
(_transferERC721sIn(order.erc721Assets, msg.sender);
) code would transfer NFT position token of caller to thePuttyV2
address because: (order.erc721Assets == [(address=PuttyV2, id= caller NFT token ID)]
andmsg.sender == user
) and also code would transfer other user tokens that are specified in order as collateral.exercise()
andwithdraw()
to get his and user tokens from contract.So because contract logics allows token addresses in order to be
PuttyV2
address it's possible to create malicious order that it seems very profitable for caller but in fact it transfers user NFT position token to contract as collateral or to attacker as premium so user couldn't use the filled order position after callingfillOrder()
and his funds would be lost.Tools Used
VIM
Recommended Mitigation Steps
don't allow the token address in order to be
PuttyV2
address.