-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
findNewOwner edgecase #27
Comments
oh wow, this is actually a really big problem. It's easier to see it if |
I have since thought of an attack that could have used this and might raise it to 3 (High risk). Due to the difficultly of monitoring which cards you own all the time a valid strategy which some users employ is to bid high enough to scare off other users (usually bidding significantly beyond the 10% minimum increase). Suppose Alice employs this strategy by bidding $100 on a card that was previously only $10. Thinking about it, this doesn't really even need Alice at all, Mal could have placed all the higher bids to simultaneously scare off other users while renting at a lower price. I think the fix is relatively simple, by checking if we found a valid user OR hit the deletion limit we can make it so that we don't skip any bids. This would then leave Alice (or Mal in the other version) correctly having to pay for the time at the higher price. |
upgrading based on sponsors analysis |
Fixed here |
Handle
gpersoon
Vulnerability details
Impact
In the function findNewOwner of RCOrderbook, as loop is done which included the check _loopCounter < maxDeletions
Afterwards a check is done for "(_loopCounter != maxDeletions)" to determine if the processing is finished.
If _loopCounter == maxDeletions then the conclusion is that it isn't finished yet.
However there is the edgecase that the processing might just be finished at the same time as _loopCounter == maxDeletions.
You can see this the best if you assume maxDeletions==1, in that case it will never draw the conclusion it is finished.
Of course having maxDeletions==1 is very unlikely in practice.
Proof of Concept
// https://github.com/code-423n4/2021-08-realitycards/blob/main/contracts/RCOrderbook.sol#L549
function findNewOwner(uint256 _card, uint256 _timeOwnershipChanged) external override onlyMarkets {
...
// delete current owner
do {
_newPrice = _removeBidFromOrderbookIgnoreOwner( _head.next, _market, _card );
_loopCounter++; // delete next bid if foreclosed
} while ( treasury.foreclosureTimeUser( _head.next, _newPrice, _timeOwnershipChanged ) < minimumTimeToOwnTo &&
_loopCounter < maxDeletions );
Tools Used
Recommended Mitigation Steps
Use a different way to determine that the processing is done. This could save some gas.
Note: the additional check also costs gas, so you have the verify the end result.
Perhaps in setDeletionLimit doublecheck that _deletionLimit > 1.
The text was updated successfully, but these errors were encountered: