August 2018 FoMo3D airdrop bot: spawns a throwaway contract that buys and withdraws in a loop, stopping when its own model of the airdrop pot falls below 1.3 ether, and refusing any request for more than five rounds.
Historical Significance
FoMo3D's airdrop lottery drew on a hash that included the buyer's address, so a contract calling repeatedly in one transaction gets a fresh draw each time. Bots that exploited this came in generations, and the distinguishing feature of this one is that it does its accounting offchain.
Reading airDropPot_ costs gas on every iteration. Modelling it instead, from a single number supplied at call time, costs nothing and is close enough over a handful of rounds. The result is a bot with no view of the thing it is attacking, running a fixed number of attempts against an estimate that was already stale when the transaction was signed. It is a small, honest illustration of what the economics looked like from the attacker's side: gas was the binding constraint, and accuracy was worth less than the gas it cost.
Key Facts
Description
Two contracts in one artifact. The deployed code is a factory with a single function, execute, taking a game address, a pot size, a round budget and an affiliate id. It creates a second contract with the ether the call carried, and that second contract's creation code is embedded in the factory's own bytecode.
The child never becomes a live contract. Its whole behaviour is a loop in the constructor. Each round it calls the game twice by raw selector: 0x8f38f309, which is buyXid, with the affiliate id and team zero and the call's ether attached, then 0x3ccfd60b, which is withdraw. Neither return value is checked. It then updates its own idea of the pot, subtracting a tenth, increments a counter, and stops when the counter passes five or the modelled pot drops below 1.3 ether. It also refuses outright, before touching the pot, if the caller asked for more than five rounds: the budget is capped in the contract rather than clamped. Whatever is left goes to tx.origin through selfdestruct.
The pot is a number the caller passes in, not a number read from the chain. The contract never asks the game how large the airdrop pot actually is; it assumes each round takes ten percent and stops when its own arithmetic says the prize is no longer worth the gas. That makes the round budget the real control and the threshold a safety catch.
Source Verified
Byzantium Era
First Metropolis hard fork. Added zk-SNARK precompiles, REVERT opcode, and staticcall.
Bytecode Overview
Verified Source Available
This contract has verified source code.
View Verification ProofShow source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
pragma solidity ^0.4.24;
contract PotDrainerRound {
constructor(address _game, uint256 _pot, uint256 _rounds, uint256 _affCode) public payable {
uint256 i = 1;
while (_pot > 1.3 ether) {
_game.call.value(msg.value)(bytes4(0x8f38f309), _affCode, uint256(0));
_game.call(bytes4(0x3ccfd60b));
if (_rounds > 5) break;
_pot = _pot - _pot / 10;
i++;
if (i > 5) break;
}
selfdestruct(tx.origin);
}
}
contract Fomo3dPotDrainer {
function execute(address _game, uint256 _pot, uint256 _rounds, uint256 _affCode) public payable {
(new PotDrainerRound).value(msg.value)(_game, _pot, _rounds, _affCode);
}
}External Links
Related contracts
Fomo3dPotDrainer
Same deployerAugust 2018 FoMo3D airdrop bot: spawns a throwaway contract that buys and withdraws in a loop, stopping when its own model of the airdrop pot falls below 1.3 ether, and refusing any request for more than five rounds.
0xf6c937...9edc80August 10, 2018Fomo3dPotDrainer
Same deployerAugust 2018 FoMo3D airdrop bot: spawns a throwaway contract that buys and withdraws in a loop, stopping when its own model of the airdrop pot falls below 1.3 ether, and refusing any request for more than five rounds.
0x61fe00...72a8d8August 10, 2018Fomo3dPotDrainer
Same deployerAugust 2018 FoMo3D airdrop bot: spawns a throwaway contract that buys and withdraws in a loop, stopping when its own model of the airdrop pot falls below 1.3 ether, and refusing any request for more than five rounds.
0x4d26cd...21c0d6August 10, 2018Fomo3dPotDrainer
Same deployerAugust 2018 FoMo3D airdrop bot: spawns a throwaway contract that buys and withdraws in a loop, stopping when its own model of the airdrop pot falls below 1.3 ether, and refusing any request for more than five rounds.
0x4515bc...75f2b0August 10, 2018Fomo3dPotDrainer
Same deployerAugust 2018 FoMo3D airdrop bot: spawns a throwaway contract that buys and withdraws in a loop, stopping when its own model of the airdrop pot falls below 1.3 ether, and refusing any request for more than five rounds.
0xf2504c...d8f8c1August 10, 2018Fomo3dPotDrainer
Same deployerAugust 2018 FoMo3D airdrop bot: spawns a throwaway contract that buys and withdraws in a loop, stopping when its own model of the airdrop pot falls below 1.3 ether, and refusing any request for more than five rounds.
0x18dc37...b5f0eaAugust 10, 2018