Skip to content

Commit

Permalink
feat: add the deployment of the libraries from the
Browse files Browse the repository at this point in the history
sismo-connect-solidity repository
  • Loading branch information
yum0e committed Aug 17, 2023
1 parent 6690c3c commit 44e787b
Show file tree
Hide file tree
Showing 9 changed files with 404 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ lib
.hardhat/contracts

# Deployment files
**deployments/test.json
**deployments/test/*.json
**/tmp/*
!**/tmp/example.json
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ optimizer_runs = 1000000
verbosity = 1
libs = ["lib"]
fs_permissions = [{ access = "read-write", path = "./"}]
ffi = true

bytecode_hash="none"
solc_version="0.8.19"
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"scripts": {
"test": "forge test",
"save-deployments": "./script/bash/save-deployments.sh",
"lint": "prettier --write **.sol"
}
}
126 changes: 126 additions & 0 deletions script/BaseConfig.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import {Script} from "forge-std/Script.sol";
import "forge-std/console.sol";
import "@openzeppelin/contracts/utils/Strings.sol";

struct DeploymentConfig {
address authRequestBuilder;
address claimRequestBuilder;
address requestBuilder;
address signatureBuilder;
}

contract BaseDeploymentConfig is Script {
DeploymentConfig public config;

string public _chainName;
bool public _checkIfEmpty;

address immutable SISMO_ADDRESSES_PROVIDER_V2 = 0x3Cd5334eB64ebBd4003b72022CC25465f1BFcEe6;
address immutable ZERO_ADDRESS = 0x0000000000000000000000000000000000000000;

error ChainNameNotFound(string chainName);

function _setConfig(string memory chainName) internal {
if (
_compareStrings(chainName, "mainnet") ||
_compareStrings(chainName, "gnosis") ||
_compareStrings(chainName, "polygon") ||
_compareStrings(chainName, "optimism") ||
_compareStrings(chainName, "arbitrum-one") ||
_compareStrings(chainName, "testnet-goerli") ||
_compareStrings(chainName, "testnet-sepolia") ||
_compareStrings(chainName, "testnet-mumbai") ||
_compareStrings(chainName, "optimism-goerli") ||
_compareStrings(chainName, "arbitrum-goerli") ||
_compareStrings(chainName, "scroll-testnet-goerli") ||
_compareStrings(chainName, "staging-goerli") ||
_compareStrings(chainName, "staging-mumbai")
) {
config = _readDeploymentConfig(
string.concat(vm.projectRoot(), "/deployments/", chainName, ".json")
);
} else if (_compareStrings(chainName, "test")) {
config = DeploymentConfig(address(0), address(0), address(0), address(0));
} else {
revert ChainNameNotFound(chainName);
}
}

function _readDeploymentConfig(
string memory filePath
) internal view returns (DeploymentConfig memory) {
string memory file = _tryReadingFile(filePath);
return
DeploymentConfig({
authRequestBuilder: _tryReadingAddressFromFileAtKey(file, ".authRequestBuilder"),
claimRequestBuilder: _tryReadingAddressFromFileAtKey(file, ".claimRequestBuilder"),
requestBuilder: _tryReadingAddressFromFileAtKey(file, ".requestBuilder"),
signatureBuilder: _tryReadingAddressFromFileAtKey(file, ".signatureBuilder")
});
}

function _tryReadingFile(string memory filePath) internal view returns (string memory) {
try vm.readFile(filePath) returns (string memory file) {
return file;
} catch {
return "";
}
}

function _tryReadingAddressFromFileAtKey(
string memory file,
string memory key
) internal view returns (address) {
try vm.parseJson(file, key) returns (bytes memory encodedAddress) {
return
keccak256(encodedAddress) == keccak256(abi.encodePacked(("")))
? address(0)
: abi.decode(encodedAddress, (address));
} catch {
return ZERO_ADDRESS;
}
}

function _saveDeploymentConfig(string memory chainName) internal {
_createFolderIfItDoesNotExists(string.concat(vm.projectRoot(), "/deployments"));
_createFolderIfItDoesNotExists(string.concat(vm.projectRoot(), "/deployments/tmp"));
_createFolderIfItDoesNotExists(string.concat(vm.projectRoot(), "/deployments/tmp/", chainName));

vm.serializeAddress(chainName, "authRequestBuilder", address(config.authRequestBuilder));
vm.serializeAddress(chainName, "claimRequestBuilder", address(config.claimRequestBuilder));
vm.serializeAddress(chainName, "requestBuilder", address(config.requestBuilder));
string memory finalJson = vm.serializeAddress(
chainName,
"signatureBuilder",
address(config.signatureBuilder)
);

vm.writeJson(
finalJson,
string.concat(
vm.projectRoot(),
"/deployments/tmp/",
chainName,
"/logs",
"-",
Strings.toString(block.timestamp),
".json"
)
);
}

function _createFolderIfItDoesNotExists(string memory folderPath) internal {
string[] memory inputs = new string[](3);
inputs[0] = "mkdir";
inputs[1] = "-p";
inputs[2] = folderPath;
vm.ffi(inputs);
}

function _compareStrings(string memory a, string memory b) internal pure returns (bool) {
return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
}
}
173 changes: 173 additions & 0 deletions script/DeployLibraries.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.17;

