Created
September 2, 2021 21:35
-
-
Save saadSarwar28/f77b2861960fd2322fd733624043fef2 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=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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){ | |
// 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