Motorbike
Take ownership of the Motorbike contract engine by exploiting the UUPS proxy pattern and initializing the logic contract.
Vulnerable Code
Analyze the Solidity code below to find the vulnerability.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// From OpenZeppelin Contracts v4.x
import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";
import "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/proxy/utils/Initializable.sol";
// Logic Contract (The Engine)
contract Engine is Initializable, Ownable {
address public horsePower; // Example state variable
address public rider;
// Initializer function for the logic contract
function initialize() external initializer {
// Sets the owner of the logic contract instance
__Ownable_init();
// Example initialization logic
horsePower = address(123); // Placeholder value
rider = msg.sender; // Initial rider is deployer/initializer
}
// Function to upgrade the implementation (only callable by owner)
// This function is PART of the logic contract in UUPS
function upgradeToAndCall(address newImplementation, bytes memory data) external payable onlyOwner {
_upgradeToAndCall(newImplementation, data, true);
}
// Internal upgrade function (part of UUPS pattern)
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
// Placeholder functions
function getHorsePower() public view returns(address) { return horsePower; }
function getRider() public view returns(address) { return rider; }
// A function vulnerable to selfdestruct
function explode() public payable {
// Only callable after upgrade? Assume it's present.
selfdestruct(payable(msg.sender));
}
}
// Proxy Contract (The Motorbike)
// Inherits from BeaconProxy, pointing to an UpgradeableBeacon
// Assume the beacon and initial Engine logic contract are deployed separately.
// Example Beacon setup (not shown in detail):
// UpgradeableBeacon beacon = new UpgradeableBeacon(initialEngineAddress);
// BeaconProxy motorbikeProxy = new BeaconProxy(address(beacon), initData);
// --- Simplified for context ---
// Imagine Motorbike is a proxy pointing to an Engine instance.
// The vulnerability relies on the Engine's state and upgradeability.
Submit Explanation
Explain the vulnerability and how to exploit it.
Hints (5)
Just a little peak
Hint 1
Hint 2
Hint 3
Hint 4
Hint 5
Explanation
Discomfort = Learning