Skip to content

Instantly share code, notes, and snippets.

@saadSarwar28
Created September 4, 2021 15:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saadSarwar28/ceee1069fab79e0c439b257ede938f2e to your computer and use it in GitHub Desktop.
Save saadSarwar28/ceee1069fab79e0c439b257ede938f2e to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.4+commit.c7e474f2.js&optimize=true&runs=200&gist=
pragma solidity >=0.7.0 <0.9.0;
import "./access/Ownable.sol";
import "./token/BEP20/IBEP20.sol";
// SPDX-License-Identifier: MIT
/**
* @title RugSwap
* @author Saad Sarwar
*/
interface ZombieOnChainPrice {
function usdToZmbe(uint amount) external view returns(uint);
}
contract RugSwap is Ownable{
uint256 public totalUnlockedContracts = 0; // total unlocked contracts, also helpful for id in UnlockedContractsInfo (id = totalUnlockedContracts + 1)
address public burnAddress = 0x000000000000000000000000000000000000dEaD; // Burn address
address public treasury; // treasury address
address public zombieTokenContractAddress;
address public priceContract;
uint256 public totalWhitelisted = 0;
constructor (address _zombieTokenContractAddress, address _treasury, address _priceContract) {
priceContract = _priceContract;
treasury = _treasury;
zombieTokenContractAddress = _zombieTokenContractAddress;
}
address[] public whiteList;
function addToWhitelist (address ruggedContractAddress) public onlyOwner returns(bool) {
// so an address doesn't get whitelisted twice or more.
require(!isWhiteListed(ruggedContractAddress), "The token is already white listed.");
whiteList.push(ruggedContractAddress);
totalWhitelisted = totalWhitelisted + 1;
return true;
}
// removes a given address from the whiteList without any holes because a new array is created and assigned to the whiteList.
function removeFromWhitelist (address contractAddress) public onlyOwner returns(bool) {
require(isWhiteListed(contractAddress), "The token is not white listed.");
address[] memory newWhitelist = new address[](whiteList.length - 1);
bool deleted = false;
for (uint256 index = 0; index < whiteList.length; index++) {
if (deleted) {
newWhitelist[index - 1] = whiteList[index];
} else {
if (whiteList[index] != contractAddress) {
newWhitelist[index] = whiteList[index];
} else {
deleted = true;
}
}
}
whiteList = newWhitelist;
totalWhitelisted = totalWhitelisted - 1;
return true;
}
function isWhiteListed(address contractAddress) public view returns(bool) {
for (uint256 index = 0; index < whiteList.length; index++) {
if (whiteList[index] == contractAddress) {
return true;
}
}
return false;
}
function burn(uint256 amount) internal {
IBEP20(zombieTokenContractAddress).transferFrom(msg.sender, burnAddress, amount);
}
function toTreasury(uint256 amount) internal {
IBEP20(zombieTokenContractAddress).transferFrom(msg.sender, treasury, amount);
}
// returns address just for the event to show the rugged token
function ruggedTokenSwap(address _ruggedTokenAddress) private returns(bool){
// transferring a rugged token from user wallet to this contractAddress, needs approval first.
IBEP20(_ruggedTokenAddress).transferFrom(msg.sender, address(this), 10**IBEP20(_ruggedTokenAddress).decimals());
// generating a random rugged token except the token which user provided.
address[] memory newWhitelist = new address[](whiteList.length - 1);
bool sameTokenFound = false;
for (uint256 index = 0; index < whiteList.length; index++) {
if (sameTokenFound) {
newWhitelist[index - 1] = whiteList[index];
} else {
if (whiteList[index] != _ruggedTokenAddress) {
newWhitelist[index] = whiteList[index];
} else {
sameTokenFound = true;
}
}
}
address randomTokenAddress;
// handling an edge case, if whiteList has only two addresses then one of them will be omitted in above loop so returning the remaining one.
if (newWhitelist.length < 2) {
randomTokenAddress = newWhitelist[0];
} else {
randomTokenAddress = newWhitelist[getRandomNum(newWhitelist.length)];
}
// transferring the random rugged token to the user. hopefully he finds it in his wallet ;).
IBEP20(randomTokenAddress).transfer(msg.sender, 10**IBEP20(randomTokenAddress).decimals());
return true;
}
// function to withdraw tokens in case of v2.
function withdrawTokens(address ruggedTokenAddress, uint256 _amount) public payable onlyOwner returns(bool result) {
IBEP20(ruggedTokenAddress).transfer(msg.sender, _amount * 10**IBEP20(ruggedTokenAddress).decimals());
return true;
}
// returns the amount of zombie tokens required for one BUSD
function getAmount() public view returns(uint) {
return ZombieOnChainPrice(priceContract).usdToZmbe(10**IBEP20(zombieTokenContractAddress).decimals());
}
function rugSwap(address ruggedTokenAddress) public payable returns(bool result) {
uint256 zombieAmount = getAmount();
require(whiteList.length > 1, "Please add more tokens to whitelist.");
require(isWhiteListed(ruggedTokenAddress), "Only whitelisted tokens are allowed.");
require(IBEP20(zombieTokenContractAddress).balanceOf(msg.sender) >= zombieAmount, "Not enough balance.");
require(IBEP20(ruggedTokenAddress).balanceOf(msg.sender) >= 10**IBEP20(ruggedTokenAddress).decimals(), "Rugged token balance not enough.");
// burning half the amount of zombie tokens
burn(zombieAmount / 2);
// tranferring the other half to treasury
toTreasury(zombieAmount / 2);
ruggedTokenSwap(ruggedTokenAddress);
totalUnlockedContracts = totalUnlockedContracts + 1;
emit Swapped(msg.sender, zombieAmount, ruggedTokenAddress);
return true;
}
uint nonce = 0;
// generates a pseudo random number just to return a rugged token which doesn't have any value, totally predictable so not suitable for selecting any serious random number.
function getRandomNum(uint256 length) internal returns(uint256) {
nonce = nonce + 1;
return uint(keccak256(abi.encodePacked(block.timestamp, block.difficulty, nonce))) % (length - 1);
}
// to check balance of the rugged tokens
function balanceOf(address _ruggedTokenAddress) public view returns(uint) {
return IBEP20(_ruggedTokenAddress).balanceOf(address(this)) / 10**IBEP20(_ruggedTokenAddress).decimals();
}
event Swapped(address indexed _from, uint _zombieAmount, address _ruggedTokenAddress);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment