-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity >=0.8.23 <0.9.0; | ||
|
||
import {Script} from "forge-std/Script.sol"; | ||
import {console2} from "forge-std/console2.sol"; | ||
|
||
abstract contract DeployBaseScript is Script { | ||
address internal constant FACTORY = 0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed; | ||
address internal constant DS_IMPL = 0xfC7C29C1f869C6DB5933235C8540Ff4526B26f69; | ||
address internal constant TDS_IMPL = 0x8E9Eb7f019068f42E075f0a985D8A29596C82ED4; | ||
|
||
constructor() { | ||
require(getDocumentStoreSalt() != getTransferableDocumentStoreSalt(), "Salts must be different"); | ||
} | ||
|
||
function getSaltEntropy(string memory entropyName) internal view returns (bytes11) { | ||
bytes11 entropy = bytes11(vm.envOr({name: entropyName, defaultValue: bytes("")})); | ||
require(entropy != bytes11(0), "Salt entropy not set"); | ||
|
||
return entropy; | ||
} | ||
|
||
function getSalt(bytes11 entropy) internal view returns (bytes32 salt) { | ||
require(entropy != bytes11(0), "Salt entropy not be zero"); | ||
|
||
address deployer = vm.envOr({name: "DEPLOYER_ADDRESS", defaultValue: address(0)}); | ||
require(deployer != address(0), "Deployer address not set"); | ||
|
||
bytes20 deployerBytes = bytes20(deployer); | ||
|
||
salt = bytes32(abi.encodePacked(deployerBytes, bytes1(0x00), entropy)); | ||
} | ||
|
||
function getDocumentStoreSalt() internal view returns (bytes32 salt) { | ||
bytes11 entropy = getSaltEntropy("SALT_DOCUMENT_STORE"); | ||
salt = getSalt(entropy); | ||
} | ||
|
||
function getTransferableDocumentStoreSalt() internal view returns (bytes32 salt) { | ||
bytes11 entropy = getSaltEntropy("SALT_TRANSFERABLE_DOCUMENT_STORE"); | ||
salt = getSalt(entropy); | ||
} | ||
|
||
function dsImplExists() internal view returns (bool) { | ||
return _exists(DS_IMPL); | ||
} | ||
|
||
function tdsImplExists() internal view returns (bool) { | ||
return _exists(TDS_IMPL); | ||
} | ||
|
||
function computeAddr(bytes32 salt) internal view returns (address) { | ||
bytes32 guardedSalt = _hash(bytes32(uint256(uint160(msg.sender))), salt); | ||
(bool ok, bytes memory data) = FACTORY.staticcall( | ||
abi.encodeWithSignature("computeCreate3Address(bytes32)", guardedSalt) | ||
); | ||
require(ok, "Error compute DocumentStoreInitializable address"); | ||
return abi.decode(data, (address)); | ||
} | ||
|
||
function deploy(bytes32 salt, bytes memory initCode) internal returns (address) { | ||
(bool ok, bytes memory data) = FACTORY.call( | ||
abi.encodeWithSignature("deployCreate3(bytes32,bytes)", salt, initCode) | ||
); | ||
require(ok, "Deployment failed"); | ||
|
||
return abi.decode(data, (address)); | ||
} | ||
|
||
function clone(address impl, bytes memory initData) internal returns (address) { | ||
(bool ok, bytes memory data) = FACTORY.call( | ||
abi.encodeWithSignature("deployCreate2Clone(address,bytes)", impl, initData) | ||
); | ||
require(ok, "Clone deployment failed"); | ||
|
||
return abi.decode(data, (address)); | ||
} | ||
|
||
function _hash(bytes32 a, bytes32 b) internal pure returns (bytes32 hash) { | ||
assembly ("memory-safe") { | ||
mstore(0x00, a) | ||
mstore(0x20, b) | ||
hash := keccak256(0x00, 0x40) | ||
} | ||
} | ||
|
||
function _exists(address addr) internal view returns (bool) { | ||
uint256 size; | ||
assembly { | ||
size := extcodesize(addr) | ||
} | ||
return size > 0; | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity >=0.8.23 <0.9.0; | ||
|
||
import "./DeployBase.s.sol"; | ||
import "../src/DocumentStore.sol"; | ||
|
||
contract DocumentStoreScript is DeployBaseScript { | ||
function run(string memory name, address admin) public returns (DocumentStore ds) { | ||
_requireParams(name, admin); | ||
|
||
console2.log("DocumentStore Name: ", name); | ||
console2.log("DocumentStore Admin: ", admin); | ||
|
||
if (dsImplExists()) { | ||
bytes memory initData = abi.encodeWithSignature("initialize(string,address)", name, admin); | ||
|
||
vm.broadcast(); | ||
address dsAddr = clone(DS_IMPL, initData); | ||
|
||
ds = DocumentStore(dsAddr); | ||
} else { | ||
vm.broadcast(); | ||
ds = new DocumentStore(name, admin); | ||
} | ||
} | ||
|
||
function _requireParams(string memory name, address admin) private pure { | ||
require(bytes(name).length > 0, "Name is required"); | ||
require(admin != address(0), "Admin address is required"); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity >=0.8.23 <0.9.0; | ||
|
||
import "./DeployBase.s.sol"; | ||
import "../src/initializables/DocumentStoreInitializable.sol"; | ||
|
||
contract DocumentStoreInitializableScript is DeployBaseScript { | ||
function run() public returns (DocumentStoreInitializable documentStore) { | ||
require(!dsImplExists(), "DocumentStoreInitializable already exists"); | ||
|
||
bytes memory initCode = abi.encodePacked(type(DocumentStoreInitializable).creationCode); | ||
|
||
bytes32 dsSalt = getDocumentStoreSalt(); | ||
|
||
address computedAddr = computeAddr(dsSalt); | ||
require(computedAddr == DS_IMPL, "Bad deployment address"); | ||
|
||
vm.broadcast(); | ||
address dsAddr = deploy(dsSalt, initCode); | ||
|
||
documentStore = DocumentStoreInitializable(dsAddr); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity >=0.8.23 <0.9.0; | ||
|
||
import "./DeployBase.s.sol"; | ||
import "../src/OwnableDocumentStore.sol"; | ||
|
||
contract OwnableDocumentStoreScript is DeployBaseScript { | ||
function run(string memory name, string memory symbol, address admin) public returns (OwnableDocumentStore ds) { | ||
_requireParams(name, symbol, admin); | ||
|
||
console2.log("OwnableDocumentStore Name: ", name); | ||
console2.log("OwnableDocumentStore Symbol: ", symbol); | ||
console2.log("OwnableDocumentStore Admin: ", admin); | ||
|
||
if (tdsImplExists()) { | ||
bytes memory initData = abi.encodeWithSignature("initialize(string,string,address)", name, symbol, admin); | ||
|
||
vm.broadcast(); | ||
address dsAddr = clone(TDS_IMPL, initData); | ||
|
||
ds = OwnableDocumentStore(dsAddr); | ||
} else { | ||
vm.broadcast(); | ||
ds = new OwnableDocumentStore(name, symbol, admin); | ||
} | ||
} | ||
|
||
function _requireParams(string memory name, string memory symbol, address admin) private pure { | ||
require(bytes(name).length > 0, "Name is required"); | ||
require(bytes(symbol).length > 0, "Symbol is required"); | ||
require(admin != address(0), "Admin address is required"); | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// SPDX-License-Identifier: Apache-2.0 | ||
pragma solidity >=0.8.23 <0.9.0; | ||
|
||
import "./DeployBase.s.sol"; | ||
import "../src/initializables/OwnableDocumentStoreInitializable.sol"; | ||
|
||
contract OwnableDocumentStoreInitializableScript is DeployBaseScript { | ||
function run() public returns (OwnableDocumentStoreInitializable documentStore) { | ||
require(!dsImplExists(), "OwnableDocumentStoreInitializable already exists"); | ||
|
||
bytes memory initCode = abi.encodePacked(type(OwnableDocumentStoreInitializable).creationCode); | ||
|
||
bytes32 dsSalt = getTransferableDocumentStoreSalt(); | ||
|
||
address computedAddr = computeAddr(dsSalt); | ||
require(computedAddr == TDS_IMPL, "Bad deployment address"); | ||
|
||
vm.broadcast(); | ||
address dsAddr = deploy(dsSalt, initCode); | ||
|
||
documentStore = OwnableDocumentStoreInitializable(dsAddr); | ||
} | ||
} |