Qubicle Honeypot
What happened
Qubicle (QBE) has no global pause or transfer switch. Its trap is a per-holder time lock: transfer and transferFrom revert while locked[sender] < now is false, and lock(address addr, uint periodInDays) can be called by the saleAgent for any address. The saleAgent is set by setSaleAgent, which the owner (or the current agent) can call, and the lock length has no upper bound in the code.
A locked holder cannot move or sell QBE until the lock expires, and the contract has no unlock function. De.Fi's REKT database lists QBE as an exit scam/honeypot, stating that the owner could disable the transfer function.
How it happened
QBETokenoverrides transfers with a lock check:require(locked[msg.sender] < now);intransferandrequire(locked[_from] < now);intransferFrom, so a locked address cannot send tokens directly or have them pulled by a router.locksets the lock:require(locked[addr] < now && (msg.sender == saleAgent || msg.sender == addr)); locked[addr] = now + periodInDays * 1 days;. ThesaleAgentcan therefore lock any address that is not already locked, for any number of days it chooses.- The
saleAgentis assigned bysetSaleAgent:require(msg.sender == saleAgent || msg.sender == owner); saleAgent = newSaleAgnet;. The owner can point it at any address, including one it controls. - Nothing in the contract clears
locked[addr]before it expires, so a holder locked this way is stuck for the whole period; a holder locked for a very long period cannot sell at all. - The code shows this capability only. It does not show which address is the current
saleAgentor that any holder was locked; no transaction was opened.
Protocol details
Evidence
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.