import "forge-std/Script.sol";
import "forge-std/console.sol";
import {BaseDeploymentConfig, DeploymentConfig} from "script/BaseConfig.sol";
import {IAddressesProvider} from "src/interfaces/IAddressesProvider.sol";
import {AuthRequestBuilder} from "src/utils/AuthRequestBuilder.sol";
import {ClaimRequestBuilder} from "src/utils/ClaimRequestBuilder.sol";
import {SignatureBuilder} from "src/utils/SignatureBuilder.sol";
import {RequestBuilder} from "src/utils/RequestBuilder.sol";

/**
* @title DeployLibraries Script
* @notice To test this script locally, run:
* in a first terminal: `anvil fork-url https://rpc.ankr.com/polygon_mumbai`
* in a second terminal: `cast rpc anvil_impersonateAccount`
* and finally: `CHAIN_NAME=test forge script DeployLibraries --rpc-url localhost --sender 0xbb8fca8f2381cfeede5d7541d7bf76343ef6c67b --unlocked -vvvv`
* You should see that the libraries are being deployed and successfully set in the AddressesProvider contract.
* You can then run the `yarn save-deployments` command to save the deployment addresses in the `deployments` folder. You will see the libraries addresses in the `deployments/test/logs-*.json` file.
*/

contract DeployLibraries is Script, BaseDeploymentConfig {
struct DeployedLibraries {
AuthRequestBuilder authRequestBuilder;
ClaimRequestBuilder claimRequestBuilder;
SignatureBuilder signatureBuilder;
RequestBuilder requestBuilder;
}

struct DeployedLibrary {
address addr;
string name;
}

// useful variables to set libraries addresses in AddressesProvider in batch
address[] public contractAddresses;
string[] public contractNames;

function run() public {
runFor(vm.envString("CHAIN_NAME"));
}

function runFor(string memory chainName) public returns (DeploymentConfig memory) {
console.log("Run for CHAIN_NAME:", chainName);
console.log("Deployer:", msg.sender);

vm.startBroadcast();

_setConfig({chainName: chainName});

// deploy external libraries
DeployedLibraries memory deployedLibraries;
deployedLibraries.authRequestBuilder = _deployAuthRequestBuilder();
deployedLibraries.claimRequestBuilder = _deployClaimRequestBuilder();
deployedLibraries.signatureBuilder = _deploySignatureBuilder();
deployedLibraries.requestBuilder = _deployRequestBuilder();

// associate libraries addresses to names
DeployedLibrary[] memory deployedLibrariesArray = new DeployedLibrary[](4);
deployedLibrariesArray[0] = DeployedLibrary({
addr: address(deployedLibraries.authRequestBuilder),
name: "authRequestBuilder-v1.1"
});
deployedLibrariesArray[1] = DeployedLibrary({
addr: address(deployedLibraries.claimRequestBuilder),
name: "claimRequestBuilder-v1.1"
});
deployedLibrariesArray[2] = DeployedLibrary({
addr: address(deployedLibraries.signatureBuilder),
name: "signatureBuilder-v1.1"
});
deployedLibrariesArray[3] = DeployedLibrary({
addr: address(deployedLibraries.requestBuilder),
name: "requestBuilder-v1.1"
});

// update addresses provider with deployed libraries addresses
_setLibrariesAddresses(deployedLibrariesArray);

// update deployment config with deployed libraries addresses
// and save it in `deployments` folder
// only for a successful broadcast
config = DeploymentConfig({
authRequestBuilder: address(deployedLibraries.authRequestBuilder),
claimRequestBuilder: address(deployedLibraries.claimRequestBuilder),
signatureBuilder: address(deployedLibraries.signatureBuilder),
requestBuilder: address(deployedLibraries.requestBuilder)
});
vm.stopBroadcast();
_saveDeploymentConfig(chainName);

return config;
}

function _deployAuthRequestBuilder() private returns (AuthRequestBuilder) {
address authRequestBuilderAddress = config.authRequestBuilder;
if (authRequestBuilderAddress != address(0)) {
console.log("Using existing authrequestBuilder:", authRequestBuilderAddress);
return AuthRequestBuilder(authRequestBuilderAddress);
}
AuthRequestBuilder authRequestBuilder = new AuthRequestBuilder();
console.log("authRequestBuilder Deployed:", address(authRequestBuilder));
return authRequestBuilder;
}

function _deployClaimRequestBuilder() private returns (ClaimRequestBuilder) {
address claimRequestBuilderAddress = config.claimRequestBuilder;
if (claimRequestBuilderAddress != address(0)) {
console.log("Using existing claimRequestBuilder:", claimRequestBuilderAddress);
return ClaimRequestBuilder(claimRequestBuilderAddress);
}
ClaimRequestBuilder claimRequestBuilder = new ClaimRequestBuilder();
console.log("claimRequestBuilder Deployed:", address(claimRequestBuilder));
return claimRequestBuilder;
}

function _deploySignatureBuilder() private returns (SignatureBuilder) {
address signatureBuilderAddress = config.signatureBuilder;
if (signatureBuilderAddress != address(0)) {
console.log("Using existing signatureBuilder:", signatureBuilderAddress);
return SignatureBuilder(signatureBuilderAddress);
}
SignatureBuilder signatureBuilder = new SignatureBuilder();
console.log("signatureBuilder Deployed:", address(signatureBuilder));
return signatureBuilder;
}

function _deployRequestBuilder() private returns (RequestBuilder) {
address requestBuilderAddress = config.requestBuilder;
if (requestBuilderAddress != address(0)) {
console.log("Using existing requestBuilder:", requestBuilderAddress);
return RequestBuilder(requestBuilderAddress);
}
RequestBuilder requestBuilder = new RequestBuilder();
console.log("requestBuilder Deployed:", address(requestBuilder));
return requestBuilder;
}

function _setLibrariesAddresses(DeployedLibrary[] memory deployedLibrariesArray) private {
console.log("== Updating Addresses Provider ==");
IAddressesProvider sismoAddressProvider = IAddressesProvider(SISMO_ADDRESSES_PROVIDER_V2);

for (uint256 i = 0; i < deployedLibrariesArray.length; i++) {
DeployedLibrary memory deployedLibrary = deployedLibrariesArray[i];
address currentContractAddress = sismoAddressProvider.get(deployedLibrary.name);

if (currentContractAddress != deployedLibrary.addr) {
console.log(
"current contract address for",
deployedLibrary.name,
"is different. Updating address to",
deployedLibrary.addr
);
// save address to update in batch after
contractAddresses.push(deployedLibrary.addr);
contractNames.push(deployedLibrary.name);
} else {
console.log(
"current contract address for",
deployedLibrary.name,
"is already the expected one. skipping update"
);
}
}

if (contractAddresses.length > 0) {
console.log("Updating Addresses Provider in batch...");
sismoAddressProvider.setBatch(contractAddresses, contractNames);
}
}
}
25 changes: 25 additions & 0 deletions script/bash/save-deployments.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

