SheepFarm Bonus Replay Drain
Exploit Transactions
0x5735026e5de6d1968ab5baef0cc436cc0a3f4de4ab735335c5b1bd31fa60c582Victim Addresses
0x4726010da871f4b57b5031e3ea48bde961f122aaBSCLoss Breakdown
Similar Incidents
BXH Bonus Oracle Manipulation
35%Transit Router V5 Drain
34%UEarnPool Reward Drain
33%Sheep Burn Reserve Drain
33%DBW Static-Income LP Drain
33%GGGTOKEN Treasury Drain via receive()
32%Root Cause Analysis
SheepFarm Bonus Replay Drain
1. Incident Overview TL;DR
SheepFarm on BNB Smart Chain was drained through a replayable signup-bonus path. In transaction 0x5735026e5de6d1968ab5baef0cc436cc0a3f4de4ab735335c5b1bd31fa60c582, the attacker repeatedly called register(address) from a fresh helper address before making any deposit, minted 8040 referral gems, activated once with the minimum 0.0005 BNB payment, built the profitable first-sheep route, sold the village, withdrew 156000 wool, and exited with net profit while SheepFarm lost 0.779525 BNB.
The root cause is that registration was treated as "timestamp is still zero" instead of being enforced as a one-time state transition. register(address) checks villages[user].timestamp == 0 but does not set timestamp or any dedicated registration flag, so the same fresh address can claim the referral bonus repeatedly until addGems() is called.
2. Key Background
SheepFarm tracks each player in a Village struct that includes per-farm sheep counts, gem balances, wool balances, and a timestamp field. Registration and activation are split across two functions:
register(address)sets the player's neighbor and grants gems.addGems()accepts BNB, mints gems, and is the first place wheretimestampbecomes non-zero.
That split matters because a valid public neighbor with at least one sheep turns the signup into a 20-gem reward path. At block 23088156, public address 0x14598f3a9f3042097486dc58c65780daf3e3acfb already had sheep in farm 0, so it was enough to satisfy the high-bonus branch. The first profitable build route was deterministic:
- Upgrade farms
0through4once each. - Gem cost:
(400 + 4000 + 12000 + 24000 + 40000) / 10 = 8040. - Yield after the route:
5 + 56 + 179 + 382 + 678 = 1300. sellVillage()converts that into1300 * 24 * 5 = 156000wool.
3. Vulnerability Analysis & Root Cause Summary
The vulnerability is a replayable reward-minting flaw in SheepFarm's registration logic. The intended invariant is that a village address may receive the referral signup bonus at most once before becoming active. The contract instead uses villages[user].timestamp == 0 as the only gate for "new user" status. Because register(address) does not set timestamp, the same helper contract remains eligible for bonus minting across repeated calls. addGems() later sets timestamp, but by then the attacker has already minted enough gems to build the profitable route. This is an application-layer logic bug, not a pricing issue, flash-loan dependency, or privileged-access condition.
Snippet from the verified SheepFarm contract on BscScan:
function register(address neighbor) external initialized {
address user = msg.sender;
require(villages[user].timestamp == 0, "just new users");
uint256 gems;
if (villages[neighbor].sheeps[0] > 0 && neighbor != manager) {
gems += GEM_BONUS * 2;
} else {
neighbor = manager;
gems += GEM_BONUS;
}
villages[user].neighbor = neighbor;
villages[user].gems += gems;
}
function addGems() external payable initialized {
uint256 gems = msg.value / 5e14;
address user = msg.sender;
require(villages[user].neighbor != address(0), "first register");
if (villages[user].timestamp == 0) {
villages[user].timestamp = block.timestamp;
}
...
}
4. Detailed Root Cause Analysis
The exploit starts from entirely public state. Before block 23088157, SheepFarm held enough BNB to pay the withdrawal path, and a public neighbor already satisfied the sheeps[0] > 0 referral condition. The attacker therefore only needed a fresh helper address whose timestamp was still zero.
From the seed transaction trace, the attacker-controlled orchestrator created helper contract 0xa448a215bbb54d4bd67f6fbb931874f019e7bd8a, and that helper executed the full exploit flow against SheepFarm. The decisive trace pattern is repeated successful register calls before the first addGems:
SheepFarm::register(0x14598f3a9f3042097486DC58C65780Daf3e3acFB)
emit Newbie(user: 0xA448a215bbB54d4bd67F6fbb931874F019e7Bd8a, bonus: 20)
...
SheepFarm::addGems{value: 500000000000000}()
emit BuyGem(user: 0xA448a215bbB54d4bd67F6fbb931874F019e7Bd8a, amount: 500000000000000, gem: 1, ...)
The trace contains exactly 402 Newbie events for that helper. At 20 gems each, those replays minted 8040 gems. The subsequent minimum addGems() deposit contributed 1 more gem, giving 8041 total, which is enough to fund the five-upgrade route with one gem left over.
Once activated, monetization was deterministic. The trace shows five VillageUpgraded events, one SellVillage, and one SellWool for 156000 wool:
emit VillageUpgraded(... farm: 0 ...)
emit VillageUpgraded(... farm: 1 ...)
emit VillageUpgraded(... farm: 2 ...)
emit VillageUpgraded(... farm: 3 ...)
emit VillageUpgraded(... farm: 4 ...)
emit SellVillage(user: 0xA448..., ...)
SheepFarm::withdrawMoney(156000)
emit SellWool(user: 0xA448..., wool: 156000, ...)
The helper then self-destructed and returned the proceeds to the attacker stack:
SELFDESTRUCT: contract: 0xa448a215bbb54d4bd67f6fbb931874f019e7bd8a,
refund target: 0xf2db8665d82e1a23895ed78b213d36d62eec6bbc,
value 764400000000000000
This demonstrates the exact code-level breakpoint: the signup reward was replayable until addGems() eventually wrote timestamp. A persistent one-time registration flag, or setting timestamp during the first successful register, would have prevented the exploit.
5. Adversary Flow Analysis
The adversary flow spans two on-chain transactions.
- In
0x18e5b61e4afae34fed93ec2aec7ea424489961ed983ac790d430fc7457301786, EOA0x2131c67ed7b6aa01b7aa308c71991ef5baedd049deployed attacker-controlled contract0xf2db8665d82e1a23895ed78b213d36d62eec6bbc. - In seed transaction
0x5735026e5de6d1968ab5baef0cc436cc0a3f4de4ab735335c5b1bd31fa60c582, that orchestrator created helper0xa448a215bbb54d4bd67f6fbb931874f019e7bd8a. - The helper called
register(publicNeighbor)402times while itstimestampremained zero. - The helper called
addGems()once with0.0005BNB, which both activated the village and added one gem. - The helper upgraded farms
0through4, sold the village, withdrew156000wool, and self-destructed. - The profit flowed back through the attacker contract to the originating EOA.
This sequence satisfies the ACT model. No private key compromise, privileged role, private off-chain artifact, or victim cooperation was required. The public ingredients were sufficient: verified SheepFarm code, public protocol balances, a valid public neighbor, and standard transaction submission.
6. Impact & Losses
SheepFarm lost 779525000000000000 wei (0.779525 BNB) in the seed transaction. The same balance-diff artifact shows the attacker EOA moved from 0.82676133 BNB to 1.46749691 BNB, a net increase of 0.64073558 BNB after gas, while fee recipients collected 0.015625 BNB from the withdrawal path.
The affected victim contract was:
- SheepFarm:
0x4726010da871f4b57b5031e3ea48bde961f122aaon BNB Smart Chain (chainid=56)
The loss is narrow in this incident transaction, but the bug class is repeatable whenever SheepFarm retains sufficient BNB and a valid public neighbor remains available.
7. References
- Seed transaction:
0x5735026e5de6d1968ab5baef0cc436cc0a3f4de4ab735335c5b1bd31fa60c582 - Related deployment transaction:
0x18e5b61e4afae34fed93ec2aec7ea424489961ed983ac790d430fc7457301786 - Victim contract:
0x4726010da871f4b57b5031e3ea48bde961f122aa - Public referral neighbor used in analysis:
0x14598f3a9f3042097486dc58c65780daf3e3acfb - Collector metadata:
/workspace/session/artifacts/collector/seed/56/0x5735026e5de6d1968ab5baef0cc436cc0a3f4de4ab735335c5b1bd31fa60c582/metadata.json - Collector trace:
/workspace/session/artifacts/collector/seed/56/0x5735026e5de6d1968ab5baef0cc436cc0a3f4de4ab735335c5b1bd31fa60c582/trace.cast.log - Collector balance diff:
/workspace/session/artifacts/collector/seed/56/0x5735026e5de6d1968ab5baef0cc436cc0a3f4de4ab735335c5b1bd31fa60c582/balance_diff.json - Verified SheepFarm source:
https://bscscan.com/address/0x4726010da871f4b57b5031e3ea48bde961f122aa#code