Skip to content

Commit

Permalink
Move ScriptUtils from aave-helpers (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
kyzia551 authored Jul 29, 2024
1 parent 9e12156 commit 58c5243
Showing 1 changed file with 156 additions and 0 deletions.
156 changes: 156 additions & 0 deletions src/contracts/utils/ScriptUtils.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Script} from 'forge-std/Script.sol';
import {ChainIds} from './ChainHelpers.sol';

/**
* Helper contract to enforce correct chain selection in scripts
*/
abstract contract WithChainIdValidation is Script {
constructor(uint256 chainId) {
require(block.chainid == chainId, 'CHAIN_ID_MISMATCH');
}

modifier broadcast() {
vm.startBroadcast();
_;
vm.stopBroadcast();
}
}

abstract contract EthereumScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.MAINNET) {}
}

abstract contract OptimismScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.OPTIMISM) {}
}

abstract contract ArbitrumScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.ARBITRUM) {}
}

abstract contract PolygonScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.POLYGON) {}
}

abstract contract AvalancheScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.AVALANCHE) {}
}

abstract contract FantomScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.FANTOM) {}
}

abstract contract HarmonyScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.HARMONY) {}
}

abstract contract MetisScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.METIS) {}
}

abstract contract BaseScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.BASE) {}
}

abstract contract BNBScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.BNB) {}
}

abstract contract GnosisScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.GNOSIS) {}
}

abstract contract ScrollScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.SCROLL) {}
}

abstract contract PolygonZkEvmScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.ZK_EVM) {}
}

abstract contract SepoliaScript is WithChainIdValidation {
constructor() WithChainIdValidation(ChainIds.SEPOLIA) {}
}

library Create2Utils {
// https://github.com/safe-global/safe-singleton-factory
address public constant CREATE2_FACTORY = 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7;

function create2Deploy(
bytes32 salt,
bytes memory bytecode,
bytes memory arguments
) internal returns (address) {
if (isContractDeployed(CREATE2_FACTORY) == false) {
revert('MISSING_CREATE2_FACTORY');
}
address computed = computeCreate2Address(salt, bytecode, arguments);

if (isContractDeployed(computed)) {
return computed;
} else {
bytes memory creationBytecode = abi.encodePacked(salt, abi.encodePacked(bytecode, arguments));
bytes memory returnData;
(, returnData) = CREATE2_FACTORY.call(creationBytecode);
address deployedAt = address(uint160(bytes20(returnData)));
require(deployedAt == computed, 'failure at create2 address derivation');
return deployedAt;
}
}

function create2Deploy(bytes32 salt, bytes memory bytecode) internal returns (address) {
if (isContractDeployed(CREATE2_FACTORY) == false) {
revert('MISSING_CREATE2_FACTORY');
}
address computed = computeCreate2Address(salt, bytecode);

if (isContractDeployed(computed)) {
return computed;
} else {
bytes memory creationBytecode = abi.encodePacked(salt, bytecode);
bytes memory returnData;
(, returnData) = CREATE2_FACTORY.call(creationBytecode);
address deployedAt = address(uint160(bytes20(returnData)));
require(deployedAt == computed, 'failure at create2 address derivation');
return deployedAt;
}
}

function isContractDeployed(address _addr) internal view returns (bool isContract) {
return (_addr.code.length > 0);
}

function computeCreate2Address(bytes32 salt, bytes32 initcodeHash)
internal
pure
returns (address)
{
return
addressFromLast20Bytes(
keccak256(abi.encodePacked(bytes1(0xff), CREATE2_FACTORY, salt, initcodeHash))
);
}

function computeCreate2Address(bytes32 salt, bytes memory bytecode)
internal
pure
returns (address)
{
return computeCreate2Address(salt, keccak256(abi.encodePacked(bytecode)));
}

function computeCreate2Address(
bytes32 salt,
bytes memory bytecode,
bytes memory arguments
) internal pure returns (address) {
return computeCreate2Address(salt, keccak256(abi.encodePacked(bytecode, arguments)));
}

function addressFromLast20Bytes(bytes32 bytesValue) internal pure returns (address) {
return address(uint160(uint256(bytesValue)));
}
}

0 comments on commit 58c5243

Please sign in to comment.