Skip to content

Instantly share code, notes, and snippets.

@korrio
Last active October 22, 2024 04:15
Show Gist options
  • Save korrio/ce77bfe5f3f188c5030fa3ee0c794b44 to your computer and use it in GitHub Desktop.
Save korrio/ce77bfe5f3f188c5030fa3ee0c794b44 to your computer and use it in GitHub Desktop.
SweepNSwap.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x < y ? x : y;
}
function sqrt(uint256 y) internal pure returns (uint256 z) {
if (y > 3) {
z = y;
uint256 x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
interface IERC20 {
function totalSupply() external view returns (uint);
function balanceOf(address account) external view returns (uint);
function transfer(address recipient, uint amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint amount) external returns (bool);
function transferFrom(address sender, address recipient, uint amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint value);
event Approval(address indexed owner, address indexed spender, uint value);
}
interface IUniswapV2Router {
function getAmountsOut(uint256 amountIn, address[] memory path) external view returns (uint256[] memory amounts);
function swapExactTokensForTokens(uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline) external returns (uint256[] memory amounts);
}
interface IUniswapV2Pair {
function token0() external view returns (address);
function token1() external view returns (address);
function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;
}
contract SweepNSwap is Ownable(msg.sender) {
using SafeMath for uint256;
address public constant UNISWAP_ROUTER = 0x10ED43C718714eb63d5aA57B78B54704E256024E;
address public constant USDT = 0x55d398326f99059fF775485246999027B3197955;
function swap(address router, address _tokenIn, address _tokenOut, uint256 _amount) private {
IERC20(_tokenIn).approve(router, _amount);
address[] memory path;
path = new address[](2);
path[0] = _tokenIn;
path[1] = _tokenOut;
uint deadline = block.timestamp + 300;
IUniswapV2Router(router).swapExactTokensForTokens(_amount, 1, path, address(this), deadline);
}
function swapAndReturn(address router, address _tokenIn, address _tokenOut, uint256 _amount, address receipent) private {
IERC20(_tokenIn).approve(router, _amount);
address[] memory path;
path = new address[](2);
path[0] = _tokenIn;
path[1] = _tokenOut;
uint deadline = block.timestamp + 300;
IUniswapV2Router(router).swapExactTokensForTokens(_amount, 1, path, address(this), deadline);
uint endBalance = IERC20(USDT).balanceOf(address(this));
IERC20(USDT).approve(address(this),endBalance);
IERC20(USDT).transferFrom(address(this),receipent,endBalance);
}
// Function in your frontend/script to be called before sweepTokens
function approveTokens(address[] calldata tokens) external {
for (uint i = 0; i < tokens.length; i++) {
address token = tokens[i];
uint256 balance = IERC20(token).balanceOf(msg.sender);
if (balance > 0) {
IERC20(token).approve(address(this), balance);
}
}
}
// Your contract function
function sweepTokensAndSwap(address[] calldata tokens, address recipient) external {
for (uint i = 0; i < tokens.length; i++) {
address token = tokens[i];
uint256 balance = IERC20(token).balanceOf(msg.sender);
require(balance > 0, "No tokens to sweep woi");
// Remove this line as approve needs to be called by msg.sender
// IERC20(token).approve(address(this), balance);
// Check allowance first
uint256 allowance = IERC20(token).allowance(msg.sender, address(this));
require(allowance >= balance, "Insufficient allowance woi");
// Transfer tokens from the caller to this contract
bool success = IERC20(token).transferFrom(msg.sender, address(this), balance);
require(success, "Transfer failed woi");
// Swap tokens to USDT and return to recipient address
swapAndReturn(UNISWAP_ROUTER, token, USDT, balance, recipient);
}
}
function getBalance (address _tokenContractAddress) external view returns (uint256) {
uint balance = IERC20(_tokenContractAddress).balanceOf(address(this));
return balance;
}
function recoverEth() external onlyOwner {
payable(msg.sender).transfer(address(this).balance);
}
function recoverTokens(address tokenAddress) external onlyOwner {
IERC20 token = IERC20(tokenAddress);
token.transfer(msg.sender, token.balanceOf(address(this)));
}
receive() external payable {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment