This serves as a walkthrough for your research process when auditing contracts that implement the sERC20 Contract.
You should verify that that included sERC20 library has not been tampered with. The latest version is available on our GitHub for you to reference.
sERC20 should be the sole controller of both the pair and router within a contract. Check that references to these are always using the sERC20 helpers methods.
+if (to != _sercPair() && to != address(_sercRouter())) { 2 usedBot = true;3}
-if (to != someLocalPairAddressVariable && to != address(someLocalRouterAddressVariable)) { 2 usedBot = true;3}
sERC20 should be the sole controller of setting and reading tax values within a contract. Check that references to taxes are reading from the sERC20 helper methods and any methods that change the tax rates forward on to the _sercSetTaxes() method.
1function setBuyTax(uint256 buyDevTax, uint256 buyLiqTax) 2 external 3 onlyOwner 4{ 5 uint256[] memory buyTaxes = new uint256[](2); 6 buyTaxes[0] = buyDevTax; 7 buyTaxes[1] = buyLiqTax; 8 + _sercSetTaxes(buyTaxes, true); 10}11 +uint256[] memory sellTaxes = _sercSellTax(); +uint256 sellTotalFees = _sercSellTotalTax(); 14 +uint256[] memory buyTaxes = _sercBuyTax(); +uint256 buyTotalFees = _sercBuyTotalTax();
1function setBuyTax(uint256 buyDevTax, uint256 buyLiqTax) 2 external 3 onlyOwner 4{ 5 uint256[] memory buyTaxes = new uint256[](2); 6 buyTaxes[0] = buyDevTax; 7 buyTaxes[1] = buyLiqTax; 8 - buyTax = buyTaxes; 10}11 -uint256[] memory sellTaxes = sellTaxes; -uint256 sellTotalFees = totalSellTax; 14 -uint256[] memory buyTaxes = buyTaxes; -uint256 buyTotalFees = totalSellTax;
sERC20 should be the sole controller of setting and reading transaction limit values within a contract. Check that references to taxes are reading from the sERC20 helper methods and any methods that changes the transaction limits use the built-in sercSetMaxTx() and sercSetMaxWallet() methods.
+require(amount <= _sercMaxTx(), "Max transaction exceeded."); +require( + amount + balanceOf(to) <= _sercMaxWallet(), + "Max wallet exceeded" +);
-require(amount <= maxTx, "Max transaction exceeded."); -require( - amount + balanceOf(to) <= maxWallet, - "Max wallet exceeded" -);
sERC20 should be the sole controller of blacklisting address's within a contract. Check that references to the blacklist are reading from the sERC20 helper methods and any methods that changes the blacklist use the built-in sercSetBlacklisted() or _sercSetBlacklisted() methods.
1if (usedBot) {+ _sercSetBlacklisted(addressList, true); 3}
1if (usedBot) {+ blacklisted[address] = true 3}
sERC20 should be the sole controller of the trading status within a contract. Check that references to the trading status are reading from the sERC20 helper methods and any methods that changes the trading status use the built-in sercSetTradingEnabled() methods
1function sercSetTradingEnabled() public virtual override onlyOwner { + super.sercSetTradingEnabled(); 3 lastLpBurnTime = block.timestamp; 4 launchBlock = block.number; 5} 6 +if (!_sercTradingEnabled()) { 8 require( 9 _isExcludedFromFees[from] || _isExcludedFromFees[to],10 "Trading is not active."11 );12}
1function sercSetTradingEnabled() public virtual override onlyOwner { - tradingEnabled = true 3 lastLpBurnTime = block.timestamp; 4 launchBlock = block.number; 5} 6 -if (!tradingEnabled) { 8 require( 9 _isExcludedFromFees[from] || _isExcludedFromFees[to],10 "Trading is not active."11 );12}