The auction logic in Shortfall.sol refunds the previously accepted (highest) bid when a new acceptable bid is placed via the placeBid function.
It is important that this refund succeeds as otherwise a new acceptable (higher) bid is not possible and the auction is disrupted which consequently makes the current highest bidder the auction winner and causes a loss for the Venus project and its users.
When refunding the safeTransfer of OpenZeppelin SafeERC20Upgradeable (inheriting from SafeERC20) is used which deals with the multiple ways in which different ERC-20 (BEP-20) tokens indicate the success/failure of a token transfer.
Nevertheless, there are additional scenarios that may still disrupt the auction and put it into a state of DOS (Denial of Service). Specifically, 2 scenarios were identified:
DOS with the underlying token implementing a blacklist
DOS with the underlying token being an ERC20-compatible ERC777 token
Proof of Concept
1. DOS with the underlying token implementing a blacklist
In this scenario, the underlying token is implemented with a blacklist (also known as blocklist).
Because this is common for tokens on the Ethereum network (e.g. USDC/USDT implementing blacklist/blocklist; See: https://github.com/d-xo/weird-erc20) this is a scenario also possible for tokens on the Binance Chain.
And since it is not specifically stated that such tokens are excluded from the Venus project, while fee on transfer/deflationary/rebase tokens are specifically mentioned to be excluded, this is assumed to be a potential issue.
The following steps describe the issue:
Bidder 1 makes a bid while he is not on the token blacklist
After the bid he is put on the token blacklist
Bidder 2 makes a higher bid and the refund to bidder 1 is attempted
The refund reverts due to bidder 1 being blacklisted which blocks the token transfer back
Bidder 1 remains the highest bidder and wins the auction
2. DOS with the underlying token being an ERC20-compatible ERC777 token
In this scenario, the underlying token is an ER777 token instead of an ERC20. Since contest does not state specifically state that ERC777 tokens (which are ERC-20 compatible!) are out of scope, this is assumed to be a potential issue.
Bidder 1 implements a contract that acts as an "ERC777 recipient" which can either accept/reject tokens that are transferred to it
Bidder 1 makes a bid not with an EOA (externally owned account) but uses his smart contract make the bid
After the bid was accepted he activates that his smart contract rejects any tokens transferred to it
Bidder 2 makes a higher bid and the refund to the smart contract of bidder 1 is attempted
The refund fails due to the smart contract of bidder 1 rejecting the token transfer (ERC777 token calls tokensReceived function of receiving smart contract to finalize the token transfer which reverts)
Bidder 1 remains the highest bidder and wins the auction
Coded POC
To prove both aforementioned scenarios of putting the auction into a state of DOS, the Shortfall.ts test was modified and 1 test case for each scenario was added. Code for additional required mock tokens etc. (MockTokenERC20Blacklistable.sol, MockTokenERC777.sol, ERC777Recipient.sol) are included below as well.
Lines of code
https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L183 https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Shortfall/Shortfall.sol#L190
Vulnerability details
Impact
The auction logic in
Shortfall.sol
refunds the previously accepted (highest) bid when a new acceptable bid is placed via theplaceBid
function.It is important that this refund succeeds as otherwise a new acceptable (higher) bid is not possible and the auction is disrupted which consequently makes the current highest bidder the auction winner and causes a loss for the Venus project and its users.
When refunding the
safeTransfer
of OpenZeppelinSafeERC20Upgradeable
(inheriting from SafeERC20) is used which deals with the multiple ways in which different ERC-20 (BEP-20) tokens indicate the success/failure of a token transfer.For details see: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol#L12
Nevertheless, there are additional scenarios that may still disrupt the auction and put it into a state of DOS (Denial of Service). Specifically, 2 scenarios were identified:
Proof of Concept
1. DOS with the underlying token implementing a blacklist
In this scenario, the underlying token is implemented with a blacklist (also known as blocklist).
Because this is common for tokens on the Ethereum network (e.g. USDC/USDT implementing blacklist/blocklist; See: https://github.com/d-xo/weird-erc20) this is a scenario also possible for tokens on the Binance Chain.
And since it is not specifically stated that such tokens are excluded from the Venus project, while fee on transfer/deflationary/rebase tokens are specifically mentioned to be excluded, this is assumed to be a potential issue.
The following steps describe the issue:
2. DOS with the underlying token being an ERC20-compatible ERC777 token
In this scenario, the underlying token is an ER777 token instead of an ERC20. Since contest does not state specifically state that ERC777 tokens (which are ERC-20 compatible!) are out of scope, this is assumed to be a potential issue.
See https://docs.openzeppelin.com/contracts/2.x/api/token/erc777 for details on ERC777 tokens.
The following steps describe the issue:
tokensReceived
function of receiving smart contract to finalize the token transfer which reverts)Coded POC
To prove both aforementioned scenarios of putting the auction into a state of DOS, the
Shortfall.ts
test was modified and 1 test case for each scenario was added. Code for additional required mock tokens etc. (MockTokenERC20Blacklistable.sol
,MockTokenERC777.sol
,ERC777Recipient.sol
) are included below as well.