Original.finance Rug Pull

Reported loss Not disclosed
BNB Chain
Rugpull

What happened

Original.finance is a BNB Smart Chain farm whose MasterChef pays out PhotonToken (Photon) and tracks a referral tree. De.Fi's REKT database lists it as an Exit Scam/Rugpull dated 2021-08-26. The code has two separate freeze switches, each guarded by its own moderator variable: MasterChef.moderator controls updatePaused, which makes every deposit, withdraw and emergencyWithdraw revert, and PhotonToken.moderator controls statusTransfer, which makes every Photon _transfer revert.

The two variables are set by separate constructors, and the source does not show whether one address holds both roles. The MasterChef owner can also set a pool deposit fee up to 100%. The source shows what these keys allow; no transaction showing any of them being used was opened.

How it happened

What the code allows (no transaction showing these calls was opened):

  1. MasterChef starts locked: bool public paused = true; and deposit, withdraw and emergencyWithdraw each start with require(paused == false, "!paused");. Only the MasterChef moderator (the address passed as _moderator to the MasterChef constructor) can change it: updatePaused runs require(moderator == msg.sender); and then paused = _value;.
  2. Once users have staked LP tokens, the MasterChef moderator can call updatePaused(true) again. Every withdraw and emergencyWithdraw then reverts, so the LP tokens recorded in user.amount cannot be pulled out through this contract until that moderator unpauses.
  3. Separately, PhotonToken has its own address public moderator;, set from the _mod argument of the PhotonToken constructor. It overrides _transfer with require(!_pausedTokens, "!paused");, and statusTransfer(bool _value) sets _pausedTokens after require(moderator == msg.sender);. While _pausedTokens is true, every transfer and transferFrom of Photon reverts, including transfers to or from an exchange pair, so held Photon can be neither moved nor sold. Minting is unaffected because mint calls the internal _mint, which does not call _transfer.
  4. Each moderator can hand its role to another address with its own changeMod function, and the source does not show which addresses hold the two roles or whether they are the same.
  5. The deposit fee is a further lever: set and add accept _depositFeeBP <= 10000, so an owner (or setup address) can set 100%. deposit then sends depositFee to feeAddress and credits user.amount = user.amount.add(_amount).sub(depositFee), which is zero for a 100% fee.
  6. addSetup has no access check beyond require(setup == address(0)), so while no setup address is recorded any caller can set it, and onlyOwnerAndSetup then lets that address call add, set and updateEmissionRate.

on 2021-08-26 is not established by the source; De.Fi's REKT database lists the project as an Exit Scam/Rugpull.

Protocol details

Classification Token
Protocol Type Exit Scam/Rugpull
Affected asset / contract Original.finance
Protocol links Website

Build your security review skills

Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.