Created
October 21, 2022 00:21
-
-
Save ergatea/4c27bbb55fe6730059dc40e9ab20409c 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.17+commit.8df45f5f.js&optimize=false&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
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.7; | |
interface IXEN { | |
function claimRank(uint term) external; | |
function claimMintReward() external; | |
function claimMintRewardAndShare(address other, uint256 pct) external; | |
function transfer(address recipient, uint256 amount) external returns (bool); | |
function balanceOf(address account) external view returns (uint256); | |
} | |
interface IMiniProxyV4{ | |
function claimRank(uint term) external; | |
function claimMintRewardAndShare() external; | |
} | |
contract MiniProxyV4 is IMiniProxyV4{ | |
address private original; | |
address private claim = 0x66042381FE037f32557eb68Ecbaab9B5f394f5cc; | |
address public constant xenContract = 0xca41f293A32d25c2216bC4B30f5b0Ab61b6ed2CB; //0x06450dEe7FD2Fb8E39061434BAbCFC05599a6Fb8; | |
constructor() { | |
original = msg.sender; | |
} | |
function claimRank(uint term) external { | |
IXEN(xenContract).claimRank(term); | |
} | |
function claimMintRewardAndShare() external { | |
IXEN(xenContract).claimMintRewardAndShare(claim, 100); | |
if(address(this) != original) // proxy delegatecall | |
selfdestruct(payable(tx.origin)); | |
} | |
} | |
contract AttackV4 { | |
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1167.md | |
bytes miniProxy; // = 0x363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3; | |
address private immutable deployer; | |
mapping (address=>uint) public countClaimRank; | |
mapping (address=>uint) public countClaimMint; | |
constructor(address _miniProxy) { | |
miniProxy = bytes.concat(bytes20(0x3D602d80600A3D3981F3363d3d373d3D3D363d73), bytes20(address(_miniProxy)), bytes15(0x5af43d82803e903d91602b57fd5bf3)); | |
deployer = msg.sender; | |
} | |
function proxyFor(address sender, uint i) public view returns (address proxy) { | |
bytes32 salt = keccak256(abi.encodePacked(sender, i)); | |
proxy = address(uint160(uint(keccak256(abi.encodePacked( | |
hex'ff', | |
address(this), | |
salt, | |
keccak256(abi.encodePacked(miniProxy)) | |
))))); | |
} | |
function batchClaimRank(uint times, uint term) external { | |
bytes memory bytecode = miniProxy; | |
address proxy; | |
uint N = countClaimRank[msg.sender]; | |
for(uint i=N; i<N+times; i++) { | |
bytes32 salt = keccak256(abi.encodePacked(msg.sender, i)); | |
assembly { | |
proxy := create2(0, add(bytecode, 32), mload(bytecode), salt) | |
} | |
IMiniProxyV4(proxy).claimRank(term); | |
} | |
countClaimRank[msg.sender] = N+times; | |
} | |
function batchClaimMintReward(uint times) external { | |
uint M = countClaimMint[msg.sender]; | |
uint N = countClaimRank[msg.sender]; | |
N = M+times < N ? M+times : N; | |
for(uint i=M; i<N; i++) { | |
address proxy = proxyFor(msg.sender, i); | |
IMiniProxyV4(proxy).claimMintRewardAndShare(); | |
} | |
countClaimMint[msg.sender] = N; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment