A short can create an NFT of its short and if this short has a bad ratio and could be liquidated, front-run this liquidator/flagger by transferring the short NFT , the liquidator TX would then revert as the short address would have changed.
When a shorter wants to create a short order he/she calls libShortRecord.sol#createShortRecord()
the process will create a struct in storage :
LibShortRecord.sol#createShortRecord()
if match => LibOrders.sol#sellMatchAlgo()
else LibOrders.sol#addShort()
will be called to add the short in the queue
when short is matched (immediately or when matched with good bid) LibOrders.sol#matchIncomingShort()
is called
LibOrders.sol#matchIncomingShort()
will call LibShortRecord.sol#createShortRecord()
LibShortRecord.sol#createShortRecord()
will create a storage struct
This struct will be specific to shorter address.
DittoEth allow a short to create an NFT representing a short order using ERC721Facet.sol#mintNFT() :
DittoEth also allow an NFT short owner to transfer this NFT to another address by using function transferFrom(address from, address to, uint256 tokenId) public
also from ERC721Facet.sol.
Process to transfer an NFT is like this :
LibShortRecord.transferShortRecord(asset, from, to, uint40(tokenId), nft)
:
Regarding liquidation ,there is 2 process to liquidate a short that has a bad ratio :
MarginCallPrimaryFacet.sol#flagShort() and then wait 10 hours to liquidate using MarginCallPrimaryFacet.sol#liquidate()
MarginCallSecondartFacet.sol#liquidateSecondary()
to liquidate shorters having a really bad ratio (< 1.5 time collateralized)
both these function use s.assetUser[asset][m.shorter].shortRecordId
to find which short to liquidate.
Regarding all this process,a malicious user which have a short with bad ratio could look at the mempool for flagShort()
or liquidateSecondary()
TX and front-run them by transferring the NFT just before so that the flag/liquidate TX would revert because of the checks on these functions :
MarginCallPrimaryFacet.sol#flagShort()
:
Both these functions have the onlyValidShortRecord()
modifier which is in AppStorage.sol
:
And revert if short is canceled (or transferred)
Regarding the second method : MarginCallSecondartFacet.sol#liquidateSecondary()
continue to next short to liquidate if short to liquidate is cancelled.
We can see that if a short is cancelled (or transferred) it won't be possible to liquidate it in any way, so a malicious user could indefinitely transfer its bad collaterallized NFT each time someone wants to liquidate it.
VSCode
Add a timelock
that prevent a transferred short to be re-transferred during 24 hours so that liquidator could liquidate it if necessary
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.