---
# System prepended metadata

title: Untitled

---

```
pragma solidity ^0.6.0;

import "github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/Create2.sol";

interface IFactory
{
    function deploy(uint256, uint256) external returns (address);
    function upgradeproxy(uint256, uint256) external returns (address);
}

contract Proxy
{
    IFactory public factory;
    uint256  public salt;
    uint256  public value;
    
    modifier onlyFactory()
    {
        require(address(factory) == msg.sender);
        _;
    }
    
    constructor()
    public
    {
        factory = IFactory(msg.sender);
    }
    
    function initialize(uint256 _salt, uint256 _value)
    public onlyFactory()
    {
        salt  = _salt;
        value = _value;
    }
    
    function destroy()
    public onlyFactory()
    {
        selfdestruct(payable(address(this)));
    }
    
    function upgrade(uint256 _newvalue)
    public /* restricted */
    {
        factory.upgradeproxy(salt, _newvalue);
    }
}

contract Factory
{
    function deploy(uint256 _salt, uint256 _value)
    public returns (address)
    {
        address proxy = Create2.deploy(0, bytes32(_salt), abi.encodePacked(type(Proxy).creationCode));
        Proxy(proxy).initialize(_salt, _value);
        return proxy;
    }
    
    function upgradeproxy(uint256 _salt, uint256 _newvalue)
    public returns (address)
    {
        Proxy(msg.sender).destroy();
        deploy(_salt, _newvalue);
    }
}

```