source_folder="$PWD/deployments/tmp"
destination_root="$PWD/deployments"

# Find all subfolders containing JSON files and process them
find "$source_folder" -type f -name "*.json" | while read -r json_file; do
subfolder=$(dirname "$json_file")
subfolder_name=$(basename "$subfolder")
destination_folder="$destination_root/$subfolder_name"

# Create the destination folder after deleting the previous one if it exists
if [ -d "$destination_folder" ]; then rm -Rf $destination_folder; fi
mkdir "$destination_folder"

# Find the latest JSON file in the subfolder
latest_file=$(ls -t "$subfolder"/*.json | head -n 1)

if [ -n "$latest_file" ]; then
# Copy the latest JSON file to the destination folder to keep track of the latest deployment
cp "$latest_file" "$destination_folder"
else
echo "No matching files found in $subfolder_name."
fi
done
14 changes: 7 additions & 7 deletions test/BaseTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ contract BaseTest is Test {
address immutable user1 = vm.addr(1);
address immutable user2 = vm.addr(2);
address immutable owner = vm.addr(3);
address immutable sismoAddressProviderV2 = 0x3Cd5334eB64ebBd4003b72022CC25465f1BFcEe6;
address public immutable SISMO_ADDRESSES_PROVIDER_V2 = 0x3Cd5334eB64ebBd4003b72022CC25465f1BFcEe6;

SismoConnectVerifierMock sismoConnectVerifier;

Expand All @@ -34,25 +34,25 @@ contract BaseTest is Test {
signatureBuilder = new SignatureBuilder();
requestBuilder = new RequestBuilder();

vm.etch(sismoAddressProviderV2, address(addressesProviderMock).code);
vm.etch(SISMO_ADDRESSES_PROVIDER_V2, address(addressesProviderMock).code);

IAddressesProvider(sismoAddressProviderV2).set(
IAddressesProvider(SISMO_ADDRESSES_PROVIDER_V2).set(
address(sismoConnectVerifier),
string("sismoConnectVerifier-v1.2")
);
IAddressesProvider(sismoAddressProviderV2).set(
IAddressesProvider(SISMO_ADDRESSES_PROVIDER_V2).set(
address(authRequestBuilder),
string("authRequestBuilder-v1.1")
);
IAddressesProvider(sismoAddressProviderV2).set(
IAddressesProvider(SISMO_ADDRESSES_PROVIDER_V2).set(
address(claimRequestBuilder),
string("claimRequestBuilder-v1.1")
);
IAddressesProvider(sismoAddressProviderV2).set(
IAddressesProvider(SISMO_ADDRESSES_PROVIDER_V2).set(
address(signatureBuilder),
string("signatureBuilder-v1.1")
);
IAddressesProvider(sismoAddressProviderV2).set(
IAddressesProvider(SISMO_ADDRESSES_PROVIDER_V2).set(
address(requestBuilder),
string("requestBuilder-v1.1")
);
Expand Down
Loading

0 comments on commit 44e787b

Please sign in to comment.