Reproduced Exploit

TRZN — RM_UpdateReward has no access control

RM_UpdateReward is named for the risk manager. The stored risk manager is 0xbeef. The function does not read msg.sender. A caller sets reward to 1000, the vault's entire balance, and claim transfers it. The same call on a function that requires the risk manager reverts, and the 1000 tokens stay. ru…

Jan 2024•Other•access-control•3 min read

Chain

Other

Category

access-control

Date

Jan 2024

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: 37230-function-rm-updatereward-in-vaulteth-v2-has-no-access-contro. Standalone Foundry PoC and full write-up: 37230-function-rm-updatereward-in-vaulteth-v2-has-no-access-contro_exp in the evm-hack-registry mirror.


Vulnerability classes: vuln/access-control/missing-modifier · vuln/access-control/missing-auth

Reproduction: a self-contained Foundry PoC that compiles and runs offline with only forge-std — no fork and no RPC. Trace: output.txt. PoC: test/37230-function-rm-updatereward-in-vaulteth-v2-has-no-access-contro_exp.sol.


Key info#

ImpactHIGH — any caller sets the claimable reward to 1000 and takes the vault's reward tokens
ProtocolTRZN VaultETH_V2.RM_UpdateReward
Vulnerable codereward = newReward with no caller check
Bug classMissing risk-manager authorization
FindingZokyo — TRZN Finance · id 37230
ReportZokyo TRZN Finance, 12 Jan 2024
SourceAuditVault finding
StatusThe report says the issue was resolved. Reproduced as a local synthetic.
Compilersolc 0.8.27, cancun, via IR

TL;DR#

RM_UpdateReward is named for the risk manager. The stored risk manager is 0xbeef. The function does not read msg.sender. A caller sets reward to 1000, the vault's entire balance, and claim transfers it. The same call on a function that requires the risk manager reverts, and the 1000 tokens stay. run() does not warp.

The vulnerable code#

SOLIDITY
function RM_UpdateReward(uint256 newReward) external {
    // @> VULN: RM_UpdateReward has no risk-manager check
    reward = newReward;
}

Root cause#

The report says any user can call a function that is supposed to be limited to risk managers. The reward value is what claim pays out of the vault.

Preconditions#

  • The vault holds 1000 reward tokens funded for stakers.
  • The caller is not the risk manager.

Attack walkthrough#

  1. RM_UpdateReward(1000 ether) writes reward.
  2. claim copies reward, zeroes it, and transfers 1000 tokens to the caller.
  3. The vault balance is 0.

Diagrams#

flowchart TD A["Caller is not the risk manager"] --> B["RM_UpdateReward writes 1000"] B --> C["claim reads that reward"] C --> D["1000 tokens transfer to the caller"] D --> E["Vault balance is 0"]

Impact#

Stakers lose the 1000 reward tokens. The caller did not stake and is not the risk manager.

Remediation#

Require msg.sender to be the risk manager before writing reward.

How to reproduce#

BASH
cd evm-hack-registry/37230-function-rm-updatereward-in-vaulteth-v2-has-no-access-contro_exp
forge test -vv

Sources#

  • AuditVault finding 37230
  • Zokyo, TRZN Finance, 12 January 2024, VaultETH_V2.RM_UpdateReward

Sources & further analysis#

Reproductions & code

Alerts & third-party analyses

  • Web3Sec X hacked database: search.
  • Rekt leaderboard: search.
  • Solodit incident search: search.

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.