Platform: Code4rena
Start Date: 19/01/2024
Pot Size: $36,500 USDC
Total HM: 9
Participants: 113
Period: 3 days
Judge: 0xsomeone
Id: 322
League: ETH
Rank: 85/113
Findings: 1
Award: $0.12
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: NPCsCorp
Also found by: 0x11singh99, 0xAadi, 0xBugSlayer, 0xE1, 0xPluto, 0xSimeon, 0xSmartContract, 0xabhay, 0xdice91, 0xprinc, Aamir, Aymen0909, CDSecurity, DadeKuma, DarkTower, EV_om, Eeyore, GeekyLumberjack, GhK3Ndf, Giorgio, Greed, Inference, JanuaryPersimmon2024, Kaysoft, Krace, Matue, MrPotatoMagic, NentoR, Nikki, PUSH0, Soliditors, Tendency, Tigerfrake, Timeless, Timenov, ZanyBonzy, ZdravkoHr, abiih, adeolu, al88nsk, azanux, bareli, boredpukar, cu5t0mpeo, d4r3d3v1l, darksnow, deth, dutra, ether_sky, haxatron, ke1caM, kodyvim, m4ttm, mgf15, mrudenko, nmirchev8, nobody2018, nuthan2x, peanuts, piyushshukla, ravikiranweb3, rouhsamad, seraviz, simplor, slylandro_star, stealth, th13vn, vnavascues, wangxx2026, zaevlad
0.1172 USDC - $0.12
An attacker can gain access to onlyRouter
privileged functions by setting themselves (EOA) or their contract as the router
address and proceeding to mint/burn DcntEth tokens at will.
The DcntEth
contract mints Decent Eth, the supposed Decent's Protocol tokenized Eth. Ideally, functions that influence token supply/circulation are protected by modifiers that restricts access to trusted addresses or the protocol team for example, the owner
address with an onlyOwner
modifier. But, the setRouter(address _router)
function which sets up one such privilege for a specified router address is exposed to anyone. It gives the router
address the privilege to mint
& burn
DcntEth tokens at will. The function doesn't verify that the caller actually owns the DcntEth
contract or has privileges to modify it. It just goes ahead and sets the router
address.
When an attacker gains access to the onlyRouter
privileged actions, what can they do with it? Well, while burn
is interesting (because you can burn from anyone's account), mint
is more interesting because it makes you richer faster and you can engineer such a scenario below for a better outcome:
setRouter()
function, figures if she sets herself, she gains privileges, then proceeds to call the function setting her address as the router
DecentEthRouter
contractredeemWeth()
, and if the DecentEthRouter
has some WETH i.e enough reserves, she slowly offloads her DcntEth for WETHThis is the affected code block: DcntEth::setRouter :
@> function setRouter(address _router) public { router = _router; }
As you can see, the function is missing an access control modifier.
Manual Review
Make the setRouter()
function have access control. For example, doing something like:
- function setRouter(address _router) public { + function setRouter(address _router) public onlyOwner { router = _router; }
Access Control
#0 - c4-pre-sort
2024-01-24T05:45:07Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-01-24T05:45:14Z
raymondfam marked the issue as duplicate of #14
#2 - c4-judge
2024-02-03T13:24:28Z
alex-ppg marked the issue as satisfactory