Skip to content

Commit

Permalink
Fix failing of scenario and separate out calculation of create 2 addr…
Browse files Browse the repository at this point in the history
…esses
  • Loading branch information
RobinNagpal authored Oct 21, 2024
1 parent 771d6f4 commit c60c008
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 48 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/run-scenarios.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: Run Scenarios
on:
workflow_dispatch:
pull_request:
permissions:
checks: write
jobs:
run-scenarios:
strategy:
Expand Down
14 changes: 14 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ deploy-contracts:
-vvvv \
--sender $(SENDER)

# Compute contracts addresses
compute-contracts-addresses:
@echo "Computing contracts addresses..."
CHAIN_ID=$(CHAIN_ID) forge script forge/script/marketupdates/ComputeContractsAddresses.s.sol:ComputeContractAddresses \
--rpc-url $(RPC_URL) \
--optimize \
--optimizer-runs 200 \
--use $(SOLIDITY_COMPILER_VERSION) \
--evm-version $(EVM_VERSION) \
--via-ir \
-vvvv \
--skip-simulation \
--sender $(SENDER)

# Verifying MarketUpdateTimelock
verify-MarketUpdateTimelock:
@echo "Verifying MarketUpdateTimelock..."
Expand Down
63 changes: 63 additions & 0 deletions forge/script/marketupdates/ComputeContractsAddresses.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@forge-std/src/Script.sol";
import "@forge-std/src/console.sol";
import "@comet-contracts/marketupdates/MarketUpdateTimelock.sol";
import "@comet-contracts/marketupdates/MarketUpdateProposer.sol";
import "@comet-contracts/Configurator.sol";
import "@comet-contracts/CometProxyAdmin.sol";
import "@comet-contracts/marketupdates/MarketAdminPermissionChecker.sol";
import "@comet-contracts/Create2DeployerInterface.sol";
import "./helpers/MarketUpdateAddresses.sol";
import "./helpers/MarketUpdateContractsDeployer.sol";
import "./helpers/ChainAddresses.sol";

