Skip to content

Instantly share code, notes, and snippets.

@hihiben
Created June 7, 2022 11:24
Show Gist options
  • Save hihiben/40ec54959994e4c748b04041fddef671 to your computer and use it in GitHub Desktop.
Save hihiben/40ec54959994e4c748b04041fddef671 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=
// 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, ""));
}
}
// 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));
}
}
// 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());
}
}
// 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;
}
}
// 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--;
}
}
// 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));
}
}
// 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));
}
}
// 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, ""));
}
}
// 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