I think in this video we got rid of onlyOwner modifier from “setNumberOfDogs” because it is inherited from Dogs contract. So the whole initialization concept does not make sense. Dogs contract cannot have onlyOwner modifier in “setNumberOfDogs” because it would need also initialize function and would become the same contract as DogsUpdated. So something like this would be better:
Dogs:
pragma solidity 0.5.2;
import "./Storage.sol";
contract Dogs is Storage {
constructor() public {
owner = msg.sender;
}
function getNumberOfDogs() public view returns (uint256) {
return _uintStorage["Dogs"];
}
function setNumberOfDogs(uint256 toSet) public {
_uintStorage["Dogs"] = toSet;
}
}
DogsUpdated:
pragma solidity 0.5.2;
import "./Dogs.sol";
contract DogsUpdated is Dogs {
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
constructor() public {
//This function will not be called - because we are using delegatecall from proxy contract
//But the attacker can easily call it and then change owner from DogsUpdated perspective
//so to prevent that this function must be included
initialize(msg.sender);
}
function initialize(address _owner) public {
//Action can be performed only once
require(!_initialized);
owner = _owner;
_initialized = true;
}
function setNumberOfDogs(uint256 toSet) public onlyOwner {
_uintStorage["Dogs"] = toSet;
}
}