I have deployed an upgradable proxy contract with create3factory from solmate.
In my contract i transfer ownership to an address. But still the owner ship is not on that address. Its a differant address. Here is my contract how should i do?
Code to reproduce
Here is box contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "hardhat/console.sol";
contract Box is Initializable, OwnableUpgradeable {
uint256 public value;
function initialize(uint256 _value, address _owner) public initializer {
__Ownable_init();
transferOwnership(_owner);
value = _value;
console.log(_owner);
}
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
// Emitted when the stored value changes
event ValueChanged(uint256 newValue);
// Stores a new value in the contract
function store(uint256 newValue) public onlyOwner {
value = newValue;
emit ValueChanged(newValue);
}
// Reads the last stored value
function retrieve() public view returns (uint256) {
return value;
}
}
Here is create3 contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
import "@openzeppelin/contracts/access/Ownable.sol";
import "solmate/src/utils/CREATE3.sol";
contract Create3Factory is Ownable {
event Deployed(address contractAddress);
function deploy(
bytes32 _salt,
bytes memory _creationCode
) external payable onlyOwner returns (address deployed) {
bytes32 salt = keccak256(abi.encodePacked(msg.sender, _salt));
deployed = CREATE3.deploy(salt, _creationCode, msg.value);
emit Deployed(deployed);
}
function getDeployedAddress(
address _deployer,
bytes32 _salt
) external view returns (address) {
bytes32 salt = keccak256(abi.encodePacked(_deployer, _salt));
return CREATE3.getDeployed(salt);
}
}
Deployment scripts:
module.exports = async ({ getNamedAccounts, deployments }) => {
const { deploy, log } = deployments;
const { deployer } = await getNamedAccounts();
const args = [];
const Box = await hre.ethers.getContractFactory("Box");
const Create3Factory = await hre.deployments.get("Create3Factory");
const create3Factory = await hre.ethers.getContractAt(
"Create3Factory",
Create3Factory.address
);
const ProxyAdmin = await hre.deployments.get("ProxyAdmin");
const proxyAdmin = await hre.ethers.getContractAt(
"ProxyAdmin",
ProxyAdmin.address
);
const box = await Box.deploy();
await box.deployed();
console.log("box address: ", box.address);
const functionData = box.interface.encodeFunctionData("initialize", [
42,
deployer,
]);
const TransparentProxyCreationCode = await getCreationCode({
contractName: "TransparentProxy",
constructorArgs: {
types: ["address", "address", "bytes"],
values: [box.address, proxyAdmin.address, functionData],
},
});
const tx2 = await create3Factory.deploy(
"0x43f379c0214535bb128fca03870dd998b303c983a3d40d49c0ab85fc3f8c0f1f",
TransparentProxyCreationCode
);
const receipt = await tx2.wait();
const parsedEvents = receipt.events?.map((event) => {
return {
name: event.event,
args: event.args,
};
});
if (!parsedEvents) {
throw new Error("No events found");
}
const { contractAddress } = parsedEvents.find(
(event) => event.name === "Deployed"
)?.args;
console.log("proxyAddress: ", contractAddress);
};
const getCreationCode = async ({ contractName, constructorArgs }) => {
const bytecode = (await ethers.getContractFactory(contractName)).bytecode;
return `${bytecode}${ethers.utils.defaultAbiCoder
.encode(constructorArgs.types, constructorArgs.values)
.slice(2)}`;
};
module.exports.tags = ["all", "proxy"];
Here is i am try to check owner of the contract:
const { ethers } = require("hardhat");
async function main() {
const [deployer, user, user1] = await ethers.getSigners();
console.log(user.address);
const Box = await ethers.getContractFactory("Box");
const box = Box.attach("PUT ADDRESS OF THE ADDRESS OF CONTRACT ADDRESS FROM DEPLOYMENT SCRIPT ");
console.log(await box.owner());
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Here is result of console.log this script 0xE20420d16367dCbB69Be37f57F76cCe594b6C35C
this is not the deployer address. The deployer address is 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 which is first address of hardhat node.
What am i doing wrong?
Edit:
Here is i deploy to mumbai network.First i deploy create3factory: https://mumbai.polygonscan.com/address/0x844b8e887b1e2561da375b48a73ec916972592cf
Second i deploy proxyadmin:
https://mumbai.polygonscan.com/address/0x7ff287395cccf64244226b1a165b96aedb7bee91
Third i deploy boxV1 contract and call proxy:
BoxV1 : https://mumbai.polygonscan.com/address/0xead45dfc2a64855e35421bf5e52ace65e064eae4
create3Factory deploys this contract: https://mumbai.polygonscan.com/address/0x52079aa2e26232fcec8ad69218ccafc2ff4890ec
What is this contract? its not proxy contract? When i get the owner of the proxy contract ( which is this one 0x173415F1501A6Ccc4a57CCe2BD3bcE268417ff0a coming from create3factory contract event)
i get this contract address. How can i able to call proxy contract functions with onlyowner modifer? ıf this contract is the owner of the proxy i shouldnt able to call it. ? What am i missing?
Environment
Hardhat