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: 91/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
https://github.com/decentxyz/decent-bridge/blob/7f90fd4489551b69c20d11eeecb17a3f564afb18/src/DcntEth.sol#L20-L22 https://github.com/decentxyz/decent-bridge/blob/7f90fd4489551b69c20d11eeecb17a3f564afb18/src/DecentEthRouter.sol#L285-L300
Arbitrary minting and burning of DcntEth
tokens, which may later be used to redeem ETH/WETH from the router.
In the DcntEth
contract, tokens can be minted/burned either by the owner or the router.
function mint(address _to, uint256 _amount) public onlyRouter { _mint(_to, _amount); } function burn(address _from, uint256 _amount) public onlyRouter { _burn(_from, _amount); } function mintByOwner(address _to, uint256 _amount) public onlyOwner { _mint(_to, _amount); } function burnByOwner(address _from, uint256 _amount) public onlyOwner { _burn(_from, _amount); }
To mint tokens through the router, the router needs to be set.
function setRouter(address _router) public { router = _router; }
The function to the set the router however, is public and unprotected, making it accessible to anyone. This causes that any user, a malicious user can set any address as the router address and mint/burn DcntEth
at will.
The malicious user can also use this to redeem ETH and WETH from the DecentEthRouter
contract thereby stealing funds from the protocol.
function redeemEth( uint256 amount ) public onlyIfWeHaveEnoughReserves(amount) { dcntEth.transferFrom(msg.sender, address(this), amount); weth.withdraw(amount); payable(msg.sender).transfer(amount); } /// @inheritdoc IDecentEthRouter function redeemWeth( uint256 amount ) public onlyIfWeHaveEnoughReserves(amount) { dcntEth.transferFrom(msg.sender, address(this), amount); weth.transfer(msg.sender, amount); }
Manual code review
Add an onlyOwner modifier to the setRouter
function
Access Control
#0 - c4-pre-sort
2024-01-24T22:46:24Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-01-24T22:46:35Z
raymondfam marked the issue as duplicate of #14
#2 - c4-judge
2024-02-03T13:13:44Z
alex-ppg marked the issue as satisfactory
🌟 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
A malicious user can change router address or set it to address 0, hampering the DecentEthRouter's ability to add or remove ETH/WETH liquidity.
Bridge liquidity can be added to or removed from DecentEthRouter
by calling the addLiquidityEth
, addLiquidityWeth
, removeLiquidityEth
and removeLiquidityWeth
functions.
function addLiquidityEth() public payable onlyEthChain userDepositing(msg.value) { weth.deposit{value: msg.value}(); dcntEth.mint(address(this), msg.value); //@note } /// @inheritdoc IDecentEthRouter function removeLiquidityEth( uint256 amount ) public onlyEthChain userIsWithdrawing(amount) { dcntEth.burn(address(this), amount); //@note weth.withdraw(amount); payable(msg.sender).transfer(amount); }
Doing this requires that DcntEth tokens are minted or burned before ETH/WETH is sent to or retrieved from the user, which is executed in the DcntEth contract by calling the mint/burn functions.
function mint(address _to, uint256 _amount) public onlyRouter { _mint(_to, _amount); } function burn(address _from, uint256 _amount) public onlyRouter { _burn(_from, _amount); }
The mint/burn functions are inteded to be called by only the router, in this case the DecentEthRouter and is expected to be set by calling the setRouter
function.
/** * @param _router the decentEthRouter associated with this eth */ function setRouter(address _router) public { router = _router; }
As can be seen from the above, the function is public and unprotected meaning anyone can call the function. Note also that the function is executed in one step and features no zero address checks.
A malicious user can call the the function, passing in a zero address, or any arbitrary address, causing that all calls to mint or burn tokens from the DecentEthRouter fails, and thus liquidity cannot be added or removed from the bridge.
Manual code review
Add an onlyOwner modifier to the setRouter
function
Access Control
#0 - c4-pre-sort
2024-01-24T22:52:36Z
raymondfam marked the issue as sufficient quality report
#1 - c4-pre-sort
2024-01-24T22:52:43Z
raymondfam marked the issue as duplicate of #14
#2 - alex-ppg
2024-02-03T13:14:47Z
The submission fails to identify the correct impact or exploitation vector and instead mentions an attack vector that would not be of high risk.
#3 - c4-judge
2024-02-03T13:14:59Z
alex-ppg marked the issue as partial-50