Omniscia Seen Haus Audit
AuctionRunnerFacet Manual Review Findings
AuctionRunnerFacet Manual Review Findings
ARF-01M: Ineffectual Protection & Bid Refund Re-Entrancy
Type | Severity | Location |
---|---|---|
Logical Fault | Major | AuctionRunnerFacet.sol:L116, L128 |
Description:
The bid
code refunds the previous buyer
's bid before replacing the bid data with the new one. This permits a re-entrancy attack to unfold whereby the current buyer
of an auction is informed of the action. As a result, a complex attack can unfold whereby a secondary auction can steal user funds by creating an auction and a corresponding bid, waiting for a victim's outbid and then during the re-entrancy cancelling the auction thereby refunding the bid to the malicious attacker twice while causing the victim's funds to be permanently lost in the contract. We should note that the attack vector is possible due to the fact that the isContract
safe-guard is ineffectual and can be bypassed by the constructor
of a contract given that it will yield false
for a contract in-creation.
Example:
115// Make sure we can accept the caller's bid116require(!AddressUpgradeable.isContract(msg.sender), "Contracts may not bid");117require(block.timestamp >= auction.start, "Auction hasn't started");118if ((auction.state != State.Pending) || (auction.clock != Clock.Trigger)) {119 require(block.timestamp <= endTime, "Auction timer has elapsed");120}121require(msg.value >= auction.reserve, "Bid below reserve price");122
123// If a standing bid exists:124// - Be sure new bid outbids previous125// - Give back the previous bidder's money126if (auction.bid > 0) {127 require(msg.value >= (auction.bid + getPercentageOf(auction.bid, getMarketController().getOutBidPercentage())), "Bid too small");128 auction.buyer.transfer(auction.bid);129 emit BidReturned(consignment.id, auction.buyer, auction.bid);130}131
132// Record the new bid133auction.bid = msg.value;134auction.buyer = payable(msg.sender);135getMarketController().setConsignmentPendingPayout(consignment.id, msg.value);
Recommendation:
We advise the Checks-Effects-Interactions (CEI) pattern to be conformed to by applying a pull pattern to bid refunds. If refunds are disbursed immediately, the buyer
will be able to outbid the current bidder and generally cause the bid system to be rigged.
Alleviation:
Although the statements were re-ordered to conform to the CEI pattern, the code still performs a regular refund at the end of execution. This allows a smart-contract based bidder to automatically re-bid in the auction. We assume the support of "smart" bidders is intended and as such consider this exhibit dealt with.
ARF-02M: Deprecated Native Asset Transfer
Type | Severity | Location |
---|---|---|
Language Specific | Minor | AuctionRunnerFacet.sol:L128 |
Description:
The transfer
member exposed by payable
address types has been deprecated as it does not reliably execute and can fail in future updates of the EVM as it forwards a fixed gas stipend which is not compatible with gas cost EIP upgrades such as EIP-2929.
Example:
128auction.buyer.transfer(auction.bid);
Recommendation:
We advise a safe wrapper library to be utilized instead such as the sendValue
function of the Address
library by OpenZeppelin which is guaranteed to execute under all circumstances.
Alleviation:
The codebase was updated to utilize an internal sendValueOrCreditAccount
function that attempts to send the native asset to the recipient address and in case the action fails for any reason, the user is given a redeemable credit of their native asset portion. This change has alleviated this exhibit in full.