contract ComputeContractAddresses is Script {
address public deployedWalletAddress;

address constant public create2DeployerAddress = 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2;

Check notice

Code scanning / Semgrep OSS

Semgrep Finding: compound.solidity.constant-not-in-uppercase Note

A constant name is not in UPPER_CASE like other constant variables.
address constant public ZER0_ADDRESS_MARKET_UPDATE_PROPOSAL_GUARDIAN = address(0);
address constant public ZER0_ADDRESS_MARKET_ADMIN_PAUSE_GUARDIAN = address(0);
address constant public INITIAL_ADDRESS_MARKET_UPDATE_MULTI_SIG = address(0x7e14050080306cd36b47DE61ce604b3a1EC70c4e);


function run() external {
uint256 passedChainId = vm.envUint("CHAIN_ID");

require(block.chainid == passedChainId, "Chain ID mismatch");

Check notice

Code scanning / Semgrep OSS

Semgrep Finding: rules.solidity.performance.use-custom-error-not-require Note

Consider using custom errors as they are more gas efficient while allowing developers
to describe the error in detail using NatSpec.

ChainAddresses.Chain chain = ChainAddresses.getChainBasedOnChainId(passedChainId);
ChainAddresses.ChainAddressesStruct memory chainAddresses = ChainAddresses.getChainAddresses(chain);

console.log("Deploying contracts with sender: ", msg.sender);

uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");

address deployer = vm.rememberKey(deployerPrivateKey);
vm.startBroadcast(deployer);

console.log("Broadcasting transaction with deployer: ", deployer);

bytes32 salt = keccak256(abi.encodePacked(vm.envString("SALT")));

/// Call library function
MarketUpdateContractsDeployer.DeployedContracts memory deployedContracts = MarketUpdateContractsDeployer.calculateContractAddresses(
salt,
msg.sender,
chainAddresses.marketAdmin,
chainAddresses.marketUpdatePauseGuardian,
chainAddresses.marketUpdateProposalGuardian,
chainAddresses.governorTimelockAddress
);

/// Console log deployed contracts
console.log("MarketUpdateTimelock: ", deployedContracts.marketUpdateTimelock);
console.log("MarketUpdateProposer: ", deployedContracts.marketUpdateProposer);
console.log("NewConfiguratorImplementation: ", deployedContracts.newConfiguratorImplementation);
console.log("NewCometProxyAdmin: ", deployedContracts.newCometProxyAdmin);
console.log("MarketAdminPermissionChecker: ", deployedContracts.marketAdminPermissionChecker);

vm.stopBroadcast();
}
}
2 changes: 1 addition & 1 deletion forge/script/marketupdates/DeployContracts.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ contract DeployContracts is Script {
bytes32 salt = keccak256(abi.encodePacked(vm.envString("SALT")));

/// Call library function
MarketUpdateContractsDeployer.DeployedContracts memory deployedContracts = MarketUpdateContractsDeployer._deployContracts(
MarketUpdateContractsDeployer.DeployedContracts memory deployedContracts = MarketUpdateContractsDeployer._prepareAndDeployContracts(
salt,
msg.sender,
chainAddresses.marketAdmin,
Expand Down
182 changes: 139 additions & 43 deletions forge/script/marketupdates/helpers/MarketUpdateContractsDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ library MarketUpdateContractsDeployer {
console.log("Deploying contracts with sender", msg.sender);
vm.startBroadcast(msg.sender);

DeployedContracts memory deployedContracts = _deployContracts(
DeployedContracts memory deployedContracts = _prepareAndDeployContracts(
salt,
msg.sender,
marketUpdateMultiSig,
Expand All @@ -57,33 +57,141 @@ library MarketUpdateContractsDeployer {
return deployedContracts;
}

function _deployContracts(
function _prepareAndDeployContracts(
bytes32 salt,
address msgSender,
address marketUpdateMultiSig,
address marketAdminPauseGuardianAddress,
address marketUpdateProposalGuardianAddress,
address localTimelockAddress
) internal returns (DeployedContracts memory) {
console.log("Deploying contracts with sender", msgSender);
console.log("Preparing contracts with sender", msgSender);

ICreate2Deployer create2Deployer = ICreate2Deployer(create2DeployerAddress);

// Initialize variables to hold computed addresses
address computedMarketUpdateTimelockAddress;
address computedMarketUpdateProposerAddress;
address computedConfiguratorAddress;
address computedMarketAdminPermissionCheckerAddress;
address computedCometProxyAdminAddress;

// Prepare and deploy MarketUpdateTimelock
ContractDeploymentParams memory marketUpdateTimelockParams = getMarketUpdateTimelockParams(msgSender);

computedMarketUpdateTimelockAddress = computeContractAddress(create2Deployer, salt, marketUpdateTimelockParams);

deployContractWithCreate2(create2Deployer, salt, marketUpdateTimelockParams);
// Perform any post-deployment actions
console.log("Current Governor of timelock", MarketUpdateTimelock(payable(computedMarketUpdateTimelockAddress)).governor());

// Prepare and deploy MarketUpdateProposer
ContractDeploymentParams memory marketUpdateProposerParams = getMarketUpdateProposerParams(msgSender, marketUpdateMultiSig, marketUpdateProposalGuardianAddress, computedMarketUpdateTimelockAddress);

computedMarketUpdateProposerAddress = computeContractAddress(create2Deployer, salt, marketUpdateProposerParams);

deployContractWithCreate2(create2Deployer, salt, marketUpdateProposerParams);

// Post-deployment actions
MarketUpdateProposer(computedMarketUpdateProposerAddress).setMarketAdmin(marketUpdateMultiSig);
MarketUpdateProposer(computedMarketUpdateProposerAddress).setProposalGuardian(marketUpdateProposalGuardianAddress);
MarketUpdateProposer(computedMarketUpdateProposerAddress).setGovernor(localTimelockAddress);

MarketUpdateTimelock(payable(computedMarketUpdateTimelockAddress)).setMarketUpdateProposer(computedMarketUpdateProposerAddress);
MarketUpdateTimelock(payable(computedMarketUpdateTimelockAddress)).setGovernor(localTimelockAddress);

// Prepare and deploy Configurator
ContractDeploymentParams memory configuratorParams = getConfiguratorParams();

computedConfiguratorAddress = computeContractAddress(create2Deployer, salt, configuratorParams);

deployContractWithCreate2(create2Deployer, salt, configuratorParams);
// No post-deployment actions

// Prepare and deploy MarketAdminPermissionChecker
ContractDeploymentParams memory marketAdminPermissionCheckerParams = getMarketAdminPermissionCheckerParams(msgSender);

computedMarketAdminPermissionCheckerAddress = computeContractAddress(create2Deployer, salt, marketAdminPermissionCheckerParams);

deployContractWithCreate2(create2Deployer, salt, marketAdminPermissionCheckerParams);

// Post-deployment actions
MarketAdminPermissionChecker(computedMarketAdminPermissionCheckerAddress).setMarketAdmin(computedMarketUpdateTimelockAddress);
MarketAdminPermissionChecker(computedMarketAdminPermissionCheckerAddress).setMarketAdminPauseGuardian(marketAdminPauseGuardianAddress);
MarketAdminPermissionChecker(computedMarketAdminPermissionCheckerAddress).transferOwnership(localTimelockAddress);

// Prepare and deploy CometProxyAdmin
ContractDeploymentParams memory cometProxyAdminParams = getCometProxyAdminParams(msgSender);

computedCometProxyAdminAddress = computeContractAddress(create2Deployer, salt, cometProxyAdminParams);


deployContractWithCreate2(create2Deployer, salt, cometProxyAdminParams);

// Post-deployment actions
CometProxyAdmin(computedCometProxyAdminAddress).setMarketAdminPermissionChecker(MarketAdminPermissionChecker(computedMarketAdminPermissionCheckerAddress));
CometProxyAdmin(computedCometProxyAdminAddress).transferOwnership(localTimelockAddress);

console.log("Owner of cometProxyAdmin: ", CometProxyAdmin(computedCometProxyAdminAddress).owner());


return DeployedContracts({
marketUpdateTimelock: computedMarketUpdateTimelockAddress,
marketUpdateProposer: computedMarketUpdateProposerAddress,
newCometProxyAdmin: computedCometProxyAdminAddress,
newConfiguratorImplementation: computedConfiguratorAddress,
marketAdminPermissionChecker: computedMarketAdminPermissionCheckerAddress
});
}

function calculateContractAddresses(
bytes32 salt,
address msgSender,
address marketUpdateMultiSig,
address marketAdminPauseGuardianAddress,
address marketUpdateProposalGuardianAddress,
address localTimelockAddress
) internal returns (DeployedContracts memory) {

ICreate2Deployer create2Deployer = ICreate2Deployer(create2DeployerAddress);
ContractDeploymentParams memory marketUpdateTimelockParams = getMarketUpdateTimelockParams(msgSender);

address computedMarketUpdateTimelockAddress = computeContractAddress(create2Deployer, salt, marketUpdateTimelockParams);
ContractDeploymentParams memory marketUpdateProposerParams = getMarketUpdateProposerParams(msgSender, marketUpdateMultiSig, marketUpdateProposalGuardianAddress, computedMarketUpdateTimelockAddress);

address computedMarketUpdateProposerAddress = computeContractAddress(create2Deployer, salt, marketUpdateProposerParams);
ContractDeploymentParams memory configuratorParams = getConfiguratorParams();

// Prepare deployment parameters for each contract
ContractDeploymentParams memory marketUpdateTimelockParams = ContractDeploymentParams({
address computedConfiguratorAddress = computeContractAddress(create2Deployer, salt, configuratorParams);
ContractDeploymentParams memory marketAdminPermissionCheckerParams = getMarketAdminPermissionCheckerParams(msgSender);

address computedMarketAdminPermissionCheckerAddress = computeContractAddress(create2Deployer, salt, marketAdminPermissionCheckerParams);

ContractDeploymentParams memory cometProxyAdminParams = getCometProxyAdminParams(msgSender);
address computedCometProxyAdminAddress = computeContractAddress(create2Deployer, salt, cometProxyAdminParams);

return DeployedContracts({
marketUpdateTimelock: computedMarketUpdateTimelockAddress,
marketUpdateProposer: computedMarketUpdateProposerAddress,
newCometProxyAdmin: computedCometProxyAdminAddress,
newConfiguratorImplementation: computedConfiguratorAddress,
marketAdminPermissionChecker: computedMarketAdminPermissionCheckerAddress
});
}


function getMarketUpdateTimelockParams(address msgSender) internal pure returns (ContractDeploymentParams memory) {
return ContractDeploymentParams({
creationCode: type(MarketUpdateTimelock).creationCode,
constructorArgs: abi.encode(msgSender, 2 days), // 2 days
constructorArgs: abi.encode(msgSender, 2 days),
expectedRuntimeCode: type(MarketUpdateTimelock).runtimeCode,
contractName: "MarketUpdateTimelock"
});
}

address computedMarketUpdateTimelockAddress = deployContractWithCreate2(create2Deployer, salt, marketUpdateTimelockParams);

console.log("Current Governor of timelock", MarketUpdateTimelock(payable(computedMarketUpdateTimelockAddress)).governor());

ContractDeploymentParams memory marketUpdateProposerParams = ContractDeploymentParams({
function getMarketUpdateProposerParams(address msgSender, address marketUpdateMultiSig, address marketUpdateProposalGuardianAddress, address computedMarketUpdateTimelockAddress) internal pure returns (ContractDeploymentParams memory) {
return ContractDeploymentParams({
creationCode: type(MarketUpdateProposer).creationCode,
constructorArgs: abi.encode(
msgSender,
Expand All @@ -94,70 +202,58 @@ library MarketUpdateContractsDeployer {
expectedRuntimeCode: type(MarketUpdateProposer).runtimeCode,
contractName: "MarketUpdateProposer"
});
}

address computedMarketUpdateProposerAddress = deployContractWithCreate2(create2Deployer, salt, marketUpdateProposerParams);
MarketUpdateProposer(computedMarketUpdateProposerAddress).setMarketAdmin(marketUpdateMultiSig);
MarketUpdateProposer(computedMarketUpdateProposerAddress).setProposalGuardian(marketUpdateProposalGuardianAddress);
MarketUpdateProposer(computedMarketUpdateProposerAddress).setGovernor(localTimelockAddress);

MarketUpdateTimelock(payable(computedMarketUpdateTimelockAddress)).setMarketUpdateProposer(computedMarketUpdateProposerAddress);
MarketUpdateTimelock(payable(computedMarketUpdateTimelockAddress)).setGovernor(localTimelockAddress);

ContractDeploymentParams memory configuratorParams = ContractDeploymentParams({
function getConfiguratorParams() internal pure returns (ContractDeploymentParams memory) {
return ContractDeploymentParams({
creationCode: type(Configurator).creationCode,
constructorArgs: "",
expectedRuntimeCode: type(Configurator).runtimeCode,
contractName: "Configurator"
});
}

address computedConfiguratorAddress = deployContractWithCreate2(create2Deployer, salt, configuratorParams);

ContractDeploymentParams memory marketAdminPermissionCheckerParams = ContractDeploymentParams({
function getMarketAdminPermissionCheckerParams(address msgSender) internal pure returns (ContractDeploymentParams memory) {
return ContractDeploymentParams({
creationCode: type(MarketAdminPermissionChecker).creationCode,
constructorArgs: abi.encode(msgSender, INITIAL_ADDRESS_MARKET_UPDATE_MULTI_SIG, address(0)),
expectedRuntimeCode: type(MarketAdminPermissionChecker).runtimeCode,
contractName: "MarketAdminPermissionChecker"
});
}

address computedMarketAdminPermissionCheckerAddress = deployContractWithCreate2(create2Deployer, salt, marketAdminPermissionCheckerParams);
MarketAdminPermissionChecker(computedMarketAdminPermissionCheckerAddress).setMarketAdmin(computedMarketUpdateTimelockAddress);
MarketAdminPermissionChecker(computedMarketAdminPermissionCheckerAddress).setMarketAdminPauseGuardian(marketAdminPauseGuardianAddress);

MarketAdminPermissionChecker(computedMarketAdminPermissionCheckerAddress).transferOwnership(localTimelockAddress);

ContractDeploymentParams memory cometProxyAdminParams = ContractDeploymentParams({
function getCometProxyAdminParams(address msgSender) internal pure returns (ContractDeploymentParams memory) {
return ContractDeploymentParams({
creationCode: type(CometProxyAdmin).creationCode,
constructorArgs: abi.encode(msgSender),
expectedRuntimeCode: type(CometProxyAdmin).runtimeCode,
contractName: "CometProxyAdmin"
});

address computedCometProxyAdminAddress = deployContractWithCreate2(create2Deployer, salt, cometProxyAdminParams);
CometProxyAdmin(computedCometProxyAdminAddress).setMarketAdminPermissionChecker(MarketAdminPermissionChecker(computedMarketAdminPermissionCheckerAddress));
CometProxyAdmin(computedCometProxyAdminAddress).transferOwnership(localTimelockAddress);

console.log("Owner of cometProxyAdmin: ", CometProxyAdmin(computedCometProxyAdminAddress).owner());

return DeployedContracts({
marketUpdateTimelock: computedMarketUpdateTimelockAddress,
marketUpdateProposer: computedMarketUpdateProposerAddress,
newCometProxyAdmin: computedCometProxyAdminAddress,
newConfiguratorImplementation: computedConfiguratorAddress,
marketAdminPermissionChecker: computedMarketAdminPermissionCheckerAddress
});
}


function deployContractWithCreate2(
ICreate2Deployer create2Deployer,
bytes32 salt,
ContractDeploymentParams memory params
) internal returns (address) {
address computedAddress = computeContractAddress(create2Deployer, salt, params);
bytes memory bytecode = abi.encodePacked(params.creationCode, params.constructorArgs);
address computedAddress = create2Deployer.computeAddress(salt, keccak256(bytecode));
checkOrDeployAndCompareBytecodes(create2Deployer, salt, bytecode, computedAddress, params.expectedRuntimeCode);
return computedAddress;
}

function computeContractAddress(
ICreate2Deployer create2Deployer,
bytes32 salt,
ContractDeploymentParams memory params
) internal view returns (address) {
bytes memory bytecode = abi.encodePacked(params.creationCode, params.constructorArgs);
address computedAddress = create2Deployer.computeAddress(salt, keccak256(bytecode));
return computedAddress;
}

function checkOrDeployAndCompareBytecodes(
ICreate2Deployer create2Deployer,
bytes32 salt,
Expand Down
4 changes: 3 additions & 1 deletion plugins/scenario/utils/TokenSourcer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface SourceTokenParameters {
asset: string;
address: string;
blacklist: string[];
blockNumber?: number;
}

export async function fetchQuery(
Expand Down Expand Up @@ -55,14 +56,15 @@ export async function sourceTokens({
asset,
address,
blacklist,
blockNumber,
}: SourceTokenParameters) {
let amount = BigNumber.from(amount_);
if (amount.isZero()) {
return;
} else if (amount.isNegative()) {
await removeTokens(dm, amount.abs(), asset, address);
} else {
await addTokens(dm, amount, asset, address, [address].concat(blacklist));
await addTokens(dm, amount, asset, address, [address].concat(blacklist), blockNumber);
}
}

Expand Down
7 changes: 6 additions & 1 deletion scenario/RewardsScenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,12 @@ async function testScalingReward(properties: CometProperties, context: CometCont
[albert.address]
);
await newRewards.connect(albert.signer).setRewardConfigWithMultiplier(comet.address, rewardTokenAddress, multiplier);
await context.sourceTokens(exp(1_000, rewardDecimals), rewardTokenAddress, newRewards.address);
await context.sourceTokens(
100000, // maximum amount which can be sourced from transaction logs
rewardTokenAddress, // CometAsset
newRewards.address, // Recipient's address
2751700 // Block number to start searching for transfer event
);

await baseAsset.approve(albert, comet.address);
await albert.safeSupplyAsset({ asset: baseAssetAddress, amount: 100n * baseScale });
Expand Down
Loading

0 comments on commit c60c008

Please sign in to comment.