Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions guides/AllDeployments.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* **VaultManager** `0x589a504f2ee9d054b483c700fa814863d639381e` [sonicscan](https://sonicscan.org/address/0x589a504f2ee9d054b483c700fa814863d639381e)
* **StrategyLogic** `0xe0e71b484bb20e37d18ab51fb60c32dec778478a` [sonicscan](https://sonicscan.org/address/0xe0e71b484bb20e37d18ab51fb60c32dec778478a)
* **Zap** `0x029dfd1a79e0ad9305d773fb8f3c01d8ef9b913d` [sonicscan](https://sonicscan.org/address/0x029dfd1a79e0ad9305d773fb8f3c01d8ef9b913d)
* **ProxyFactory** `0xab82117689541c4B893D0021Cd168cAb566D92E1` [sonicscan](https://sonicscan.org/address/0xab82117689541c4b893d0021cd168cab566d92e1#readProxyContract)

### Periphery

Expand Down
20 changes: 20 additions & 0 deletions script/deploy-core-single/ProxyFactory.Sonic.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {Script} from "forge-std/Script.sol";
import {SonicConstantsLib} from "../../chains/sonic/SonicConstantsLib.sol";
import {ProxyFactory, IProxyFactory} from "../../src/core/ProxyFactory.sol";
import {Proxy} from "../../src/core/proxy/Proxy.sol";

contract DeployProxyFactorySonic is Script {
function run() external {
uint deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);
Proxy proxy = new Proxy();
proxy.initProxy(address(new ProxyFactory()));
IProxyFactory(address(proxy)).initialize(SonicConstantsLib.PLATFORM);
vm.stopBroadcast();
}

function testDeployScript() external {}
}
53 changes: 53 additions & 0 deletions src/core/ProxyFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {Controllable, IControllable} from "./base/Controllable.sol";
import {Proxy, IProxy} from "./proxy/Proxy.sol";
import {IProxyFactory} from "../interfaces/IProxyFactory.sol";

/// @notice Create2 proxy deployer
/// @author Alien Deployer (https://github.com/a17)
contract ProxyFactory is Controllable, IProxyFactory {
/*Β΄:Β°β€’.Β°+.*β€’Β΄.*:˚.Β°*.Λšβ€’Β΄.Β°:Β°β€’.Β°β€’.*β€’Β΄.*:˚.Β°*.Λšβ€’Β΄.Β°:Β°β€’.Β°+.*β€’Β΄.*:*/
/* CONSTANTS */
/*.β€’Β°:Β°.Β΄+˚.*Β°.˚:*.Β΄β€’*.+Β°.β€’Β°:Β΄*.Β΄β€’*.β€’Β°.β€’Β°:Β°.Β΄:β€’ΛšΒ°.*Β°.˚:*.Β΄+Β°.β€’*/

/// @inheritdoc IControllable
string public constant VERSION = "1.0.0";

/*Β΄:Β°β€’.Β°+.*β€’Β΄.*:˚.Β°*.Λšβ€’Β΄.Β°:Β°β€’.Β°β€’.*β€’Β΄.*:˚.Β°*.Λšβ€’Β΄.Β°:Β°β€’.Β°+.*β€’Β΄.*:*/
/* INITIALIZATION */
/*.β€’Β°:Β°.Β΄+˚.*Β°.˚:*.Β΄β€’*.+Β°.β€’Β°:Β΄*.Β΄β€’*.β€’Β°.β€’Β°:Β°.Β΄:β€’ΛšΒ°.*Β°.˚:*.Β΄+Β°.β€’*/

/// @inheritdoc IProxyFactory
function initialize(address platform_) public initializer {
__Controllable_init(platform_);
}

/*Β΄:Β°β€’.Β°+.*β€’Β΄.*:˚.Β°*.Λšβ€’Β΄.Β°:Β°β€’.Β°β€’.*β€’Β΄.*:˚.Β°*.Λšβ€’Β΄.Β°:Β°β€’.Β°+.*β€’Β΄.*:*/
/* RESTRICTED ACTIONS */
/*.β€’Β°:Β°.Β΄+˚.*Β°.˚:*.Β΄β€’*.+Β°.β€’Β°:Β΄*.Β΄β€’*.β€’Β°.β€’Β°:Β°.Β΄:β€’ΛšΒ°.*Β°.˚:*.Β΄+Β°.β€’*/

/// @inheritdoc IProxyFactory
function deployProxy(bytes32 salt, address implementation) external onlyOperator returns (address proxy) {
proxy = address(new Proxy{salt: salt}());
IProxy(proxy).initProxy(implementation);
}

/*Β΄:Β°β€’.Β°+.*β€’Β΄.*:˚.Β°*.Λšβ€’Β΄.Β°:Β°β€’.Β°β€’.*β€’Β΄.*:˚.Β°*.Λšβ€’Β΄.Β°:Β°β€’.Β°+.*β€’Β΄.*:*/
/* VIEW FUNCTIONS */
/*.β€’Β°:Β°.Β΄+˚.*Β°.˚:*.Β΄β€’*.+Β°.β€’Β°:Β΄*.Β΄β€’*.β€’Β°.β€’Β°:Β°.Β΄:β€’ΛšΒ°.*Β°.˚:*.Β΄+Β°.β€’*/

/// @inheritdoc IProxyFactory
function getProxyInitCodeHash() public pure returns (bytes32) {
return keccak256(abi.encodePacked(type(Proxy).creationCode));
}

/// @inheritdoc IProxyFactory
function getCreate2Address(bytes32 salt) external view returns (address) {
return
address(
uint160(uint(keccak256(abi.encodePacked(bytes1(0xff), address(this), salt, getProxyInitCodeHash()))))
);
}
}
23 changes: 23 additions & 0 deletions src/interfaces/IProxyFactory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

interface IProxyFactory {
/// @dev Initialize proxy factory
/// @param platform_ Platform of the stability
function initialize(address platform_) external;

/// @dev Deploy and initialize new Proxy contract
/// @param salt Salt for Create2
/// @param implementation Contract logic for proxy to be initialized
/// @return proxy Deployed address
function deployProxy(bytes32 salt, address implementation) external returns (address proxy);

/// @notice Get init code hash for Create2 addresses generation
/// @return Keccak256 hash of encoded Proxy creation code
function getProxyInitCodeHash() external pure returns (bytes32);

/// @notice Check proxy address that will be deployed
/// @param salt Salt for Create2
/// @return Deployed address
function getCreate2Address(bytes32 salt) external view returns (address);
}
32 changes: 32 additions & 0 deletions test/core/ProxyFactory.Ethereum.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {EthereumSetup} from "../base/chains/EthereumSetup.sol";
import {ProxyFactory, IProxyFactory, Proxy} from "../../src/core/ProxyFactory.sol";
import {Swapper} from "../../src/core/Swapper.sol";

contract ProxyFactoryEthereumTest is EthereumSetup {
IProxyFactory public proxyFactory;

constructor() {
vm.rollFork(23600000); // Oct-17-2025 09:15:23 PM +UTC
_init();
}

function setUp() public {
ProxyFactory implementation = new ProxyFactory();
Proxy proxy = new Proxy();
proxy.initProxy(address(implementation));
proxyFactory = IProxyFactory(address(proxy));
proxyFactory.initialize(address(platform));
}

function testProxyFactory() public {
//console.logBytes32(proxyFactory.getProxyInitCodeHash());
//console.log(address (proxyFactory));
//assertEq(proxyFactory.getProxyInitCodeHash(), 0x83e57d2d2b2765120795e70721641dfd7fbfb8130cf002195d9fbfeb619fb88a);
proxyFactory.getProxyInitCodeHash();
address deployedProxy = proxyFactory.deployProxy("0x00", address(new Swapper()));
assertEq(deployedProxy, proxyFactory.getCreate2Address("0x00"));
}
}