You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Some major tokens went live before ERC20 was finalised, resulting in a discrepancy whether the transfer functions a) should return a boolean or b) revert/fail on error. The current best practice is that they should revert, but return “true” on success. However, not every token claiming ERC20-compatibility is doing this — some only return true/false; some revert, but do not return anything on success. This is a well known issue, heavily discussed since mid-2018.
RealityCards is not using such a wrapper, but instead tries to ensure successful transfers via the balancedBooks modifier:
modifier balancedBooks {
_;
// using >= not == in case anyone sends tokens direct to contract
require(
erc20.balanceOf(address(this)) >=
totalDeposits + marketBalance + totalMarketPots,
"Books are unbalanced!"
);
}
This modifier is present on most functions, but is missing on topupMarketBalance:
In the case an ERC20 token which is not reverting on failures is used, a malicious actor could call topupMarketBalance with a failing transfer, but also move the value of marketBalance above the actual holdings. After this, deposit, withdrawDeposit, payRent, payout, sponsor, etc. could be locked up and always failing with “Books are unbalanced”.
Proof of Concept
Anyone can call topupMarketBalance with some unrealistically large number, so that marketBalance does not overflow, but is above the actually helping balances. This is only possible if the underlying ERC20 used is not reverting on failures, but return “false” instead.
Tools Used
Manual review
Recommended Mitigation Steps
Use something like OpenZeppelin’s SafeERC20
Set up an allow list for tokens, which are knowingly safe
Consider a different approach to the balancedBooks modifier
The text was updated successfully, but these errors were encountered:
The particular ERC20 contracts we are using don't have this issue. However for futureproofing in the event we change ERC20 tokens we will implement the recommended mitigation 1 and start using OpenZeppelin’s SafeERC20.
Handle
axic
Vulnerability details
Impact
Some major tokens went live before ERC20 was finalised, resulting in a discrepancy whether the transfer functions a) should return a boolean or b) revert/fail on error. The current best practice is that they should revert, but return “true” on success. However, not every token claiming ERC20-compatibility is doing this — some only return true/false; some revert, but do not return anything on success. This is a well known issue, heavily discussed since mid-2018.
Today many tools, including OpenZeppelin, offer a wrapper for “safe ERC20 transfer”: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol
RealityCards is not using such a wrapper, but instead tries to ensure successful transfers via the
balancedBooks
modifier:This modifier is present on most functions, but is missing on
topupMarketBalance
:In the case an ERC20 token which is not reverting on failures is used, a malicious actor could call
topupMarketBalance
with a failing transfer, but also move the value ofmarketBalance
above the actual holdings. After this,deposit
,withdrawDeposit
,payRent
,payout
,sponsor
, etc. could be locked up and always failing with “Books are unbalanced”.Proof of Concept
Anyone can call
topupMarketBalance
with some unrealistically large number, so thatmarketBalance
does not overflow, but is above the actually helping balances. This is only possible if the underlying ERC20 used is not reverting on failures, but return “false” instead.Tools Used
Manual review
Recommended Mitigation Steps
balancedBooks
modifierThe text was updated successfully, but these errors were encountered: