-
-
Save madeinfree/369d5fdf4ccf7724b581b23013f192bb to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.14+commit.80d49f37.js&optimize=false&runs=200&gist=
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity 0.8.14; | |
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/master/contracts/proxy/beacon/BeaconProxy.sol"; | |
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/master/contracts/proxy/beacon/UpgradeableBeacon.sol"; | |
import {ImplementationV1, ImplementationV2} from "./Implementation.sol"; | |
contract Setup { | |
address immutable public proxy1; | |
address immutable public proxy2; | |
address immutable public beacon; | |
address immutable public implV1; | |
address immutable public implV2; | |
constructor() { | |
implV1 = address(new ImplementationV1()); | |
implV2 = address(new ImplementationV2()); | |
beacon = address(new UpgradeableBeacon(implV1)); | |
UpgradeableBeacon(beacon).transferOwnership(msg.sender); | |
proxy1 = address(new BeaconProxy(beacon, "")); | |
proxy2 = address(new BeaconProxy(beacon, "")); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity 0.8.14; | |
contract Caller { | |
address immutable public callee; | |
uint256 public n; | |
constructor(address callee_) { | |
callee = callee_; | |
} | |
function fooDelegateCall(uint256 n_) public { | |
(bool ok, ) = callee.delegatecall(abi.encodeCall(Callee.bar, (n_))); | |
require(ok, "delegate call failed"); | |
} | |
function fooCall(uint256 n_) public { | |
(bool ok, ) = callee.call(abi.encodeCall(Callee.bar, (n_))); | |
require(ok, "call failed"); | |
} | |
} | |
contract Callee { | |
uint256 public n; | |
function bar(uint256 n_) public { | |
n = n_; | |
} | |
} | |
contract Setup { | |
address immutable public caller; | |
address immutable public callee; | |
constructor() { | |
callee = address(new Callee()); | |
caller = address(new Caller(callee)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity 0.8.14; | |
import "https://raw.githubusercontent.com/mudgen/diamond-3-hardhat/main/contracts/Diamond.sol"; | |
import "https://raw.githubusercontent.com/mudgen/diamond-3-hardhat/main/contracts/upgradeInitializers/DiamondInit.sol"; | |
import "https://raw.githubusercontent.com/mudgen/diamond-3-hardhat/main/contracts/facets/DiamondCutFacet.sol"; | |
import "https://raw.githubusercontent.com/mudgen/diamond-3-hardhat/main/contracts/facets/OwnershipFacet.sol"; | |
import "https://raw.githubusercontent.com/mudgen/diamond-3-hardhat/main/contracts/facets/DiamondLoupeFacet.sol"; | |
import "./Facet.sol"; | |
contract Setup { | |
address immutable public diamond; | |
address immutable public facetCut; | |
address immutable public facetLoupe; | |
address immutable public facetOwnership; | |
address immutable public facet1; | |
address immutable public facet2; | |
constructor() { | |
// Deploy facets | |
facetCut = address(new DiamondCutFacet()); | |
address init = address(new DiamondInit()); | |
facetLoupe = address(new DiamondLoupeFacet()); | |
facetOwnership = address(new OwnershipFacet()); | |
// Deploy diamond | |
diamond = address(new Diamond(address(this), facetCut)); | |
// Initialize facets | |
IDiamondCut.FacetCut[] memory cuts = new IDiamondCut.FacetCut[](2); | |
bytes4[] memory loupeSelectors = new bytes4[](5); | |
loupeSelectors[0] = DiamondLoupeFacet.facets.selector; | |
loupeSelectors[1] = DiamondLoupeFacet.facetFunctionSelectors.selector; | |
loupeSelectors[2] = DiamondLoupeFacet.facetAddresses.selector; | |
loupeSelectors[3] = DiamondLoupeFacet.facetAddress.selector; | |
loupeSelectors[4] = DiamondLoupeFacet.supportsInterface.selector; | |
bytes4[] memory ownableSelectors = new bytes4[](2); | |
ownableSelectors[0] = OwnershipFacet.transferOwnership.selector; | |
ownableSelectors[1] = OwnershipFacet.owner.selector; | |
cuts[0] = IDiamondCut.FacetCut(facetLoupe, IDiamondCut.FacetCutAction.Add, loupeSelectors); | |
cuts[1] = IDiamondCut.FacetCut(facetOwnership, IDiamondCut.FacetCutAction.Add, ownableSelectors); | |
DiamondCutFacet(diamond).diamondCut(cuts, init, abi.encodeCall(DiamondInit.init, ())); | |
// Transfer the ownership back to msg.sender | |
OwnershipFacet(diamond).transferOwnership(msg.sender); | |
facet1 = address(new Facet1()); | |
facet2 = address(new Facet2()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity 0.8.14; | |
library LibAppStorage { | |
struct AppStorage { | |
uint256 n; | |
} | |
function diamondStorage() internal pure returns (AppStorage storage ds) { | |
assembly { | |
ds.slot := 0 | |
} | |
} | |
} | |
library LibFacet1 { | |
bytes32 constant storagePosition = keccak256("diamond.storage.LibFacet1"); | |
struct DiamondStorage { | |
uint256 n; | |
} | |
function diamondStorage() internal pure returns (DiamondStorage storage ds) { | |
bytes32 position = storagePosition; | |
assembly { | |
ds.slot := position | |
} | |
} | |
} | |
contract Facet1 { | |
LibAppStorage.AppStorage internal _s; | |
/** ["0x514182b8", "0x3e955225", "0x8c6979df", "0x3f7a0270"] | |
* "514182b8": "getF1N()", | |
* "3e955225": "getN()", | |
* "8c6979df": "setF1N(uint256)", | |
* "3f7a0270": "setN(uint256)" | |
*/ | |
function setN(uint256 n_) public { | |
_s.n = n_; | |
} | |
function getN() public view returns (uint256) { | |
return _s.n; | |
} | |
function setF1N(uint256 n_) public { | |
LibFacet1.DiamondStorage storage s = LibFacet1.diamondStorage(); | |
s.n = n_; | |
} | |
function getF1N() public view returns (uint256) { | |
LibFacet1.DiamondStorage storage s = LibFacet1.diamondStorage(); | |
return s.n; | |
} | |
} | |
library LibFacet2 { | |
bytes32 constant storagePosition = keccak256("diamond.storage.LibFacet2"); | |
struct DiamondStorage { | |
uint256 n; | |
} | |
function diamondStorage() internal pure returns (DiamondStorage storage ds) { | |
bytes32 position = storagePosition; | |
assembly { | |
ds.slot := position | |
} | |
} | |
} | |
contract Facet2 { | |
LibAppStorage.AppStorage internal _s; | |
/** ["0x0d3973c5", "0x53750a05", "0x928b50bf", "0x725cdf69"] | |
* "0d3973c5": "decN()", | |
* "53750a05": "getF2N()", | |
* "928b50bf": "incN()", | |
* "725cdf69": "setF2N(uint256)" | |
*/ | |
function incN() public { | |
_s.n++; | |
} | |
function decN() public { | |
_s.n--; | |
} | |
function setF2N(uint256 n_) public { | |
LibFacet2.DiamondStorage storage s = LibFacet2.diamondStorage(); | |
s.n = n_; | |
} | |
function getF2N() public view returns (uint256) { | |
LibFacet2.DiamondStorage storage s = LibFacet2.diamondStorage(); | |
return s.n; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity 0.8.14; | |
contract ImplementationV1 { | |
uint256 internal _n; | |
function setN(uint256 n_) public { | |
_n = n_; | |
} | |
function getN() public view returns (uint256) { | |
return _n; | |
} | |
} | |
contract ImplementationV2 is ImplementationV1 { | |
function incN() public { | |
_n++; | |
} | |
function decN() public { | |
_n--; | |
} | |
} | |
contract ImplementationV3 { | |
uint256 internal _n; | |
function incN() public { | |
_n++; | |
} | |
function decN() public { | |
_n--; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity 0.8.14; | |
import "https://raw.githubusercontent.com/Instadapp/infinite-proxy/main/contracts/infiniteProxy/proxy.sol"; | |
import {ImplementationV1, ImplementationV3} from "./Implementation.sol"; | |
contract InfiniteProxy is Proxy { | |
constructor(address admin_, address dummyImplementation_) Proxy(admin_, dummyImplementation_) {} | |
} | |
contract Setup { | |
address immutable public proxy; | |
address immutable public implV1; | |
address immutable public implV3; | |
constructor() { | |
implV1 = address(new ImplementationV1()); | |
/** ["0x3e955225", "0x3f7a0270"] | |
* "3e955225": "getN()", | |
* "3f7a0270": "setN(uint256)" | |
*/ | |
implV3 = address(new ImplementationV3()); | |
/** ["0x0d3973c5", "0x928b50bf"] | |
* "0d3973c5": "decN()", | |
* "928b50bf": "incN()" | |
*/ | |
proxy = address(new InfiniteProxy(msg.sender, implV1)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity 0.8.14; | |
import {ImplementationV1 as Implementation} from "./Implementation.sol"; | |
contract Proxy { | |
bytes32 internal constant _IMPLEMENTATION_SLOT = keccak256("proxy.implementation"); | |
constructor(address impl_) { | |
bytes32 slot = _IMPLEMENTATION_SLOT; | |
assembly { | |
sstore(slot, impl_) | |
} | |
} | |
fallback(bytes calldata data) external payable returns (bytes memory) { | |
address impl; | |
bytes32 slot = _IMPLEMENTATION_SLOT; | |
assembly { | |
impl := sload(slot) | |
} | |
(bool ok, bytes memory ret) = impl.delegatecall(data); | |
require(ok, "proxy delegatecall failed"); | |
return ret; | |
} | |
} | |
contract Setup { | |
address immutable public proxy; | |
address immutable public impl; | |
constructor() { | |
impl = address(new Implementation()); | |
proxy = address(new Proxy(impl)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity 0.8.14; | |
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/master/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; | |
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/master/contracts/proxy/transparent/ProxyAdmin.sol"; | |
import {ImplementationV1, ImplementationV2} from "./Implementation.sol"; | |
contract Setup { | |
address immutable public proxy; | |
address immutable public admin; | |
address immutable public implV1; | |
address immutable public implV2; | |
constructor() { | |
implV1 = address(new ImplementationV1()); | |
implV2 = address(new ImplementationV2()); | |
admin = address(new ProxyAdmin()); | |
ProxyAdmin(admin).transferOwnership(msg.sender); | |
proxy = address(new TransparentUpgradeableProxy(implV1, admin, "")); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity 0.8.14; | |
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/master/contracts/proxy/utils/UUPSUpgradeable.sol"; | |
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/master/contracts/proxy/ERC1967/ERC1967Proxy.sol"; | |
import "https://raw.githubusercontent.com/OpenZeppelin/openzeppelin-contracts/master/contracts/access/Ownable.sol"; | |
import {ImplementationV1, ImplementationV2} from "./Implementation.sol"; | |
contract UUPSImplementationV1 is ImplementationV1, UUPSUpgradeable, Ownable { | |
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} | |
function initializeOwnership(address owner_) external { | |
require(owner() == address(0), "Owner initialized"); | |
_transferOwnership(owner_); | |
} | |
} | |
contract UUPSImplementationV2 is ImplementationV2, UUPSUpgradeable, Ownable { | |
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} | |
function initializeOwnership(address owner_) external { | |
require(owner() == address(0), "Owner initialized"); | |
_transferOwnership(owner_); | |
} | |
} | |
contract Setup { | |
address immutable public proxy; | |
address immutable public implV1; | |
address immutable public implV2; | |
constructor() { | |
implV1 = address(new UUPSImplementationV1()); | |
implV2 = address(new UUPSImplementationV2()); | |
proxy = address(new ERC1967Proxy(implV1, abi.encodeCall(UUPSImplementationV1.initializeOwnership, (msg.sender)))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment