Platform: Code4rena
Start Date: 07/07/2022
Pot Size: $75,000 USDC
Total HM: 32
Participants: 141
Period: 7 days
Judge: HardlyDifficult
Total Solo HM: 4
Id: 144
League: ETH
Rank: 135/141
Findings: 1
Award: $4.96
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: byterocket
Also found by: 0x1f8b, 242, ACai, BradMoon, Chom, Lambda, PwnedNoMore, Twpony, __141345__, ayeslick, berndartmueller, cccz, giovannidisiena, infosec_us_team, minhtrng, nine9, oyc_109, reassor, slywaters, sseefried, tofunmi, unforgiven
4.9607 USDC - $4.96
https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/Vault.sol#L125-L132 https://github.com/code-423n4/2022-07-fractional/blob/8f2697ae727c60c93ea47276f8fa128369abfe51/src/Vault.sol#L24-L29
Contract Vault
implements logic in _execute
function to prevent plugins from changing Vault
's owner.
(..) // Save the owner address in memory to ensure that it cannot be modified during the DELEGATECALL address owner_ = owner; // Reserve some gas to ensure that the function has enough to finish the execution uint256 stipend = gasleft() - MIN_GAS_RESERVE; // Delegate call to the target contract (success, response) = _target.delegatecall{gas: stipend}(_data); if (owner_ != owner) revert OwnerChanged(owner_, owner); (..)
If owner
changes then the transaction reverts with OwnerChanged(owner_, owner);
.
The issue is that this can be easily bypassed by changing Vault
's nonce
to 0
and then executing init
function to take over the ownership of Vault
contract.
function init() external { if (nonce != 0) revert Initialized(owner, msg.sender, nonce); nonce = 1; owner = msg.sender; emit TransferOwnership(address(0), msg.sender); }
Exploitation Scenario:
nonce
to 0
init
function to set himself as ownerVault
's owner has changedVault.sol
:
Manual Review / VSCode
It is recommended to check if nonce
has changed and revert if it did.
#0 - ecmendenhall
2022-07-15T03:42:12Z
#1 - HardlyDifficult
2022-07-26T23:59:31Z
Duping to #487