Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some workarounds for GovV3 templating #237

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions src/GovV3Playground.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 {WithChainIdValidation, EthereumScript} from './ScriptUtils.sol';
import {GovV3Helpers, IPayloadsControllerCore} from './GovV3Helpers.sol';

contract LetMeJustHaveSome {
string public name = 'some';
}

abstract contract WithChainIdValidationAndPayloads is WithChainIdValidation {
function getPayloads() public view virtual returns (bytes[] memory);
}

abstract contract DeployPayloads is WithChainIdValidationAndPayloads {
function run() external broadcast {
bytes[] memory payloadsCode = getPayloads();

// deploy payloads
address[] memory payloadsAddresses = new address[](payloadsCode.length);
for (uint256 i = 0; i < payloadsCode.length; i++) {
payloadsAddresses[i] = GovV3Helpers.deployDeterministic(payloadsCode[i]);
}

// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](payloadsCode.length);
for (uint256 i = 0; i < payloadsCode.length; i++) {
actions[i] = GovV3Helpers.buildAction(payloadsAddresses[i]);
}

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

abstract contract DeployPayloadSimple is DeployPayloads {
bytes public payloadCode;

constructor(bytes memory code) {
payloadCode = code;
}

function getPayloads() public view override returns (bytes[] memory) {
bytes[] memory payloadsCode = new bytes[](1);
payloadsCode[0] = payloadCode;
return payloadsCode;
}
}

contract DeploySomeSimple is
DeployPayloadSimple(type(LetMeJustHaveSome).creationCode),
EthereumScript
{}

contract DeploySomeMany is DeployPayloads, EthereumScript {
function getPayloads() public view override returns (bytes[] memory) {
bytes[] memory payloadsCode = new bytes[](2);
payloadsCode[0] = type(LetMeJustHaveSome).creationCode;
payloadsCode[1] = type(LetMeJustHaveSome).creationCode;
return payloadsCode;
}
}
119 changes: 119 additions & 0 deletions src/GovV3PlaygroundAdvanced.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Script} from 'forge-std/Script.sol';
import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from './GovV3Helpers.sol';

abstract contract WithPayloads {
struct ActionsPerChain {
string chainName;
bytes[] actionCode;
}

function getActions() public view virtual returns (ActionsPerChain[] memory);
}

abstract contract DeployPayloads is WithPayloads, Script {
function isChainSupported(string memory chain) public view virtual returns (bool);

function run() external {
ActionsPerChain[] memory actionsPerChain = getActions();

for (uint256 i = 0; i < actionsPerChain.length; i++) {
ActionsPerChain memory rawActions = actionsPerChain[i];

// if actions belongs to the network we should not deploy, skip
if (!isChainSupported(rawActions.chainName)) continue;
require(rawActions.actionCode.length != 0, 'should be at least one payload action per chain');

vm.rpcUrl(rawActions.chainName);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here would go the conditional to check that payload is of the appropriate chain right (as we would not be using --multi)? and i guess the contract would still inherit from the base chain payload (like currently does)

vm.startBroadcast();

// compose actions
IPayloadsControllerCore.ExecutionAction[]
memory composedActions = new IPayloadsControllerCore.ExecutionAction[](
rawActions.actionCode.length
);
// deploy payloads
for (uint256 j = 0; j < rawActions.actionCode.length; j++) {
composedActions[j] = GovV3Helpers.buildAction(
GovV3Helpers.deployDeterministic(rawActions.actionCode[j])
);
}

// register actions at payloadsController
GovV3Helpers.createPayload(composedActions);
vm.stopBroadcast();
}
}
}

// not so applicable atm, because requires solid multiChan support, but for the good future
abstract contract DeployPayloadsMultiChain is DeployPayloads {
mapping(bytes32 => bool) internal _supportedChain;

constructor(string[] memory supportedChains) {
for (uint256 i = 0; i < supportedChains.length; i++) {
_supportedChain[keccak256(bytes(supportedChains[i]))] = true;
}
}

function isChainSupported(string memory chain) public view override returns (bool) {
return _supportedChain[keccak256(bytes(chain))];
}
}

abstract contract DeployPayloadsSingleChain is DeployPayloads {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sendra something like this to stay with one chain deployment

string public supportedChain;

constructor(string memory chainName) {
supportedChain = chainName;
}

function isChainSupported(string memory chain) public view override returns (bool) {
return keccak256(bytes(chain)) == keccak256(bytes(supportedChain));
}
}

abstract contract DeployPayloadsEthereum is DeployPayloadsSingleChain('ethereum') {}

abstract contract DeployPayloadsPolygon is DeployPayloadsSingleChain('polygon') {}

abstract contract CreateProposal is WithPayloads, Script {
string internal _ipfsFilePath;

// TODO: I would make it more human readable with params: date, name, isMulti(?) and generation of the actual string
constructor(string memory ipfsFilePath) {
_ipfsFilePath = ipfsFilePath;
}

function run() external {
ActionsPerChain[] memory actionsPerChain = getActions();

// create payloads
PayloadsControllerUtils.Payload[] memory payloadsPinned = new PayloadsControllerUtils.Payload[](
actionsPerChain.length
);

for (uint256 i = 0; i < actionsPerChain.length; i++) {
ActionsPerChain memory rawActions = actionsPerChain[i];
vm.rpcUrl(rawActions.chainName);

IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](
rawActions.actionCode.length
);

for (uint256 j = 0; j < rawActions.actionCode.length; j++) {
actions[j] = GovV3Helpers.buildAction(rawActions.actionCode[j]);
}
payloadsPinned[i] = GovV3Helpers._buildPayload(vm, block.chainid, actions);
}

// create proposal
vm.rpcUrl('ethereum');
vm.startBroadcast();
GovV3Helpers.createProposal(vm, payloadsPinned, GovV3Helpers.ipfsHashFile(vm, _ipfsFilePath));
vm.stopBroadcast();
}
}
51 changes: 51 additions & 0 deletions src/GovV3PlaygroundAdvancedExamples.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import './GovV3PlaygroundAdvanced.sol';

contract LetMeJustHaveSome {
string public name = 'some';
}

contract LetMeJustHaveAnother {
string public name = 'another';
}

abstract contract MyPayloads is WithPayloads {
function getActions() public pure override returns (ActionsPerChain[] memory) {
ActionsPerChain[] memory payloads = new ActionsPerChain[](2);

payloads[0].chainName = 'ethereum';
payloads[0].actionCode = new bytes[](1);
payloads[0].actionCode[0] = type(LetMeJustHaveSome).creationCode;

payloads[1].chainName = 'polygon';
payloads[1].actionCode = new bytes[](1);
payloads[1].actionCode[0] = type(LetMeJustHaveAnother).creationCode;

return payloads;
}
}

contract DeploymentComplexEthereum is MyPayloads, DeployPayloadsEthereum {}

contract DeploymentComplexPolygon is MyPayloads, DeployPayloadsPolygon {}

// depends on what will be better for generator
contract DeploymentComplexPoly is MyPayloads, DeployPayloadsSingleChain('polygon') {

}

// I think it will look way better
// contract ProposalCreationComplex is
// MyPayloads,
// CreateProposal('20240121', 'UpdateStETHAndWETHRiskParamsOnAaveV3EthereumOptimismAndArbitrum')
// {}
contract ProposalCreationComplex is
MyPayloads,
CreateProposal(
'src/20240121_Multi_UpdateStETHAndWETHRiskParamsOnAaveV3EthereumOptimismAndArbitrum/UpdateStETHAndWETHRiskParamsOnAaveV3EthereumOptimismAndArbitrum.md'
)
{

}
Loading