Reproduced Exploit

CryptoLegacy: Vesting mixes a live rebasing balance with a stored total, so a rebase makes equal shares pay unequally

Jan 1970Otheruntagged3 min read

Chain

Other

Category

untagged

Date

Jan 1970

Source

AuditVault

EVM Playground

Source-level debugger — step opcodes and Solidity in sync

evm-hack-analyzer

The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.

Loading fork state…

Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 61287-rebaseable-tokens-cause-unfair-vesting-and-claim-failures-mi. The historical source/toolchain is unavailable; this entry is documentation only and claims no executable Forge PoC.


Vulnerability classes: vuln/rebasing-token · vuln/accounting-drift · vuln/vesting

Reproduction: a faithful minimal reproduction of the vulnerable finding — the vulnerable function is reproduced verbatim (marked @>) with faithful minimal doubles; local deploy, no fork.

Root cause#

amountToDistribute = token.balanceOf(this) + totalClaimedAmount adds a LIVE rebasing balance to a STORED non-rebasing running total. When the token rebases between two beneficiaries' claims, the distribution base shifts, so beneficiaries holding EQUAL shares end with UNEQUAL totals (1,125 vs 875) — a 250-token unfair disparity.

SOLIDITY
        // total distributable = current live balance + everything already claimed.
        // On a rebasing token balanceOf() shifts while totalClaimedAmount does not,
        // so equal shares yield unequal payouts across claims.
        uint256 amountToDistribute = IRebaseToken(_token).balanceOf(address(this)) + totalClaimedAmount; // @>

Why it's exploitable here#

  • The distribution base moves with every rebase because it is derived from balanceOf.
  • totalClaimedAmount is a fixed running total, so the two terms are denominated inconsistently after a rebase.
  • Two beneficiaries with identical fixed shares end up with different payouts purely from claim timing around a rebase.

Attack path#

flowchart TD A["Two beneficiaries hold equal 50% shares"] --> B["Beneficiary A claims (pre-rebase base)"] B --> C["Token rebases (balanceOf changes)"] C --> D["amountToDistribute mixes live balance + stored total"] D --> E["Beneficiary B claims on the shifted base"] E --> F["Equal shares → 250-token payout disparity"]

Marked-line walkthrough (Playground)#

The EVM Playground pins each step to the exact executed source line in CryptoLegacyVesting:

  1. Line 112VULN. amountToDistribute adds the rebasing balanceOf(this) to the non-rebasing totalClaimedAmount — the base moves with each rebase.
  2. Line 114 — vestedAmount = amountToDistribute * shares / BASE * vesting / BASE uses the distorted base.
  3. Line 115 — claimAmount = vestedAmount - claimed; a rebase between two equal-share claims produces a 250-token disparity.

PoC#

Registry (Foundry, local deploy — exploit path + a fixed-variant control):

BASH
cd 61287-rebaseable-tokens-cause-unfair-vesting-and-claim-failures-_exp
forge test -vv

Expected: both tests PASS — the exploit test claims around a rebase and asserts a 250-token disparity between equal-share beneficiaries; the fixed accounting keeps them equal. The browser EVM Playground is served at /hacks/61287-rebaseable-tokens-cause-unfair-vesting-and-claim-failures-/.

Remediation#

Track the total distributed amount independently of the live token balance; do not derive amountToDistribute from balanceOf of a rebasing token.

References#


Sources & further analysis#

Reproductions & code

Alerts & third-party analyses

These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.