Skip to content

Commit

Permalink
rename nonce as salt
Browse files Browse the repository at this point in the history
  • Loading branch information
mdtanrikulu committed Oct 18, 2024
1 parent 41df5e8 commit 07a8b1e
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 33 deletions.
6 changes: 3 additions & 3 deletions src/TransparentVerifiableProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interface ITransparentVerifiableProxy {
}

contract TransparentVerifiableProxy is Proxy, Initializable {
uint256 public nonce; // Nonce, being used creating the proxy
uint256 public salt; // Salt, being used creating the proxy
address public owner; // The owner of the proxy contract

// ### EVENTS
Expand All @@ -41,7 +41,7 @@ contract TransparentVerifiableProxy is Proxy, Initializable {
* - If `data` is empty, `msg.value` must be zero.
*/
function initialize(
uint256 _nonce,
uint256 _salt,
address _owner,
address implementation,
bytes memory data
Expand All @@ -51,7 +51,7 @@ contract TransparentVerifiableProxy is Proxy, Initializable {
"New implementation cannot be the zero address"
);

nonce = _nonce;
salt = _salt;
owner = _owner;

ERC1967Utils.upgradeToAndCall(implementation, data);
Expand Down
31 changes: 16 additions & 15 deletions src/VerifiableFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
import {ITransparentVerifiableProxy, TransparentVerifiableProxy} from "./TransparentVerifiableProxy.sol";

interface IProxy {
function nonce() external view returns (uint256);
function salt() external view returns (uint256);

function owner() external view returns (address);
}
Expand All @@ -17,43 +17,44 @@ contract VerifiableFactory {
event ProxyDeployed(
address indexed sender,
address indexed proxyAddress,
bytes32 salt,
uint256 salt,
address implementation
);

constructor() {}

/**
* @dev deploys a new `TransparentVerifiableProxy` contract using a deterministic address derived from
* the sender's address and a nonce.
* the sender's address and a salt.
*
* The function creates a new proxy contract that is controlled by the factory's `ProxyAdmin`.
* When the proxy is deployed, it starts by using the `RegistryProxy` contract as its main implementation.
* During the deployment, the initialize function is called to set up the proxy.
* The nonce ensures that each user gets a unique proxy, even if the same user deploys multiple proxies.
* The salt ensures that each user gets a unique proxy, even if the same user deploys multiple proxies.
*
* - The function uses a `salt` to create a deterministic address based on `msg.sender` and a provided nonce.
* - The function uses a `salt` to create a deterministic address based on `msg.sender` and a provided salt.
* - The `initialize` function of the `RegistryProxy` contract is called immediately after deployment to set up
* the proxy with the nonce and `ProxyAdmin`.
* the proxy with the salt and `ProxyAdmin`.
* - The proxy is managed by a `ProxyAdmin` contract, ensuring that upgrades and critical functions are restricted to the admin.
* - A custom event `ProxyDeployed` is emitted to track the deployment of the new proxy.
*
* @param nonce A unique number provided by the caller to create a unique proxy address.
* @param implementation Registry implementation address
* @param salt A unique number provided by the caller to create a unique proxy address.
* @return proxy The address of the deployed `TransparentVerifiableProxy` contract.
*/
function deployProxy(
address implementation,
uint256 nonce
uint256 salt
) external returns (address) {
bytes32 salt = keccak256(abi.encode(msg.sender, nonce));
bytes32 outerSalt = keccak256(abi.encode(msg.sender, salt));

TransparentVerifiableProxy proxy = new TransparentVerifiableProxy{
salt: salt
salt: outerSalt
}();

require(isContract(address(proxy)), "Proxy deployment failed");

proxy.initialize(nonce, address(this), implementation, "");
proxy.initialize(salt, address(this), implementation, "");

emit ProxyDeployed(msg.sender, address(proxy), salt, implementation);
return address(proxy);
Expand Down Expand Up @@ -86,7 +87,7 @@ contract VerifiableFactory {
*/
function verifyContract(address proxy) public view returns (bool) {
// directly fetch storage
try IProxy(proxy).nonce() returns (uint256 nonce) {
try IProxy(proxy).salt() returns (uint256 salt) {
address owner = IProxy(proxy).owner();

require(
Expand All @@ -95,16 +96,16 @@ contract VerifiableFactory {
);

// reconstruct the address using CREATE2 and the original salt
bytes32 salt = keccak256(abi.encode(msg.sender, nonce));
bytes32 outerSalt = keccak256(abi.encode(msg.sender, salt));

// bytes memory bytecode = abi.encodePacked(
// type(TransparentVerifiableProxy).creationCode,
// abi.encode(salt, address(this))
// );

// Compute the expected proxy address using the salt
// Compute the expected proxy address using the outerSalt
address expectedProxyAddress = Create2.computeAddress(
salt,
outerSalt,
keccak256(type(TransparentVerifiableProxy).creationCode)
);

Expand Down
30 changes: 15 additions & 15 deletions test/VerifiableFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ contract VerifiableFactoryTest is Test {
}

function testDeployProxy() public {
uint256 nonce = 1;
address proxyAddress = factory.deployProxy(address(0), nonce);
uint256 salt = 1;
address proxyAddress = factory.deployProxy(address(0), salt);

// Check if proxy was deployed
uint256 codeSize;
Expand All @@ -32,18 +32,18 @@ contract VerifiableFactoryTest is Test {
assert(codeSize > 0);
emit log_named_address("Deployed Proxy Address", proxyAddress);

// Check if proxy was initialized properly with nonce and proxyAdmin
// Check if proxy was initialized properly with salt and proxyAdmin
(bool success, bytes memory result) = proxyAddress.call(
abi.encodeWithSignature("nonce()")
abi.encodeWithSignature("salt()")
);
assert(success);
uint256 deployedNonce = abi.decode(result, (uint256));
assertEq(deployedNonce, nonce);
assertEq(deployedNonce, salt);
}

function testUpdateRegistry() public {
uint256 nonce = 1;
address proxyAddress = factory.deployProxy(address(0), nonce);
uint256 salt = 1;
address proxyAddress = factory.deployProxy(address(0), salt);
address newRegistryAddress = address(0xBEEF);

// Update the registry of the deployed proxy
Expand All @@ -65,17 +65,17 @@ contract VerifiableFactoryTest is Test {
}

function testVerifyContract() public {
uint256 nonce = 1;
address proxyAddress = factory.deployProxy(address(0), nonce); // tbd
uint256 salt = 1;
address proxyAddress = factory.deployProxy(address(0), salt); // tbd
factory.verifyContract(proxyAddress);

// If no revert, verification passed
assertTrue(true);
}

function testUpgradeImplementation() public {
uint256 nonce = 1;
address proxyAddress = factory.deployProxy(address(0), nonce); // tbd
uint256 salt = 1;
address proxyAddress = factory.deployProxy(address(0), salt); // tbd

// Upgrade the proxy to point to the new implementation
factory.upgradeImplementation(proxyAddress, address(0), ""); //tbd
Expand All @@ -90,10 +90,10 @@ contract VerifiableFactoryTest is Test {
}

function testUpgradeAndCall() public {
uint256 nonce = 1;
address proxyAddress = factory.deployProxy(address(0), nonce);
uint256 salt = 1;
address proxyAddress = factory.deployProxy(address(0), salt);

// ABI encode data for initializing the new implementation with a specific nonce and registry
// ABI encode data for initializing the new implementation with a specific salt and registry
bytes memory data = abi.encodeWithSignature(
"initialize(uint256,address)",
2,
Expand All @@ -105,7 +105,7 @@ contract VerifiableFactoryTest is Test {

// Check if the new implementation was initialized correctly
(bool success, bytes memory result) = proxyAddress.call(
abi.encodeWithSignature("nonce()")
abi.encodeWithSignature("salt()")
);
assert(success);
uint256 newNonce = abi.decode(result, (uint256));
Expand Down

0 comments on commit 07a8b1e

Please sign in to comment.