Skip to content

Commit

Permalink
created tests for TWCloneFactory
Browse files Browse the repository at this point in the history
  • Loading branch information
GWSzeto committed Nov 25, 2024
1 parent f37eca1 commit a842cbb
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/TWCloneFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ contract TWCloneFactory {
}
}

function _guard(bytes32 salt, bytes memory data) internal returns (bytes32) {
function _guard(bytes32 salt, bytes memory data) internal view returns (bytes32) {
// 01 if cross chain deployment is allowed
// 00 if cross chain deployment is not allowed
bool allowCrossChainDeployment = bytes1(salt[0]) == hex"01";
Expand Down
136 changes: 136 additions & 0 deletions test/TWCloneFactory.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.20;

import "../src/TWCloneFactory.sol";
import {LibClone} from "@solady/utils/LibClone.sol";
import "forge-std/Test.sol";

contract MockImplementation {

uint256 public value;

function initialize(uint256 _value) public {
value = _value;
}

}

contract TWCloneFactoryTest is Test {

TWCloneFactory factory;
MockImplementation implementation;

uint256 chainId1 = 1;
uint256 chainId2 = 2;

function setUp() public {
factory = new TWCloneFactory();
implementation = new MockImplementation();
}

// Test case 1: Cross chain deployment on - same address on two chains
function testCrossChainDeploymentOnSameAddress() public {
// Set up the salt with allowCrossChainDeployment = true, encodeDataIntoSalt = false
// salt[0] == hex"01", salt[1] == hex"00"
bytes32 salt = bytes32(abi.encodePacked(hex"01", hex"00", bytes30(0)));
bytes memory data = "";

// Save the current state
uint256 snapshotId = vm.snapshot();

// Set chain ID to chainId1 and deploy
vm.chainId(chainId1);
address proxy1 = factory.deployProxyByImplementation(address(implementation), data, salt);

// Revert to the snapshot to reset the state
vm.revertTo(snapshotId);

// Set chain ID to chainId2 and deploy
vm.chainId(chainId2);
address proxy2 = factory.deployProxyByImplementation(address(implementation), data, salt);

// Check that the proxies are the same
assertEq(proxy1, proxy2, "Proxies should be the same on different chains when cross chain deployment is on");
}

// Test case 2: Cross chain deployment off - different address on two chains
function testCrossChainDeploymentOffDifferentAddress() public {
// Set up the salt with allowCrossChainDeployment = false, encodeDataIntoSalt = false
// salt[0] == hex"00", salt[1] == hex"00"
bytes32 salt = bytes32(abi.encodePacked(hex"00", hex"00", bytes30(0)));
bytes memory data = "";

// Save the current state
uint256 snapshotId = vm.snapshot();

// Set chain ID to chainId1 and deploy
vm.chainId(chainId1);
address proxy1 = factory.deployProxyByImplementation(address(implementation), data, salt);

// Revert to the snapshot to reset the state
vm.revertTo(snapshotId);

// Set chain ID to chainId2 and deploy
vm.chainId(chainId2);
address proxy2 = factory.deployProxyByImplementation(address(implementation), data, salt);

// Check that the proxies are different
assertNotEq(
proxy1, proxy2, "Proxies should be different on different chains when cross chain deployment is off"
);
}

// Test case 3: Not encodeDataIntoSalt - same address with different init data
function testNotEncodeDataIntoSaltSameAddress() public {
// Set up the salt with allowCrossChainDeployment = true, encodeDataIntoSalt = false
// salt[0] == hex"01", salt[1] == hex"00"
bytes32 salt = bytes32(abi.encodePacked(hex"01", hex"00", bytes30(0)));

// Save the current state
uint256 snapshotId = vm.snapshot();

// Deploy with data1
vm.chainId(chainId1);
bytes memory data1 = abi.encodeWithSignature("initialize(uint256)", 42);
address proxy1 = factory.deployProxyByImplementation(address(implementation), data1, salt);

// Revert to the snapshot to reset the state
vm.revertTo(snapshotId);

// Deploy with data2
vm.chainId(chainId2);
bytes memory data2 = abi.encodeWithSignature("initialize(uint256)", 100);
address proxy2 = factory.deployProxyByImplementation(address(implementation), data2, salt);

// Check that the proxies are the same
assertEq(proxy1, proxy2, "Proxies should be the same when encodeDataIntoSalt is off");
}

// Test case 4: Encode Data into salt - different address with different init data
function testEncodeDataIntoSaltDifferentAddress() public {
// Set up the salt with allowCrossChainDeployment = true, encodeDataIntoSalt = true
// salt[0] == hex"01", salt[1] == hex"01"
bytes32 salt = bytes32(abi.encodePacked(hex"01", hex"01", bytes30(0)));

// Deploy with data1
bytes memory data1 = abi.encodeWithSignature("initialize(uint256)", 42);
address proxy1 = factory.deployProxyByImplementation(address(implementation), data1, salt);

// Deploy with data2
bytes memory data2 = abi.encodeWithSignature("initialize(uint256)", 100);
address proxy2 = factory.deployProxyByImplementation(address(implementation), data2, salt);

// Check that the proxies are different
assertNotEq(proxy1, proxy2, "Proxies should be different when encodeDataIntoSalt is on");

// Verify that both initializations took effect independently
MockImplementation proxyImpl1 = MockImplementation(proxy1);
uint256 value1 = proxyImpl1.value();
assertEq(value1, 42, "Value should be initialized to 42");

MockImplementation proxyImpl2 = MockImplementation(proxy2);
uint256 value2 = proxyImpl2.value();
assertEq(value2, 100, "Value should be initialized to 100");
}

}

0 comments on commit a842cbb

Please sign in to comment.