From a6a7350bc0c03aed1abbf0242963919699f6e53d Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 13:34:46 +0100 Subject: [PATCH 01/26] rename imports to not conflict with older versions --- .gitmodules | 3 + .vscode/settings.json | 8 +- contracts/AngleGovernor.sol | 58 +- contracts/ProposalReceiver.sol | 34 +- contracts/ProposalSender.sol | 54 +- contracts/TimelockControllerWithCounter.sol | 11 +- contracts/VeANGLEVotingDelegation.sol | 172 ++-- .../external/GovernorCountingFractional.sol | 47 +- contracts/external/GovernorShortCircuit.sol | 33 +- helpers/createProposal.sh | 2 + lib/angle-transmuter | 2 +- lib/openzeppelin-contracts-upgradeable | 2 +- lib/utils | 2 +- remappings.txt | 6 +- scripts/Constants.s.sol | 20 +- scripts/Interfaces.s.sol | 4 +- scripts/Utils.s.sol | 12 +- .../deployment/DeployOnChainGovernance.s.sol | 22 +- .../DeploySideChainGovernance.s.sol | 14 +- scripts/interaction/CheckRoles.s.sol | 823 ++++++++++++++++++ scripts/interfaces/ITransmuter.sol | 12 + .../angleGovernor/IncreaseQuorum.s.sol | 25 +- scripts/proposals/timelock/AddExecutor.s.sol | 28 +- scripts/proposals/transmuter/README.md | 50 ++ .../transmuter/TransmuterUpdateFacets.s.sol | 202 +++++ .../transmuter/TransmuterUtils.s.sol | 65 ++ test/Constants.t.sol | 4 +- test/Fixture.t.sol | 24 +- test/external/MockANGLE.sol | 2 +- test/fuzz/GovernorCountingFractional.t.sol | 283 +++--- test/fuzz/VeANGLEVotingDelegation.t.sol | 65 +- test/invariant/BasicInvariants.t.sol | 14 +- test/invariant/DelegationInvariants.t.sol | 15 +- .../invariant/MainnetGovernorInvariants.t.sol | 62 +- test/invariant/actors/BadVoter.t.sol | 37 +- test/invariant/actors/BaseActor.t.sol | 10 +- test/invariant/actors/Delegator.t.sol | 18 +- test/invariant/actors/Param.t.sol | 6 +- test/invariant/actors/Proposer.t.sol | 34 +- test/invariant/actors/Voter.t.sol | 25 +- test/scripts/timelock/AddExecutor.t.sol | 19 +- .../TransmuterUpdateFacetsTest.t.sol | 174 ++++ test/unit/AngleGovernor.t.sol | 40 +- test/unit/GovernorShortCircuit.t.sol | 57 +- test/unit/GovernorStateAndPropose.t.sol | 44 +- test/unit/ProposalLayerZeroRelayer.t.sol | 399 +++------ test/unit/Scenarios.t.sol | 43 +- test/unit/Simulate.t.sol | 31 +- test/unit/SimulationSetup.t.sol | 142 ++- test/unit/TimelockControllerWithCounter.t.sol | 215 ++--- 50 files changed, 2180 insertions(+), 1294 deletions(-) create mode 100644 scripts/interaction/CheckRoles.s.sol create mode 100644 scripts/interfaces/ITransmuter.sol create mode 100644 scripts/proposals/transmuter/README.md create mode 100644 scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol create mode 100644 scripts/proposals/transmuter/TransmuterUtils.s.sol create mode 100644 test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol diff --git a/.gitmodules b/.gitmodules index 94e23a0..1a52370 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,9 +5,11 @@ [submodule "lib/openzeppelin-contracts"] path = lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts + version = v4.7.3 [submodule "lib/openzeppelin-contracts-upgradeable"] path = lib/openzeppelin-contracts-upgradeable url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable + version = v4.7.3 [submodule "lib/solidity-examples"] path = lib/solidity-examples url = https://github.com/LayerZero-Labs/solidity-examples @@ -20,6 +22,7 @@ [submodule "lib/angle-transmuter"] path = lib/angle-transmuter url = https://github.com/AngleProtocol/angle-transmuter + branch = feat--oracles-with-firewalls-on-mint-and-burn [submodule "lib/borrow-contracts"] path = lib/borrow-contracts url = https://github.com/AngleProtocol/borrow-contracts diff --git a/.vscode/settings.json b/.vscode/settings.json index e6b354a..ed5b591 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,11 @@ { "solidity.compileUsingRemoteVersion": "0.8.20", + "solidity.formatter": "forge", + "[typescript]": { + "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" + }, "[solidity]": { - "editor.defaultFormatter": "JuanBlanco.solidity", - "editor.formatOnSave": true + "editor.defaultFormatter": "JuanBlanco.solidity" }, + "editor.formatOnSave": true, } diff --git a/contracts/AngleGovernor.sol b/contracts/AngleGovernor.sol index 1fed948..bdcf84c 100644 --- a/contracts/AngleGovernor.sol +++ b/contracts/AngleGovernor.sol @@ -2,16 +2,16 @@ pragma solidity ^0.8.20; -import { IVotes } from "oz/governance/utils/IVotes.sol"; +import {IVotes} from "oz-v5/governance/utils/IVotes.sol"; -import { Governor } from "oz/governance/Governor.sol"; -import { GovernorPreventLateQuorum } from "oz/governance/extensions/GovernorPreventLateQuorum.sol"; -import { GovernorVotesQuorumFraction, GovernorVotes } from "oz/governance/extensions/GovernorVotesQuorumFraction.sol"; -import { GovernorSettings } from "oz/governance/extensions/GovernorSettings.sol"; -import { IERC5805 } from "oz/interfaces/IERC5805.sol"; +import {Governor} from "oz-v5/governance/Governor.sol"; +import {GovernorPreventLateQuorum} from "oz-v5/governance/extensions/GovernorPreventLateQuorum.sol"; +import {GovernorVotesQuorumFraction, GovernorVotes} from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; +import {GovernorSettings} from "oz-v5/governance/extensions/GovernorSettings.sol"; +import {IERC5805} from "oz-v5/interfaces/IERC5805.sol"; -import { GovernorCountingFractional } from "./external/GovernorCountingFractional.sol"; -import { GovernorShortCircuit } from "./external/GovernorShortCircuit.sol"; +import {GovernorCountingFractional} from "./external/GovernorCountingFractional.sol"; +import {GovernorShortCircuit} from "./external/GovernorShortCircuit.sol"; import "./utils/Errors.sol"; @@ -85,9 +85,8 @@ contract AngleGovernor is function state(uint256 proposalId) public view override(Governor) returns (ProposalState) { ProposalState currentState = super.state(proposalId); if ( - currentState == ProposalState.Executed || - currentState == ProposalState.Canceled || - currentState == ProposalState.Pending + currentState == ProposalState.Executed || currentState == ProposalState.Canceled + || currentState == ProposalState.Pending ) return currentState; uint256 snapshot = proposalSnapshot(proposalId); @@ -99,25 +98,32 @@ contract AngleGovernor is return ProposalState.Succeeded; } else if (isShortCircuitAgainst) { return ProposalState.Defeated; - } else return currentState; + } else { + return currentState; + } } /// @inheritdoc GovernorVotesQuorumFraction - function quorum( - uint256 timepoint - ) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256 quorumAtTimepoint) { + function quorum(uint256 timepoint) + public + view + override(Governor, GovernorVotesQuorumFraction) + returns (uint256 quorumAtTimepoint) + { uint256 snapshotBlockNumber = $snapshotTimestampToSnapshotBlockNumber[timepoint]; if (snapshotBlockNumber == 0 || snapshotBlockNumber >= block.number) revert InvalidTimepoint(); quorumAtTimepoint = - (token().getPastTotalSupply(snapshotBlockNumber) * quorumNumerator(timepoint)) / - quorumDenominator(); + (token().getPastTotalSupply(snapshotBlockNumber) * quorumNumerator(timepoint)) / quorumDenominator(); } /// @inheritdoc GovernorPreventLateQuorum - function proposalDeadline( - uint256 proposalId - ) public view override(Governor, GovernorPreventLateQuorum) returns (uint256) { + function proposalDeadline(uint256 proposalId) + public + view + override(Governor, GovernorPreventLateQuorum) + returns (uint256) + { return GovernorPreventLateQuorum.proposalDeadline(proposalId); } @@ -168,13 +174,11 @@ contract AngleGovernor is } /// @inheritdoc GovernorPreventLateQuorum - function _castVote( - uint256 proposalId, - address account, - uint8 support, - string memory reason, - bytes memory params - ) internal override(Governor, GovernorPreventLateQuorum) returns (uint256) { + function _castVote(uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params) + internal + override(Governor, GovernorPreventLateQuorum) + returns (uint256) + { return GovernorPreventLateQuorum._castVote(proposalId, account, support, reason, params); } diff --git a/contracts/ProposalReceiver.sol b/contracts/ProposalReceiver.sol index e9c5218..73897ba 100644 --- a/contracts/ProposalReceiver.sol +++ b/contracts/ProposalReceiver.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.20; -import "oz/utils/ReentrancyGuard.sol"; +import "oz-v5/utils/ReentrancyGuard.sol"; import "lz/lzApp/NonblockingLzApp.sol"; import "./utils/Errors.sol"; @@ -25,12 +25,11 @@ contract ProposalReceiver is NonblockingLzApp, ReentrancyGuard { constructor(address _endpoint) NonblockingLzApp(_endpoint) Ownable(msg.sender) {} // overriding the virtual function in LzReceiver - function _blockingLzReceive( - uint16 _srcChainId, - bytes memory _srcAddress, - uint64 _nonce, - bytes memory _payload - ) internal virtual override { + function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) + internal + virtual + override + { bytes32 hashedPayload = keccak256(_payload); uint256 gasToStoreAndEmit = 30000; // enough gas to ensure we can store the payload and emit the event @@ -50,8 +49,8 @@ contract ProposalReceiver is NonblockingLzApp, ReentrancyGuard { /// @notice Executes the proposal /// @dev Called by LayerZero Endpoint when a message from the source is received function _nonblockingLzReceive(uint16, bytes memory, uint64, bytes memory _payload) internal virtual override { - (address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas) = abi - .decode(_payload, (address[], uint[], string[], bytes[])); + (address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas) = + abi.decode(_payload, (address[], uint256[], string[], bytes[])); for (uint256 i = 0; i < targets.length; i++) { _executeTransaction(targets[i], values[i], signatures[i], calldatas[i]); @@ -59,18 +58,15 @@ contract ProposalReceiver is NonblockingLzApp, ReentrancyGuard { emit ProposalExecuted(_payload); } - function _executeTransaction( - address target, - uint256 value, - string memory signature, - bytes memory data - ) private nonReentrant { - bytes memory callData = bytes(signature).length == 0 - ? data - : abi.encodePacked(bytes4(keccak256(bytes(signature))), data); + function _executeTransaction(address target, uint256 value, string memory signature, bytes memory data) + private + nonReentrant + { + bytes memory callData = + bytes(signature).length == 0 ? data : abi.encodePacked(bytes4(keccak256(bytes(signature))), data); // solium-disable-next-line security/no-call-value - (bool success, ) = target.call{ value: value }(callData); + (bool success,) = target.call{value: value}(callData); if (!success) revert OmnichainGovernanceExecutorTxExecReverted(); } diff --git a/contracts/ProposalSender.sol b/contracts/ProposalSender.sol index 3e60aec..21a1b48 100644 --- a/contracts/ProposalSender.sol +++ b/contracts/ProposalSender.sol @@ -1,8 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; -import "oz/access/Ownable.sol"; -import "oz/utils/ReentrancyGuard.sol"; +import "oz-v5/access/Ownable.sol"; +import "oz-v5/utils/ReentrancyGuard.sol"; import "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "./utils/Errors.sol"; @@ -47,7 +47,7 @@ contract ProposalSender is Ownable, ReentrancyGuard { uint16 indexed remoteChainId, bytes payload, bytes adapterParams, - uint value, + uint256 value, bytes reason ); @@ -66,11 +66,11 @@ contract ProposalSender is Ownable, ReentrancyGuard { /// on the destination /// @return nativeFee The amount of fee in the native gas token (e.g. ETH) /// @return zroFee The amount of fee in ZRO token - function estimateFees( - uint16 remoteChainId, - bytes calldata payload, - bytes calldata adapterParams - ) external view returns (uint nativeFee, uint zroFee) { + function estimateFees(uint16 remoteChainId, bytes calldata payload, bytes calldata adapterParams) + external + view + returns (uint256 nativeFee, uint256 zroFee) + { return lzEndpoint.estimateFees(remoteChainId, address(this), payload, false, adapterParams); } @@ -81,24 +81,17 @@ contract ProposalSender is Ownable, ReentrancyGuard { /// payload = abi.encode(targets, values, signatures, calldatas) /// @param adapterParams The params used to specify the custom amount of gas required for the execution /// on the destination - function execute( - uint16 remoteChainId, - bytes calldata payload, - bytes calldata adapterParams - ) external payable onlyOwner { + function execute(uint16 remoteChainId, bytes calldata payload, bytes calldata adapterParams) + external + payable + onlyOwner + { bytes memory trustedRemote = trustedRemoteLookup[remoteChainId]; if (trustedRemote.length == 0) revert OmnichainProposalSenderDestinationChainNotTrustedSource(); - try - lzEndpoint.send{ value: msg.value }( - remoteChainId, - trustedRemote, - payload, - payable(tx.origin), - address(0), - adapterParams - ) - { + try lzEndpoint.send{value: msg.value}( + remoteChainId, trustedRemote, payload, payable(tx.origin), address(0), adapterParams + ) { emit ExecuteRemoteProposal(remoteChainId, payload); } catch (bytes memory reason) { uint64 _lastStoredPayloadNonce = ++lastStoredPayloadNonce; @@ -122,7 +115,7 @@ contract ProposalSender is Ownable, ReentrancyGuard { uint16 remoteChainId, bytes calldata payload, bytes calldata adapterParams, - uint originalValue + uint256 originalValue ) external payable nonReentrant { bytes32 hash = storedExecutionHashes[nonce]; if (hash == bytes32(0)) revert OmnichainProposalSenderNoStoredPayload(); @@ -132,13 +125,8 @@ contract ProposalSender is Ownable, ReentrancyGuard { delete storedExecutionHashes[nonce]; - lzEndpoint.send{ value: originalValue + msg.value }( - remoteChainId, - trustedRemoteLookup[remoteChainId], - payload, - payable(msg.sender), - address(0), - adapterParams + lzEndpoint.send{value: originalValue + msg.value}( + remoteChainId, trustedRemoteLookup[remoteChainId], payload, payable(msg.sender), address(0), adapterParams ); emit ClearPayload(nonce, hash); } @@ -156,7 +144,7 @@ contract ProposalSender is Ownable, ReentrancyGuard { /// @param chainId The LayerZero chainId for the pending config change /// @param configType The type of configuration. Every messaging library has its own convention /// @param config The configuration in bytes. It can encode arbitrary content - function setConfig(uint16 version, uint16 chainId, uint configType, bytes calldata config) external onlyOwner { + function setConfig(uint16 version, uint16 chainId, uint256 configType, bytes calldata config) external onlyOwner { lzEndpoint.setConfig(version, chainId, configType, config); } @@ -170,7 +158,7 @@ contract ProposalSender is Ownable, ReentrancyGuard { /// @param version Messaging library version /// @param chainId The LayerZero chainId /// @param configType Type of configuration. Every messaging library has its own convention. - function getConfig(uint16 version, uint16 chainId, uint configType) external view returns (bytes memory) { + function getConfig(uint16 version, uint16 chainId, uint256 configType) external view returns (bytes memory) { return lzEndpoint.getConfig(version, chainId, address(this), configType); } } diff --git a/contracts/TimelockControllerWithCounter.sol b/contracts/TimelockControllerWithCounter.sol index 5074d50..2efd7ca 100644 --- a/contracts/TimelockControllerWithCounter.sol +++ b/contracts/TimelockControllerWithCounter.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.20; -import { TimelockController } from "oz/governance/TimelockController.sol"; +import {TimelockController} from "oz-v5/governance/TimelockController.sol"; /// @title AngleGovernor /// @author Angle Labs, Inc @@ -24,12 +24,9 @@ contract TimelockControllerWithCounter is TimelockController { CONSTRUCTOR //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - constructor( - uint256 minDelay, - address[] memory proposers, - address[] memory executors, - address admin - ) TimelockController(minDelay, proposers, executors, admin) {} + constructor(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) + TimelockController(minDelay, proposers, executors, admin) + {} /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EXTERNAL OVERRIDES diff --git a/contracts/VeANGLEVotingDelegation.sol b/contracts/VeANGLEVotingDelegation.sol index 8d3efc4..f1a40fe 100644 --- a/contracts/VeANGLEVotingDelegation.sol +++ b/contracts/VeANGLEVotingDelegation.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: ISC pragma solidity ^0.8.20; -import { ECDSA } from "oz/utils/cryptography/ECDSA.sol"; -import { EIP712 } from "oz/utils/cryptography/EIP712.sol"; -import { Math } from "oz/utils/math/Math.sol"; -import { SafeCast } from "oz/utils/math/SafeCast.sol"; -import { IERC5805 } from "oz/interfaces/IERC5805.sol"; -import { IveANGLE } from "./interfaces/IveANGLE.sol"; -import { IveANGLEVotingDelegation } from "./interfaces/IveANGLEVotingDelegation.sol"; +import {ECDSA} from "oz-v5/utils/cryptography/ECDSA.sol"; +import {EIP712} from "oz-v5/utils/cryptography/EIP712.sol"; +import {Math} from "oz-v5/utils/math/Math.sol"; +import {SafeCast} from "oz-v5/utils/math/SafeCast.sol"; +import {IERC5805} from "oz-v5/interfaces/IERC5805.sol"; +import {IveANGLE} from "./interfaces/IveANGLE.sol"; +import {IveANGLEVotingDelegation} from "./interfaces/IveANGLEVotingDelegation.sol"; /// @title VeANGLEVotingDelegation /// @notice Contract that keeps track of voting weights and delegations, leveraging veANGLE @@ -45,8 +45,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @notice Mapping from delegate to weekly rounded time of expiry to the aggregated values at time of expiration. /// Mirrors veANGLE expiration. - mapping(address delegate => mapping(uint256 week => IveANGLEVotingDelegation.Expiration)) - public $expiredDelegations; + mapping(address delegate => mapping(uint256 week => IveANGLEVotingDelegation.Expiration)) public $expiredDelegations; /// @notice Constructor of the contract, called on deployment /// @param veANGLE Address of veANGLE contract @@ -58,10 +57,11 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param delegateAddress Address of delegate /// @param index Integer index of the checkpoint /// @return delegateCheckpoint DelegateCheckpoint of ```delegate``` at ```index``` - function getCheckpoint( - address delegateAddress, - uint32 index - ) external view returns (IveANGLEVotingDelegation.DelegateCheckpoint memory) { + function getCheckpoint(address delegateAddress, uint32 index) + external + view + returns (IveANGLEVotingDelegation.DelegateCheckpoint memory) + { return $delegateCheckpoints[delegateAddress][index]; } @@ -71,15 +71,14 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param voter Address of voter /// @param timestamp A block.timestamp, typically corresponding to a proposal snapshot /// @return delegatedWeight Voting weight corresponding to all ```delegateAccount```'s received delegations - function _calculateDelegatedWeight( - address voter, - uint256 timestamp - ) internal view returns (uint256 delegatedWeight) { + function _calculateDelegatedWeight(address voter, uint256 timestamp) + internal + view + returns (uint256 delegatedWeight) + { // Check if delegate account has any delegations - IveANGLEVotingDelegation.DelegateCheckpoint memory checkpoint = _checkpointBinarySearch({ - _$checkpoints: $delegateCheckpoints[voter], - timestamp: timestamp - }); + IveANGLEVotingDelegation.DelegateCheckpoint memory checkpoint = + _checkpointBinarySearch({_$checkpoints: $delegateCheckpoints[voter], timestamp: timestamp}); // If checkpoint is empty, short circuit and return 0 delegated weight if (checkpoint.timestamp == 0) { @@ -88,12 +87,8 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // It's possible that some delegated veANGLE has expired. // Add up all expirations during this time period, week by week. - (uint256 totalExpiredBias, uint256 totalExpiredSlope) = _calculateExpirations({ - account: voter, - start: checkpoint.timestamp, - end: timestamp, - checkpoint: checkpoint - }); + (uint256 totalExpiredBias, uint256 totalExpiredSlope) = + _calculateExpirations({account: voter, start: checkpoint.timestamp, end: timestamp, checkpoint: checkpoint}); uint256 expirationAdjustedBias = checkpoint.normalizedBias - totalExpiredBias; uint256 expirationAdjustedSlope = checkpoint.normalizedSlope - totalExpiredSlope; @@ -119,7 +114,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { uint256 firstDelegationTimestamp = $delegations[voter].firstDelegationTimestamp; // Never delegated OR this timestamp is before the first delegation by account if (firstDelegationTimestamp == 0 || timestamp < firstDelegationTimestamp) { - try VE_ANGLE.balanceOf({ addr: voter, _t: timestamp }) returns (uint256 _balance) { + try VE_ANGLE.balanceOf({addr: voter, _t: timestamp}) returns (uint256 _balance) { return _balance; } catch {} } @@ -132,12 +127,13 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @dev See _calculateExpirations /// @param delegateAddress Address of delegate /// @return calculatedCheckpoint A new DelegateCheckpoint to write based on expirations since previous checkpoint - function calculateExpiredDelegations( - address delegateAddress - ) public view returns (IveANGLEVotingDelegation.DelegateCheckpoint memory calculatedCheckpoint) { - IveANGLEVotingDelegation.DelegateCheckpoint[] storage $userDelegationCheckpoints = $delegateCheckpoints[ - delegateAddress - ]; + function calculateExpiredDelegations(address delegateAddress) + public + view + returns (IveANGLEVotingDelegation.DelegateCheckpoint memory calculatedCheckpoint) + { + IveANGLEVotingDelegation.DelegateCheckpoint[] storage $userDelegationCheckpoints = + $delegateCheckpoints[delegateAddress]; // This ensures that checkpoints take effect at the next epoch uint256 checkpointTimestamp = ((block.timestamp / 1 days) * 1 days) + 1 days; @@ -146,9 +142,8 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // Nothing to expire if no one delegated to you if (checkpointsLength == 0) return calculatedCheckpoint; - IveANGLEVotingDelegation.DelegateCheckpoint memory lastCheckpoint = $userDelegationCheckpoints[ - checkpointsLength - 1 - ]; + IveANGLEVotingDelegation.DelegateCheckpoint memory lastCheckpoint = + $userDelegationCheckpoints[checkpointsLength - 1]; // Nothing expired because the most recent checkpoint is already written if (lastCheckpoint.timestamp == checkpointTimestamp) { @@ -201,9 +196,8 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param timestamp A block.timestamp, typically corresponding to a proposal snapshot /// @return totalVotingWeight Voting weight of ```voter``` at ```timestamp``` function _getVotingWeight(address voter, uint256 timestamp) internal view returns (uint256 totalVotingWeight) { - totalVotingWeight = - _calculateVotingWeight({ voter: voter, timestamp: timestamp }) + - _calculateDelegatedWeight({ voter: voter, timestamp: timestamp }); + totalVotingWeight = _calculateVotingWeight({voter: voter, timestamp: timestamp}) + + _calculateDelegatedWeight({voter: voter, timestamp: timestamp}); } /// @notice Calculates a voter's weight at ```timestamp``` @@ -211,14 +205,14 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param timepoint A block.timestamp, typically corresponding to a proposal snapshot /// @return votingWeight Voting weight of ```voterAddress``` at ```timepoint``` function getVotes(address voter, uint256 timepoint) external view returns (uint256) { - return _getVotingWeight({ voter: voter, timestamp: timepoint }); + return _getVotingWeight({voter: voter, timestamp: timepoint}); } /// @notice Calculates a voter's weight at the current block.timestamp /// @param voter Address of voter /// @return votingWeight Voting weight of ```voterAddress``` at ```block.timestamp``` function getVotes(address voter) external view returns (uint256 votingWeight) { - votingWeight = _getVotingWeight({ voter: voter, timestamp: block.timestamp }); + votingWeight = _getVotingWeight({voter: voter, timestamp: block.timestamp}); } /// @notice Calculates a voter's weight at ```timepoint``` @@ -228,7 +222,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { function getPastVotes(address voter, uint256 timepoint) external view returns (uint256 pastVotingWeight) { if (timepoint >= block.timestamp) revert IveANGLEVotingDelegation.TimestampInFuture(); - pastVotingWeight = _getVotingWeight({ voter: voter, timestamp: timepoint }); + pastVotingWeight = _getVotingWeight({voter: voter, timestamp: timepoint}); } /// @notice Retrieves the total supply of veANGLE at ```blockNumber``` @@ -256,7 +250,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @notice Delegates votes from signer to ```delegatee``` at the next epoch /// @param delegatee Address to delegate to function delegate(address delegatee) external { - _delegate({ delegator: msg.sender, delegatee: delegatee }); + _delegate({delegator: msg.sender, delegatee: delegatee}); } /// @notice Delegates votes from signer to ```delegatee``` @@ -266,22 +260,16 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param v Recovery ID /// @param r Output of an ECDSA signature /// @param s Output of an ECDSA signature - function delegateBySig( - address delegatee, - uint256 nonce, - uint256 expiry, - uint8 v, - bytes32 r, - bytes32 s - ) public virtual override { + function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) + public + virtual + override + { // Revert if signature is expired if (block.timestamp > expiry) revert IveANGLEVotingDelegation.SignatureExpired(); address signer = ECDSA.recover( - _hashTypedDataV4(keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry))), - v, - r, - s + _hashTypedDataV4(keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry))), v, r, s ); // Increment nonce and check against incremented value @@ -303,11 +291,8 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // This ensures that checkpoints take effect at the next epoch uint256 checkpointTimestamp = ((block.timestamp / 1 days) * 1 days) + 1 days; - IveANGLEVotingDelegation.NormalizedVeANGLELockInfo - memory normalizedDelegatorVeANGLELockInfo = _getNormalizedveANGLELockInfo({ - delegator: delegator, - checkpointTimestamp: checkpointTimestamp - }); + IveANGLEVotingDelegation.NormalizedVeANGLELockInfo memory normalizedDelegatorVeANGLELockInfo = + _getNormalizedveANGLELockInfo({delegator: delegator, checkpointTimestamp: checkpointTimestamp}); _moveVotingPowerFromPreviousDelegate({ previousDelegation: previousDelegation, @@ -331,11 +316,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { slope: uint64(normalizedDelegatorVeANGLELockInfo.slope) }); - emit DelegateChanged({ - delegator: delegator, - fromDelegate: previousDelegation.delegate, - toDelegate: delegatee - }); + emit DelegateChanged({delegator: delegator, fromDelegate: previousDelegation.delegate, toDelegate: delegatee}); } /// @notice Retrieves lock information from veANGLE. @@ -343,10 +324,11 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param delegator Address of the delegator /// @param checkpointTimestamp block.timestamp of the next checkpoint epoch /// @return normalizedVeANGLELockInfo Information about delegator's lock from veANGLE contract, normalized - function _getNormalizedveANGLELockInfo( - address delegator, - uint256 checkpointTimestamp - ) private view returns (IveANGLEVotingDelegation.NormalizedVeANGLELockInfo memory normalizedVeANGLELockInfo) { + function _getNormalizedveANGLELockInfo(address delegator, uint256 checkpointTimestamp) + private + view + returns (IveANGLEVotingDelegation.NormalizedVeANGLELockInfo memory normalizedVeANGLELockInfo) + { // Check expiry in case we need to revert uint256 expiry = VE_ANGLE.locked(delegator).end; if (expiry <= checkpointTimestamp) revert IveANGLEVotingDelegation.CantDelegateLockExpired(); @@ -354,9 +336,9 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // Most recent epoch uint256 epoch = VE_ANGLE.user_point_epoch(delegator); // Values for delegator at the most recent epoch - (int128 userBias, int128 userSlope, , ) = VE_ANGLE.user_point_history({ _addr: delegator, _idx: epoch }); + (int128 userBias, int128 userSlope,,) = VE_ANGLE.user_point_history({_addr: delegator, _idx: epoch}); // Get the timestamp of the last update in veANGLE user history - uint256 lastUpdate = VE_ANGLE.user_point_history__ts({ _addr: delegator, _idx: epoch }); + uint256 lastUpdate = VE_ANGLE.user_point_history__ts({_addr: delegator, _idx: epoch}); // Set return values normalizedVeANGLELockInfo.slope = SafeCast.toUint256(userSlope); @@ -414,15 +396,13 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // Remove voting power from previous delegate, if they exist if (previousDelegation.delegate != address(0)) { // Get the last Checkpoint for previous delegate - IveANGLEVotingDelegation.DelegateCheckpoint[] storage $previousDelegationCheckpoints = $delegateCheckpoints[ - previousDelegation.delegate - ]; + IveANGLEVotingDelegation.DelegateCheckpoint[] storage $previousDelegationCheckpoints = + $delegateCheckpoints[previousDelegation.delegate]; uint256 accountCheckpointsLength = $previousDelegationCheckpoints.length; // NOTE: we know that _accountsCheckpointLength > 0 // because we have already checked that the previous delegation exists - IveANGLEVotingDelegation.DelegateCheckpoint memory lastCheckpoint = $previousDelegationCheckpoints[ - accountCheckpointsLength - 1 - ]; + IveANGLEVotingDelegation.DelegateCheckpoint memory lastCheckpoint = + $previousDelegationCheckpoints[accountCheckpointsLength - 1]; uint256 oldWeightOldDelegate = _getVotingWeight(previousDelegation.delegate, checkpointTimestamp); // Handle Expirations @@ -433,9 +413,8 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // See testExpiredLockRedelegateNoVotingWeight(). if (previousDelegation.expiry > checkpointTimestamp) { // Calculations - IveANGLEVotingDelegation.Expiration memory expiration = $expiredDelegations[ - previousDelegation.delegate - ][previousDelegation.expiry]; + IveANGLEVotingDelegation.Expiration memory expiration = + $expiredDelegations[previousDelegation.delegate][previousDelegation.expiry]; // All expiration fields will never exceed their size so subtraction doesnt need to be checked // and they can be unsafely cast unchecked { @@ -473,7 +452,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { emit DelegateVotesChanged({ delegate: previousDelegation.delegate, previousVotes: oldWeightOldDelegate, - newVotes: _getVotingWeight({ voter: previousDelegation.delegate, timestamp: checkpointTimestamp }) + newVotes: _getVotingWeight({voter: previousDelegation.delegate, timestamp: checkpointTimestamp}) }); } } @@ -488,9 +467,8 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { uint256 checkpointTimestamp ) private { // Get the last checkpoint for the new delegate - IveANGLEVotingDelegation.DelegateCheckpoint[] storage $newDelegateCheckpoints = $delegateCheckpoints[ - newDelegate - ]; + IveANGLEVotingDelegation.DelegateCheckpoint[] storage $newDelegateCheckpoints = + $delegateCheckpoints[newDelegate]; uint256 accountCheckpointsLength = $newDelegateCheckpoints.length; IveANGLEVotingDelegation.DelegateCheckpoint memory lastCheckpoint = accountCheckpointsLength == 0 ? IveANGLEVotingDelegation.DelegateCheckpoint(0, 0, 0) @@ -499,9 +477,8 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // Handle expiration // Calculations - IveANGLEVotingDelegation.Expiration memory expiration = $expiredDelegations[newDelegate][ - delegatorVeANGLELockInfo.expiry - ]; + IveANGLEVotingDelegation.Expiration memory expiration = + $expiredDelegations[newDelegate][delegatorVeANGLELockInfo.expiry]; // NOTE: All expiration fields will never exceed their size so addition doesnt need to be checked // and can be unsafely cast @@ -536,7 +513,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { emit DelegateVotesChanged({ delegate: newDelegate, previousVotes: oldWeightNewDelegate, - newVotes: _getVotingWeight({ voter: newDelegate, timestamp: checkpointTimestamp }) + newVotes: _getVotingWeight({voter: newDelegate, timestamp: checkpointTimestamp}) }); } @@ -560,13 +537,12 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { ) private view returns (IveANGLEVotingDelegation.DelegateCheckpoint memory newCheckpoint) { // If this is the first checkpoint, create a new one and early return if (previousCheckpoint.timestamp == 0) { - return - IveANGLEVotingDelegation.DelegateCheckpoint({ - // can be unsafely cast because values will never exceed uint128 max - timestamp: uint128(checkpointTimestamp), - normalizedBias: uint128(deltaBias), - normalizedSlope: uint128(deltaSlope) - }); + return IveANGLEVotingDelegation.DelegateCheckpoint({ + // can be unsafely cast because values will never exceed uint128 max + timestamp: uint128(checkpointTimestamp), + normalizedBias: uint128(deltaBias), + normalizedSlope: uint128(deltaSlope) + }); } newCheckpoint.timestamp = previousCheckpoint.timestamp; @@ -646,8 +622,8 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { } else { // Total values will always be less than or equal to a checkpoint's values uint256 currentWeek = WEEK + (start / WEEK) * WEEK; - mapping(uint256 => IveANGLEVotingDelegation.Expiration) - storage $delegateExpirations = $expiredDelegations[account]; + mapping(uint256 => IveANGLEVotingDelegation.Expiration) storage $delegateExpirations = + $expiredDelegations[account]; // Sum values from currentWeek until end while (currentWeek <= end) { IveANGLEVotingDelegation.Expiration memory expiration = $delegateExpirations[currentWeek]; diff --git a/contracts/external/GovernorCountingFractional.sol b/contracts/external/GovernorCountingFractional.sol index c03fbbc..7d26af3 100644 --- a/contracts/external/GovernorCountingFractional.sol +++ b/contracts/external/GovernorCountingFractional.sol @@ -2,9 +2,9 @@ pragma solidity ^0.8.20; -import { Governor } from "oz/governance/Governor.sol"; -import { GovernorCountingSimple } from "oz/governance/extensions/GovernorCountingSimple.sol"; -import { SafeCast } from "oz/utils/math/SafeCast.sol"; +import {Governor} from "oz-v5/governance/Governor.sol"; +import {GovernorCountingSimple} from "oz-v5/governance/extensions/GovernorCountingSimple.sol"; +import {SafeCast} from "oz-v5/utils/math/SafeCast.sol"; import "../utils/Errors.sol"; @@ -64,9 +64,12 @@ abstract contract GovernorCountingFractional is Governor { /** * @dev Accessor to the internal vote counts. */ - function proposalVotes( - uint256 proposalId - ) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) { + function proposalVotes(uint256 proposalId) + public + view + virtual + returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) + { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return (proposalVote.againstVotes, proposalVote.forVotes, proposalVote.abstainVotes); } @@ -109,13 +112,11 @@ abstract contract GovernorCountingFractional is Governor { * * See `_countVoteNominal` and `_countVoteFractional` for more details. */ - function _countVote( - uint256 proposalId, - address account, - uint8 support, - uint256 totalWeight, - bytes memory voteData - ) internal virtual override { + function _countVote(uint256 proposalId, address account, uint8 support, uint256 totalWeight, bytes memory voteData) + internal + virtual + override + { if (totalWeight == 0) revert GovernorCountingFractionalNoWeight(); if (_proposalVotersWeightCast[proposalId][account] >= totalWeight) { revert GovernorCountingFractionalAllWeightCast(); @@ -138,8 +139,9 @@ abstract contract GovernorCountingFractional is Governor { * vote before or after. */ function _countVoteNominal(uint256 proposalId, address account, uint128 totalWeight, uint8 support) internal { - if (_proposalVotersWeightCast[proposalId][account] > 0) + if (_proposalVotersWeightCast[proposalId][account] > 0) { revert GovernorCountingFractionalVoteWouldExceedWeight(); + } _proposalVotersWeightCast[proposalId][account] = totalWeight; @@ -175,12 +177,9 @@ abstract contract GovernorCountingFractional is Governor { * Note that if partial votes are cast, all remaining weight must be cast * with _countVoteFractional: _countVoteNominal will revert. */ - function _countVoteFractional( - uint256 proposalId, - address account, - uint128 totalWeight, - bytes memory voteData - ) internal { + function _countVoteFractional(uint256 proposalId, address account, uint128 totalWeight, bytes memory voteData) + internal + { if (voteData.length != 48) revert GovernorCountingFractionalInvalidVoteData(); (uint128 _againstVotes, uint128 _forVotes, uint128 _abstainVotes) = _decodePackedVotes(voteData); @@ -211,9 +210,11 @@ abstract contract GovernorCountingFractional is Governor { * language limitation which prevents slicing bytes stored in memory, rather * than calldata. */ - function _decodePackedVotes( - bytes memory voteData - ) internal pure returns (uint128 againstVotes, uint128 forVotes, uint128 abstainVotes) { + function _decodePackedVotes(bytes memory voteData) + internal + pure + returns (uint128 againstVotes, uint128 forVotes, uint128 abstainVotes) + { assembly { againstVotes := shr(128, mload(add(voteData, 0x20))) forVotes := and(_VOTEMASK, mload(add(voteData, 0x20))) diff --git a/contracts/external/GovernorShortCircuit.sol b/contracts/external/GovernorShortCircuit.sol index 021e1fa..985deee 100644 --- a/contracts/external/GovernorShortCircuit.sol +++ b/contracts/external/GovernorShortCircuit.sol @@ -2,11 +2,11 @@ pragma solidity ^0.8.20; -import { Checkpoints } from "oz/utils/structs/Checkpoints.sol"; -import { IERC5805 } from "oz/interfaces/IERC5805.sol"; -import { GovernorVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { GovernorVotesQuorumFraction } from "oz/governance/extensions/GovernorVotesQuorumFraction.sol"; -import { GovernorCountingFractional, SafeCast } from "./GovernorCountingFractional.sol"; +import {Checkpoints} from "oz-v5/utils/structs/Checkpoints.sol"; +import {IERC5805} from "oz-v5/interfaces/IERC5805.sol"; +import {GovernorVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {GovernorVotesQuorumFraction} from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; +import {GovernorCountingFractional, SafeCast} from "./GovernorCountingFractional.sol"; import "../utils/Errors.sol"; @@ -83,9 +83,8 @@ abstract contract GovernorShortCircuit is GovernorVotes, GovernorCountingFractio } // Otherwise, do the binary search - shortCircuitNumeratorAtTimepoint = _$shortCircuitNumeratorHistory.upperLookupRecent( - SafeCast.toUint32(timepoint) - ); + shortCircuitNumeratorAtTimepoint = + _$shortCircuitNumeratorHistory.upperLookupRecent(SafeCast.toUint32(timepoint)); } /// @notice Returns the latest short circuit numerator @@ -97,8 +96,7 @@ abstract contract GovernorShortCircuit is GovernorVotes, GovernorCountingFractio if (snapshotBlockNumber == 0 || snapshotBlockNumber >= block.number) revert InvalidTimepoint(); shortCircuitThresholdAtTimepoint = - (token().getPastTotalSupply(snapshotBlockNumber) * shortCircuitNumerator(timepoint)) / - quorumDenominator(); + (token().getPastTotalSupply(snapshotBlockNumber) * shortCircuitNumerator(timepoint)) / quorumDenominator(); } /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -123,10 +121,12 @@ abstract contract GovernorShortCircuit is GovernorVotes, GovernorCountingFractio /// @param proposalId Proposal ID /// @return isShortCircuitFor Represents if short circuit threshold for votes were reached or not /// @return isShortCircuitAgainst Represents if short circuit threshold against votes were reached or not - function _shortCircuit( - uint256 proposalId - ) internal view returns (bool isShortCircuitFor, bool isShortCircuitAgainst) { - (uint256 againstVoteWeight, uint256 forVoteWeight, ) = proposalVotes(proposalId); + function _shortCircuit(uint256 proposalId) + internal + view + returns (bool isShortCircuitFor, bool isShortCircuitAgainst) + { + (uint256 againstVoteWeight, uint256 forVoteWeight,) = proposalVotes(proposalId); uint256 proposalVoteStart = proposalSnapshot(proposalId); uint256 shortCircuitThresholdValue = shortCircuitThreshold(proposalVoteStart); @@ -160,9 +160,6 @@ abstract contract GovernorShortCircuit is GovernorVotes, GovernorCountingFractio function _setVotingDelayBlocks(uint256 votingDelayBlocks) internal { uint256 oldVotingDelayBlocks = $votingDelayBlocks; $votingDelayBlocks = votingDelayBlocks; - emit VotingDelayBlocksSet({ - oldVotingDelayBlocks: oldVotingDelayBlocks, - newVotingDelayBlocks: votingDelayBlocks - }); + emit VotingDelayBlocksSet({oldVotingDelayBlocks: oldVotingDelayBlocks, newVotingDelayBlocks: votingDelayBlocks}); } } diff --git a/helpers/createProposal.sh b/helpers/createProposal.sh index 1cfc17b..ec5fb1e 100644 --- a/helpers/createProposal.sh +++ b/helpers/createProposal.sh @@ -18,6 +18,7 @@ function usage { echo -e "\t9: Polygon ZkEvm" echo -e "\t10: Optimism" echo -e "\t11: Linea" + echo -e "\t12: Fork" echo "" } @@ -64,6 +65,7 @@ function main { echo "- 9: Polygon ZkEvm" echo "- 10: Optimism" echo "- 11: Linea" + echo "- 12: Fork" echo "- 100: All" read chains diff --git a/lib/angle-transmuter b/lib/angle-transmuter index 7fd03d3..feef55a 160000 --- a/lib/angle-transmuter +++ b/lib/angle-transmuter @@ -1 +1 @@ -Subproject commit 7fd03d3135c8d2ee8bcfe174b5b80c309823560f +Subproject commit feef55a4a2d583547923fe8a4dc5ce09d1616476 diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable index ebf264c..e3007cf 160000 --- a/lib/openzeppelin-contracts-upgradeable +++ b/lib/openzeppelin-contracts-upgradeable @@ -1 +1 @@ -Subproject commit ebf264cc4b812e6557ed7d539e947211acd5670c +Subproject commit e3007cfed2b6819decdd6f8217290f7cb12ff796 diff --git a/lib/utils b/lib/utils index 3b7a747..68f85f5 160000 --- a/lib/utils +++ b/lib/utils @@ -1 +1 @@ -Subproject commit 3b7a747213be6a1210b1c92d92c7688798a74edf +Subproject commit 68f85f572e730690e9ed0bd056eafcc6f85641f0 diff --git a/remappings.txt b/remappings.txt index 962e7d4..db19fb7 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1,7 +1,7 @@ ds-test/=lib/forge-std/lib/ds-test/src/ forge-std/=lib/forge-std/src/ -oz/=lib/new-oz/contracts/ -oz-upgradeable/=lib/new-oz-upgradeable/contracts/ +oz-v5/=lib/new-oz/contracts/ +oz-upgradeable-v5/=lib/new-oz-upgradeable/contracts/ lz/=lib/solidity-examples/contracts stringutils/=lib/solidity-stringutils borrow/=lib/borrow-contracts/contracts @@ -11,5 +11,7 @@ contracts/=contracts test/=test @openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts @openzeppelin/contracts/=lib/openzeppelin-contracts/contracts +oz-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts +oz/=lib/openzeppelin-contracts/contracts @chainlink/=lib/chainlink utils/=lib/utils \ No newline at end of file diff --git a/scripts/Constants.s.sol b/scripts/Constants.s.sol index fa5415d..1ad7eab 100644 --- a/scripts/Constants.s.sol +++ b/scripts/Constants.s.sol @@ -2,16 +2,16 @@ pragma solidity ^0.8.9; -import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { ITransmuter } from "transmuter/interfaces/ITransmuter.sol"; -import { IAgToken } from "borrow/interfaces/IAgToken.sol"; -import { ProxyAdmin } from "oz/proxy/transparent/ProxyAdmin.sol"; -import { Ownable } from "oz/access/Ownable.sol"; -import { CoreBorrow } from "borrow/coreBorrow/CoreBorrow.sol"; -import { ITreasury } from "borrow/interfaces/ITreasury.sol"; -import { TimelockController } from "oz/governance/TimelockController.sol"; -import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {ITransmuter} from "transmuter/interfaces/ITransmuter.sol"; +import {IAgToken} from "borrow/interfaces/IAgToken.sol"; +import {ProxyAdmin} from "oz-v5/proxy/transparent/ProxyAdmin.sol"; +import {Ownable} from "oz-v5/access/Ownable.sol"; +import {CoreBorrow} from "borrow/coreBorrow/CoreBorrow.sol"; +import {ITreasury} from "borrow/interfaces/ITreasury.sol"; +import {TimelockController} from "oz-v5/governance/TimelockController.sol"; +import {AngleGovernor} from "contracts/AngleGovernor.sol"; import "utils/src/Constants.sol"; import "./Interfaces.s.sol"; diff --git a/scripts/Interfaces.s.sol b/scripts/Interfaces.s.sol index b753a51..44f8574 100644 --- a/scripts/Interfaces.s.sol +++ b/scripts/Interfaces.s.sol @@ -1,7 +1,7 @@ pragma solidity ^0.8.19; -import { IAccessControl } from "oz/access/IAccessControl.sol"; -import { IAccessControlManager } from "interfaces/IAccessControlManager.sol"; +import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; +import {IAccessControlManager} from "interfaces/IAccessControlManager.sol"; interface IAccessControlCore { function core() external returns (address); diff --git a/scripts/Utils.s.sol b/scripts/Utils.s.sol index 42b68f7..59bde27 100644 --- a/scripts/Utils.s.sol +++ b/scripts/Utils.s.sol @@ -2,12 +2,12 @@ pragma solidity ^0.8.19; import "forge-std/Script.sol"; -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; -import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; -import { ITreasury } from "borrow/interfaces/ITreasury.sol"; +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; +import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import {ITreasury} from "borrow/interfaces/ITreasury.sol"; import "utils/src/CommonUtils.sol"; import "./Constants.s.sol"; diff --git a/scripts/deployment/DeployOnChainGovernance.s.sol b/scripts/deployment/DeployOnChainGovernance.s.sol index 73065ab..7f6d2c7 100644 --- a/scripts/deployment/DeployOnChainGovernance.s.sol +++ b/scripts/deployment/DeployOnChainGovernance.s.sol @@ -1,23 +1,23 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import { console } from "forge-std/console.sol"; -import { stdJson } from "forge-std/StdJson.sol"; +import {console} from "forge-std/console.sol"; +import {stdJson} from "forge-std/StdJson.sol"; import "stringutils/strings.sol"; import "../Utils.s.sol"; -import "oz/interfaces/IERC20.sol"; +import "oz-v5/interfaces/IERC20.sol"; -import { IveANGLEVotingDelegation } from "contracts/interfaces/IveANGLEVotingDelegation.sol"; -import { deployMockANGLE, deployVeANGLE } from "../test/DeployANGLE.s.sol"; -import { ERC20 } from "oz/token/ERC20/ERC20.sol"; +import {IveANGLEVotingDelegation} from "contracts/interfaces/IveANGLEVotingDelegation.sol"; +import {deployMockANGLE, deployVeANGLE} from "../test/DeployANGLE.s.sol"; +import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; import "contracts/interfaces/IveANGLE.sol"; import "../../test/external/VyperDeployer.sol"; -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; -import { VeANGLEVotingDelegation, ECDSA } from "contracts/VeANGLEVotingDelegation.sol"; +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; +import {VeANGLEVotingDelegation, ECDSA} from "contracts/VeANGLEVotingDelegation.sol"; /// @dev To deploy on a different chain, just replace the import of the `Constants.s.sol` file by a file which has the /// constants defined for the chain of your choice. diff --git a/scripts/deployment/DeploySideChainGovernance.s.sol b/scripts/deployment/DeploySideChainGovernance.s.sol index e50f187..ab21196 100644 --- a/scripts/deployment/DeploySideChainGovernance.s.sol +++ b/scripts/deployment/DeploySideChainGovernance.s.sol @@ -1,17 +1,17 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import { console } from "forge-std/console.sol"; -import { stdJson } from "forge-std/StdJson.sol"; +import {console} from "forge-std/console.sol"; +import {stdJson} from "forge-std/StdJson.sol"; import "stringutils/strings.sol"; import "../Utils.s.sol"; -import "oz/interfaces/IERC20.sol"; +import "oz-v5/interfaces/IERC20.sol"; -import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; -import { ERC20 } from "oz/token/ERC20/ERC20.sol"; +import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; +import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; /// @dev To deploy on a different chain, just replace the import of the `Constants.s.sol` file by a file which has the /// constants defined for the chain of your choice. diff --git a/scripts/interaction/CheckRoles.s.sol b/scripts/interaction/CheckRoles.s.sol new file mode 100644 index 0000000..d30cdc2 --- /dev/null +++ b/scripts/interaction/CheckRoles.s.sol @@ -0,0 +1,823 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +import {console} from "forge-std/console.sol"; +import {IVaultManager} from "borrow/interfaces/IVaultManager.sol"; +import {ITreasury} from "borrow/interfaces/ITreasury.sol"; +import {IAgToken} from "borrow/interfaces/IAgToken.sol"; +import {IERC721Metadata} from "oz-v5/token/ERC721/extensions/IERC721Metadata.sol"; +import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; +import {Utils} from "../Utils.s.sol"; +import "../Constants.s.sol"; +import "stringutils/strings.sol"; + +contract CheckRoles is Utils { + using strings for *; + + address constant oldDeployer = 0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185; + address constant oldKeeper = 0xcC617C6f9725eACC993ac626C7efC6B96476916E; + address constant oldKeeperPolygon = 0x5EB715d601C2F27f83Cb554b6B36e047822fB70a; + address constant oldKeeperPolygon2 = 0xEd42E58A303E20523A695CB31ac31df26C50397B; + address constant merklKeeper = 0x435046800Fb9149eE65159721A92cB7d50a7534b; + address constant tmpCoreBorrowUSD = 0x3fc5a1bd4d0A435c55374208A6A81535A1923039; + string constant angleLZ = "Angle LZ"; + + bytes32 public constant GUARDIAN_ROLE = keccak256("GUARDIAN_ROLE"); + bytes32 public constant GOVERNOR_ROLE = keccak256("GOVERNOR_ROLE"); + bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256("FLASHLOANER_TREASURY_ROLE"); + bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE"); + bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); + bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); + bytes32 public constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE"); + bytes32 public constant KEEPER_ROLE = keccak256("KEEPER_ROLE"); + bytes32 public constant DISTRIBUTOR_ROLE = keccak256("DISTRIBUTOR_ROLE"); + bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; + + address[] public allContracts; + + string public constant OUTPUT_PATH = "./scripts/roles.json"; + string private json; + uint256 private jsonIndex; + string private output; + string private outputActor; + string private jsonActor; + uint256 private jsonActorIndex; + + // TODO also check that all proxy contracts have been initialized + function run() external { + vm.label(oldDeployer, "Old Deployer"); + vm.label(oldKeeper, "Old Keeper"); + vm.label(oldKeeperPolygon, "Old Keeper Polygon"); + vm.label(oldKeeperPolygon2, "Old Keeper Polygon 2"); + vm.label(merklKeeper, "Merkl Keeper"); + + string memory jsonGlobal = "chain"; + uint256[] memory chainIds = vm.envUint("CHAIN_IDS", ","); + string memory finalOutput; + for (uint256 i = 0; i < chainIds.length; i++) { + json = vm.toString(chainIds[i]); + jsonIndex = 0; + output = ""; + _checkRoles(chainIds[i]); + finalOutput = vm.serializeString(jsonGlobal, vm.toString(chainIds[i]), output); + } + vm.writeFile(OUTPUT_PATH, finalOutput); + } + + function _checkRoles(uint256 chainId) public { + vm.selectFork(forkIdentifier[chainId]); + + allContracts = _getAllContracts(chainId); + // Address to check roles for + uint256 nbrActors = chainId == CHAIN_ETHEREUM ? 11 : 10; + address[] memory listAddressToCheck = new address[](nbrActors); + + { + address govMultisig = _chainToContract(chainId, ContractType.GovernorMultisig); + address guardianMultisig = _chainToContract(chainId, ContractType.GuardianMultisig); + address timelock = _chainToContract(chainId, ContractType.Timelock); + address coreBorrow = _chainToContract(chainId, ContractType.CoreBorrow); + address proxyAdmin = _chainToContract(chainId, ContractType.ProxyAdmin); + + vm.label(govMultisig, "Governor Multisig"); + vm.label(guardianMultisig, "Guardian Multisig"); + vm.label(timelock, "Timelock"); + vm.label(coreBorrow, "Core Borrow"); + vm.label(proxyAdmin, "Proxy Admin"); + + listAddressToCheck[0] = oldDeployer; + listAddressToCheck[1] = oldKeeper; + listAddressToCheck[2] = oldKeeperPolygon; + listAddressToCheck[3] = oldKeeperPolygon2; + listAddressToCheck[4] = merklKeeper; + listAddressToCheck[5] = govMultisig; + listAddressToCheck[6] = guardianMultisig; + listAddressToCheck[7] = timelock; + listAddressToCheck[8] = coreBorrow; + listAddressToCheck[9] = proxyAdmin; + if (chainId == CHAIN_ETHEREUM) listAddressToCheck[10] = _chainToContract(chainId, ContractType.Governor); + } + + { + // It would be better with a try catch but I don't know how why it doesn't work + if (chainId == CHAIN_ETHEREUM) { + // Contract to check roles on + ITransmuter transmuterEUR = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + ITransmuter transmuterUSD = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgUSD)); + IAngle angle = IAngle(_chainToContract(chainId, ContractType.Angle)); + ProposalSender proposalSender = + ProposalSender(payable(_chainToContract(chainId, ContractType.ProposalSender))); + IGaugeController gaugeController = + IGaugeController(_chainToContract(chainId, ContractType.GaugeController)); + ISmartWalletWhitelist smartWalletWhitelist = + ISmartWalletWhitelist(_chainToContract(chainId, ContractType.SmartWalletWhitelist)); + IVeAngle veAngle = IVeAngle(_chainToContract(chainId, ContractType.veANGLE)); + IVeBoostProxy veBoostProxy = IVeBoostProxy(_chainToContract(chainId, ContractType.veBoostProxy)); + IGenericAccessControl merklMiddleman = + IGenericAccessControl(_chainToContract(chainId, ContractType.MerklMiddleman)); + + if (!_authorizedCore(chainId, address(transmuterEUR.accessControlManager()))) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat( + "Transmuter EUR - wrong access control manager: ", + vm.toString(address(transmuterEUR.accessControlManager())) + ) + ); + jsonIndex++; + } + if (!_authorizedCore(chainId, address(transmuterUSD.accessControlManager()))) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat( + "Transmuter USD - wrong access control manager: ", + vm.toString(address(transmuterUSD.accessControlManager())) + ) + ); + jsonIndex++; + } + if (!_authorizedMinter(chainId, angle.minter())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("Angle - minter role: ", vm.toString(angle.minter())) + ); + jsonIndex++; + } + if (!_authorizedOwner(chainId, proposalSender.owner())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("Proposal Sender - owner: ", vm.toString(proposalSender.owner())) + ); + jsonIndex++; + } + if (!_authorizedCoreMerkl(chainId, address(merklMiddleman.accessControlManager()))) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat( + "Merkl Middleman - wrong access control manager: ", + vm.toString(address(merklMiddleman.accessControlManager())) + ) + ); + jsonIndex++; + } + if (!_authorizedOwner(chainId, gaugeController.admin())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("Gauge Controller - admin role: ", vm.toString(gaugeController.admin())) + ); + jsonIndex++; + } + if (!_authorizedOwner(chainId, gaugeController.future_admin())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat( + "Gauge Controller - future admin role: ", vm.toString(gaugeController.future_admin()) + ) + ); + jsonIndex++; + } + if (!_authorizedOwner(chainId, smartWalletWhitelist.admin())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("Smart Wallet Whitelist - admin: ", vm.toString(smartWalletWhitelist.admin())) + ); + jsonIndex++; + } + if (!_authorizedOwner(chainId, smartWalletWhitelist.future_admin())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat( + "Smart Wallet Whitelist - future admin: ", vm.toString(smartWalletWhitelist.future_admin()) + ) + ); + jsonIndex++; + } + if (!_authorizedOwner(chainId, veAngle.admin())) { + output = vm.serializeString( + json, vm.toString(jsonIndex), string.concat("veANGLE - admin: ", vm.toString(veAngle.admin())) + ); + jsonIndex++; + } + if (!_authorizedOwner(chainId, veAngle.future_admin())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("veANGLE - future admin: ", vm.toString(veAngle.future_admin())) + ); + jsonIndex++; + } + if (!_authorizedOwner(chainId, veBoostProxy.admin())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("veBoostProxy - admin: ", vm.toString(veBoostProxy.admin())) + ); + jsonIndex++; + } + if (!_authorizedOwner(chainId, veBoostProxy.future_admin())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("veBoostProxy - future admin: ", vm.toString(veBoostProxy.future_admin())) + ); + jsonIndex++; + } + } else { + ProposalReceiver proposalReceiver = + ProposalReceiver(payable(_chainToContract(chainId, ContractType.ProposalReceiver))); + if (!_authorizedOwner(chainId, proposalReceiver.owner())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("Proposal Receiver - owner: ", vm.toString(proposalReceiver.owner())) + ); + jsonIndex++; + } + } + + if (_isCoreChain(chainId)) { + IAccessControlCore angleRouter = IAccessControlCore(_chainToContract(chainId, ContractType.AngleRouter)); + if (!_authorizedCore(chainId, angleRouter.core())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("Angle Router - core: ", vm.toString(angleRouter.core())) + ); + jsonIndex++; + } + } + + if (_isAngleDeployed(chainId) && chainId != CHAIN_POLYGON) { + _checkOnLZToken( + chainId, + ILayerZeroBridge(_chainToContract(chainId, ContractType.AngleLZ)), + angleLZ, + ContractType.Angle, + ContractType.TreasuryAgEUR + ); + } + + if (_isMerklDeployed(chainId)) { + IAccessControlCore distributionCreator = + IAccessControlCore(_chainToContract(chainId, ContractType.DistributionCreator)); + IAccessControlCore distributor = IAccessControlCore(_chainToContract(chainId, ContractType.Distributor)); + if (!_authorizedCoreMerkl(chainId, address(distributionCreator.core()))) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("Distribution creator - wrong core: ", vm.toString(distributionCreator.core())) + ); + jsonIndex++; + } + if (!_authorizedCoreMerkl(chainId, address(distributor.core()))) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("Distributor - wrong core: ", vm.toString(distributor.core())) + ); + jsonIndex++; + } + } + + if (_isSavingsDeployed(chainId)) { + ISavings stEUR = ISavings(_chainToContract(chainId, ContractType.StEUR)); + ISavings stUSD = ISavings(_chainToContract(chainId, ContractType.StUSD)); + if (!_authorizedCore(chainId, address(stEUR.accessControlManager()))) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat( + "StEUR - wrong access control manager: ", vm.toString(stEUR.accessControlManager()) + ) + ); + jsonIndex++; + } + if (!_authorizedCore(chainId, address(stUSD.accessControlManager()))) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat( + "StUSD - wrong access control manager: ", vm.toString(stUSD.accessControlManager()) + ) + ); + jsonIndex++; + } + } + + ProxyAdmin proxyAdmin = ProxyAdmin(_chainToContract(chainId, ContractType.ProxyAdmin)); + + if (!_authorizedProxyAdminOwner(chainId, proxyAdmin.owner())) { + output = vm.serializeString( + json, + vm.toString(jsonIndex), + string.concat("Proxy Admin - owner: ", vm.toString(proxyAdmin.owner())) + ); + jsonIndex++; + } + _checkOnLZToken( + chainId, + ILayerZeroBridge(_chainToContract(chainId, ContractType.AgEURLZ)), + "AgEUR LZ", + ContractType.AgEUR, + ContractType.TreasuryAgEUR + ); + _checkOnLZToken( + chainId, + ILayerZeroBridge(_chainToContract(chainId, ContractType.AgUSDLZ)), + "AgUSD LZ", + ContractType.AgUSD, + ContractType.TreasuryAgUSD + ); + _checkVaultManagers(chainId, ContractType.TreasuryAgEUR); + _checkVaultManagers(chainId, ContractType.TreasuryAgUSD); + + if (_revertOnWrongFunctioCall(chainId)) { + for (uint256 i = 0; i < allContracts.length; i++) { + _checkGlobalAccessControl(chainId, IGenericAccessControl(allContracts[i])); + } + } + } + + // Contract to check roles on + IAgToken agEUR = IAgToken(_chainToContract(chainId, ContractType.AgEUR)); + IAgToken agUSD = IAgToken(_chainToContract(chainId, ContractType.AgUSD)); + CoreBorrow core = CoreBorrow(_chainToContract(chainId, ContractType.CoreBorrow)); + TimelockControllerWithCounter timelock = + TimelockControllerWithCounter(payable(_chainToContract(chainId, ContractType.Timelock))); + for (uint256 i = 0; i < listAddressToCheck.length; i++) { + outputActor = ""; + jsonActor = vm.toString(listAddressToCheck[i]); + jsonActorIndex = 0; + address actor = listAddressToCheck[i]; + if (agEUR.isMinter(actor) && !_authorizedMinter(chainId, actor)) { + outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "AgEUR - minter role"); + jsonActorIndex++; + } + if (agUSD.isMinter(actor) && !_authorizedMinter(chainId, actor)) { + outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "AgUSD - minter role"); + jsonActorIndex++; + } + if (core.hasRole(GOVERNOR_ROLE, actor) && !_authorizedGovernor(chainId, actor)) { + outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Borrow - governor role"); + jsonActorIndex++; + } + if (core.hasRole(GUARDIAN_ROLE, actor) && !_authorizedGuardian(chainId, actor)) { + outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Borrow - guardian role"); + jsonActorIndex++; + } + if (core.hasRole(FLASHLOANER_TREASURY_ROLE, actor) && !_authorizedFlashloaner(chainId, actor)) { + outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Borrow - flashloan role"); + jsonActorIndex++; + } + if (timelock.hasRole(PROPOSER_ROLE, actor) && !_authorizedProposer(chainId, actor)) { + outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Timelock - proposer role"); + jsonActorIndex++; + } + if (timelock.hasRole(CANCELLER_ROLE, actor) && !_authorizedCanceller(chainId, actor)) { + outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Timelock - canceller role"); + jsonActorIndex++; + } + if (timelock.hasRole(EXECUTOR_ROLE, actor) && !_authorizedExecutor(chainId, actor)) { + outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Timelock - executor role"); + jsonActorIndex++; + } + if (timelock.hasRole(DEFAULT_ADMIN_ROLE, actor) && !_authorizeDefaultAdmin(chainId, actor)) { + outputActor = + vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Timelock - default admin role"); + jsonActorIndex++; + } + + if (_revertOnWrongFunctioCall(chainId)) { + for (uint256 j = 0; j < allContracts.length; j++) { + _checkAddressAccessControl(chainId, IGenericAccessControl(allContracts[j]), actor); + } + } + + if (_isMerklDeployed(chainId)) { + CoreBorrow coreMerkl = CoreBorrow(_chainToContract(chainId, ContractType.CoreMerkl)); + if (coreMerkl.hasRole(GOVERNOR_ROLE, actor) && !_authorizedGovernor(chainId, actor)) { + outputActor = + vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Merkl - governor role"); + jsonActorIndex++; + } + if (coreMerkl.hasRole(GUARDIAN_ROLE, actor) && !_authorizedGuardian(chainId, actor)) { + outputActor = + vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Merkl - guardian role"); + jsonActorIndex++; + } + // No one should have this role + if (coreMerkl.hasRole(FLASHLOANER_TREASURY_ROLE, actor)) { + outputActor = + vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Merkl - flashloan role"); + jsonActorIndex++; + } + } + + if (chainId == CHAIN_ETHEREUM) { + IAccessControl angleDistributor = + IAccessControl(_chainToContract(chainId, ContractType.AngleDistributor)); + if (angleDistributor.hasRole(GOVERNOR_ROLE, actor) && !_authorizedGovernor(chainId, actor)) { + outputActor = + vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Angle distributor - governor role"); + jsonActorIndex++; + } + if (angleDistributor.hasRole(GUARDIAN_ROLE, actor) && !_authorizedGuardian(chainId, actor)) { + outputActor = + vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Angle distributor - guardian role"); + jsonActorIndex++; + } + } + if (outputActor.toSlice().len() != 0) { + output = vm.serializeString(json, vm.toString(listAddressToCheck[i]), outputActor); + } + } + } + + /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + CHECKS + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + + function _checkOnLZToken( + uint256 chainId, + ILayerZeroBridge token, + string memory nameToken, + ContractType contractType, + ContractType contractTypeTreasury + ) internal returns (bool) { + if (token.canonicalToken() != _chainToContract(chainId, contractType)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(nameToken, " - wrong canonical token: ", vm.toString(token.canonicalToken())) + ); + jsonActorIndex++; + } + if (contractType == ContractType.Angle) { + if (!_authorizedCore(chainId, token.coreBorrow())) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(nameToken, " - wrong core borrow: ", vm.toString(token.coreBorrow())) + ); + jsonActorIndex++; + } + } else { + if (token.treasury() != _chainToContract(chainId, contractTypeTreasury)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(nameToken, " - wrong treasury: ", vm.toString(token.treasury())) + ); + jsonActorIndex++; + } + } + if (token.lzEndpoint() != address(_lzEndPoint(chainId))) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(nameToken, " - wrong endpoint: ", vm.toString(token.lzEndpoint())) + ); + jsonActorIndex++; + } + } + + function _checkVaultManagers(uint256 chainId, ContractType treasuryType) internal { + ITreasury treasury = ITreasury(_chainToContract(chainId, treasuryType)); + uint256 i; + while (true) { + try treasury.vaultManagerList(i) returns (address vault) { + if (address(IVaultManager(vault).treasury()) != address(treasury)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat( + IERC721Metadata(vault).name(), + "Vault Manager - wrong treasury: ", + vm.toString(address(treasury)) + ) + ); + jsonActorIndex++; + } + i++; + } catch { + break; + } + } + } + + function _checkGlobalAccessControl(uint256 chainId, IGenericAccessControl contractToCheck) public { + try contractToCheck.owner() returns (address owner) { + if (!_authorizedOwner(chainId, owner)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " owner: ", vm.toString(owner)) + ); + jsonActorIndex++; + } + } catch {} + try contractToCheck.minter() returns (address minter) { + if (!_authorizedOwner(chainId, minter)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " minter: ", vm.toString(minter)) + ); + jsonActorIndex++; + } + } catch {} + try contractToCheck.treasury() returns (address treasury) { + if (!_authorizedTreasury(chainId, treasury)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " treasury: ", vm.toString(treasury)) + ); + jsonActorIndex++; + } + } catch {} + try contractToCheck.coreBorrow() returns (address coreBorrow) { + if (!_authorizedCore(chainId, coreBorrow)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " core borrow: ", vm.toString(coreBorrow)) + ); + jsonActorIndex++; + } + } catch {} + try contractToCheck.core() returns (address coreBorrow) { + if (!_authorizedCore(chainId, coreBorrow)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " core borrow: ", vm.toString(coreBorrow)) + ); + jsonActorIndex++; + } + } catch {} + try contractToCheck.admin() returns (address admin) { + if (!_authorizedOwner(chainId, admin)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " admin: ", vm.toString(admin)) + ); + jsonActorIndex++; + } + } catch {} + try contractToCheck.future_admin() returns (address future_admin) { + if (!_authorizedOwner(chainId, future_admin)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " future admin: ", vm.toString(future_admin)) + ); + jsonActorIndex++; + } + } catch {} + } + + function _checkAddressAccessControl(uint256 chainId, IGenericAccessControl contractToCheck, address addressToCheck) + public + { + try contractToCheck.isMinter(addressToCheck) returns (bool isMinter) { + if (isMinter && !_authorizedMinter(chainId, addressToCheck)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " minter: ") + ); + jsonActorIndex++; + } + } catch {} + try contractToCheck.isTrusted(addressToCheck) returns (bool isTrusted) { + if (isTrusted && !_authorizedTrusted(chainId, addressToCheck)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " trusted: ") + ); + jsonActorIndex++; + } + } catch {} + try contractToCheck.trusted(addressToCheck) returns (uint256 isTrusted) { + if (isTrusted > 0 && !_authorizedTrusted(chainId, addressToCheck)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " trusted: ") + ); + jsonActorIndex++; + } + } catch {} + bytes32[] memory listRoles = _listRoles(); + for (uint256 i = 0; i < listRoles.length; i++) { + try contractToCheck.hasRole(listRoles[i], addressToCheck) returns (bool hasRole) { + if (hasRole && !_mapCheckRoles(i, chainId, addressToCheck)) { + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + string.concat(vm.toString(address(contractToCheck)), " have role: ", _nameRoles(i)) + ); + jsonActorIndex++; + } + } catch {} + } + } + + /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + CONSTANTS + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + + function _listRoles() internal pure returns (bytes32[] memory listRoles) { + listRoles = new bytes32[](10); + listRoles[0] = GOVERNOR_ROLE; + listRoles[1] = GUARDIAN_ROLE; + listRoles[2] = FLASHLOANER_TREASURY_ROLE; + listRoles[3] = TIMELOCK_ADMIN_ROLE; + listRoles[4] = PROPOSER_ROLE; + listRoles[5] = EXECUTOR_ROLE; + listRoles[6] = CANCELLER_ROLE; + listRoles[7] = KEEPER_ROLE; + listRoles[8] = DISTRIBUTOR_ROLE; + listRoles[9] = DEFAULT_ADMIN_ROLE; + } + + function _nameRoles(uint256 index) internal pure returns (string memory nameRole) { + if (index == 0) return "GOVERNOR"; + if (index == 1) return "GUARDIAN"; + if (index == 2) return "FLASHLOANER_TREASURY"; + if (index == 3) return "TIMELOCK_ADMIN"; + if (index == 4) return "PROPOSER"; + if (index == 5) return "EXECUTOR"; + if (index == 6) return "CANCELLER"; + if (index == 7) return "KEEPER"; + if (index == 8) return "DISTRIBUTOR"; + if (index == 9) return "DEFAULT_ADMIN"; + } + + function _mapCheckRoles(uint256 index, uint256 chainId, address addressToCheck) internal returns (bool) { + if (index == 0) return _authorizedGovernor(chainId, addressToCheck); + if (index == 1) return _authorizedGuardian(chainId, addressToCheck); + if (index == 2) return _authorizedFlashloaner(chainId, addressToCheck); + if (index == 3) return _authorizedTimelockAdmin(chainId, addressToCheck); + if (index == 4) return _authorizedProposer(chainId, addressToCheck); + if (index == 5) return _authorizedExecutor(chainId, addressToCheck); + if (index == 6) return _authorizedCanceller(chainId, addressToCheck); + if (index == 7) return _authorizedKeeper(chainId, addressToCheck); + if (index == 8) return _authorizedDistributor(chainId, addressToCheck); + if (index == 9) return _authorizeDefaultAdmin(chainId, addressToCheck); + } + + function _isCoreChain(uint256 chainId) internal pure returns (bool) { + return chainId == CHAIN_ETHEREUM || chainId == CHAIN_ARBITRUM || chainId == CHAIN_AVALANCHE + || chainId == CHAIN_OPTIMISM || chainId == CHAIN_POLYGON || chainId == CHAIN_GNOSIS; + } + + function _isAngleDeployed(uint256 chainId) internal pure returns (bool) { + return chainId == CHAIN_ETHEREUM || chainId == CHAIN_ARBITRUM || chainId == CHAIN_AURORA + || chainId == CHAIN_AVALANCHE || chainId == CHAIN_BNB || chainId == CHAIN_FANTOM || chainId == CHAIN_OPTIMISM + || chainId == CHAIN_POLYGON; + } + + function _isMerklDeployed(uint256 chainId) internal pure returns (bool) { + return chainId == CHAIN_ETHEREUM || chainId == CHAIN_ARBITRUM || chainId == CHAIN_AVALANCHE + || chainId == CHAIN_BASE || chainId == CHAIN_BNB || chainId == CHAIN_GNOSIS || chainId == CHAIN_LINEA + || chainId == CHAIN_MANTLE || chainId == CHAIN_OPTIMISM || chainId == CHAIN_POLYGON + || chainId == CHAIN_POLYGONZKEVM; + } + + function _isSavingsDeployed(uint256 chainId) internal pure returns (bool) { + return chainId == CHAIN_ETHEREUM || chainId == CHAIN_ARBITRUM || chainId == CHAIN_AVALANCHE + || chainId == CHAIN_BASE || chainId == CHAIN_BNB || chainId == CHAIN_CELO || chainId == CHAIN_GNOSIS + || chainId == CHAIN_OPTIMISM || chainId == CHAIN_POLYGON || chainId == CHAIN_POLYGONZKEVM; + } + + function _revertOnWrongFunctioCall(uint256 chainId) internal pure returns (bool) { + return chainId != CHAIN_CELO; + } + + /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + HELPERS + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + + function _authorizedOwner(uint256 chainId, address owner) internal returns (bool) { + return owner == address(0) || owner == _chainToContract(chainId, ContractType.GovernorMultisig) + // owner == _chainToContract(chainId, ContractType.GuardianMultisig) || + || owner == _chainToContract(chainId, ContractType.Timelock) + || owner == _chainToContract(chainId, ContractType.CoreBorrow) + || owner == _chainToContract(chainId, ContractType.ProxyAdmin) + || ((chainId == CHAIN_SOURCE) ? owner == _chainToContract(chainId, ContractType.Governor) : false); + } + + function _authorizedGovernor(uint256 chainId, address governor) internal returns (bool) { + return governor == address(0) || governor == _chainToContract(chainId, ContractType.GovernorMultisig) + || governor == _chainToContract(chainId, ContractType.Timelock) + || governor == _chainToContract(chainId, ContractType.CoreBorrow) + || governor == _chainToContract(chainId, ContractType.ProxyAdmin) + || ((chainId == CHAIN_SOURCE) ? governor == _chainToContract(chainId, ContractType.Governor) : false); + } + + function _authorizedGuardian(uint256 chainId, address guardian) internal returns (bool) { + return guardian == address(0) || guardian == _chainToContract(chainId, ContractType.GovernorMultisig) + || guardian == _chainToContract(chainId, ContractType.GuardianMultisig) + || guardian == _chainToContract(chainId, ContractType.Timelock) + || guardian == _chainToContract(chainId, ContractType.CoreBorrow) + || guardian == _chainToContract(chainId, ContractType.ProxyAdmin) + || ((chainId == CHAIN_SOURCE) ? guardian == _chainToContract(chainId, ContractType.Governor) : false); + } + + /// @notice Vault Managers are also minter + function _authorizedMinter(uint256 chainId, address minter) internal returns (bool) { + return minter == address(0) || minter == _chainToContract(chainId, ContractType.GovernorMultisig) + || minter == _chainToContract(chainId, ContractType.Timelock); + } + + function _authorizedCore(uint256 chainId, address core) internal returns (bool) { + // TODO remove tmp core when USD linked to real one + return core == _chainToContract(chainId, ContractType.CoreBorrow) || core == tmpCoreBorrowUSD; + } + + function _authorizedCoreMerkl(uint256 chainId, address core) internal returns (bool) { + return core == _chainToContract(chainId, ContractType.CoreMerkl); + } + + // TODO need to be fine grained for multiple stablecoins + function _authorizedFlashloaner(uint256 chainId, address loaner) internal returns (bool) { + return loaner == address(0) || loaner == _chainToContract(chainId, ContractType.TreasuryAgEUR) + || loaner == _chainToContract(chainId, ContractType.TreasuryAgUSD); + } + + function _authorizedProposer(uint256 chainId, address proposer) internal returns (bool) { + return (chainId == CHAIN_SOURCE) + ? proposer == _chainToContract(chainId, ContractType.Governor) + : proposer == _chainToContract(chainId, ContractType.ProposalReceiver); + } + + function _authorizedExecutor(uint256 chainId, address executor) internal returns (bool) { + return executor == _chainToContract(chainId, ContractType.GuardianMultisig); + } + + function _authorizedCanceller(uint256 chainId, address canceller) internal returns (bool) { + return canceller == _chainToContract(chainId, ContractType.GuardianMultisig); + } + + function _authorizedTimelockAdmin(uint256 chainId, address admin) internal returns (bool) { + return false; + } + + function _authorizeDefaultAdmin(uint256 chainId, address admin) internal returns (bool) { + return false; + } + + function _authorizedKeeper(uint256 chainId, address keeper) internal returns (bool) { + // return ( + // (chainId == CHAIN_POLYGON) + // ? (keeper == oldKeeperPolygon || keeper == oldKeeperPolygon2) + // : keeper == oldKeeper + // ); + return false; + } + + function _authorizedTrusted(uint256 chainId, address trusted) internal returns (bool) { + return trusted == _chainToContract(chainId, ContractType.GovernorMultisig) + || trusted == _chainToContract(chainId, ContractType.GuardianMultisig) + || trusted == _chainToContract(chainId, ContractType.Timelock) + || trusted == _chainToContract(chainId, ContractType.CoreBorrow) + || trusted == _chainToContract(chainId, ContractType.ProxyAdmin) + // trusted == oldDeployer || + // trusted == oldKeeper || + // trusted == oldKeeperPolygon || + // trusted == oldKeeperPolygon2 || + // trusted == merklKeeper || + || ((chainId == CHAIN_SOURCE) ? trusted == _chainToContract(chainId, ContractType.Governor) : false); + } + + function _authorizedDistributor(uint256 chainId, address distributor) internal returns (bool) { + return (chainId == CHAIN_ETHEREUM) + ? distributor == _chainToContract(chainId, ContractType.AngleDistributor) + : false; + } + + function _authorizedProxyAdminOwner(uint256 chainId, address owner) internal returns (bool) { + return owner == _chainToContract(chainId, ContractType.GovernorMultisig); + } + + function _authorizedTreasury(uint256 chainId, address treasury) internal returns (bool) { + return treasury == _chainToContract(chainId, ContractType.TreasuryAgEUR) + || treasury == _chainToContract(chainId, ContractType.TreasuryAgUSD); + } +} diff --git a/scripts/interfaces/ITransmuter.sol b/scripts/interfaces/ITransmuter.sol new file mode 100644 index 0000000..867505f --- /dev/null +++ b/scripts/interfaces/ITransmuter.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.19; + +import "transmuter/transmuter/Storage.sol" as Storage; + +interface OldTransmuter { + function getOracle(address) + external + view + returns (Storage.OracleReadType, Storage.OracleReadType, bytes memory, bytes memory); +} diff --git a/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol b/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol index 39d9f04..72db6f0 100644 --- a/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol +++ b/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.20; -import { console } from "forge-std/console.sol"; -import { Wrapper } from "../Wrapper.s.sol"; -import { GovernorVotesQuorumFraction } from "oz/governance/extensions/GovernorVotesQuorumFraction.sol"; -import { GovernorShortCircuit } from "contracts/external/GovernorShortCircuit.sol"; +import {console} from "forge-std/console.sol"; +import {Wrapper} from "../Wrapper.s.sol"; +import {GovernorVotesQuorumFraction} from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; +import {GovernorShortCircuit} from "contracts/external/GovernorShortCircuit.sol"; import "../../Constants.s.sol"; contract IncreaseQuorum is Wrapper { @@ -42,22 +42,21 @@ contract IncreaseQuorum is Wrapper { uint256[] memory chainIds = vm.envUint("CHAIN_IDS", ","); string memory description = "ipfs://QmXpXXaUYCtUb4w9T2kEtu8t1JwpSv7tqTFwMETKgimcsf"; - /** TODO complete */ + /** + * TODO complete + */ uint256 quorum = 20; uint256 quorumShortCircuit = 75; - /** END complete */ - + /** + * END complete + */ for (uint256 i = 0; i < chainIds.length; i++) { _setQuorum(chainIds[i], quorum); _setQuorumShortCircuit(chainIds[i], quorumShortCircuit); } - ( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - uint256[] memory chainIds2 - ) = _wrap(subCalls); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas, uint256[] memory chainIds2) = + _wrap(subCalls); _serializeJson(targets, values, calldatas, chainIds2, description); } } diff --git a/scripts/proposals/timelock/AddExecutor.s.sol b/scripts/proposals/timelock/AddExecutor.s.sol index 0449521..4e3be01 100644 --- a/scripts/proposals/timelock/AddExecutor.s.sol +++ b/scripts/proposals/timelock/AddExecutor.s.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.20; -import { console } from "forge-std/console.sol"; -import { IAccessControl } from "oz/access/IAccessControl.sol"; -import { Wrapper } from "../Wrapper.s.sol"; +import {console} from "forge-std/console.sol"; +import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; +import {Wrapper} from "../Wrapper.s.sol"; import "../../Constants.s.sol"; contract AddExecutor is Wrapper { @@ -16,10 +16,7 @@ contract AddExecutor is Wrapper { bytes32 EXECUTOR_ROLE = TimelockController(payable(timelock)).EXECUTOR_ROLE(); subCalls.push( SubCall( - chainId, - timelock, - 0, - abi.encodeWithSelector(IAccessControl.grantRole.selector, EXECUTOR_ROLE, executor) + chainId, timelock, 0, abi.encodeWithSelector(IAccessControl.grantRole.selector, EXECUTOR_ROLE, executor) ) ); } @@ -28,20 +25,19 @@ contract AddExecutor is Wrapper { uint256[] memory chainIds = vm.envUint("CHAIN_IDS", ","); string memory description = "ipfs://QmYv2RGPpZh78vCsQPd6R4HMJcGH61Mi2oL5a4eXMei61n"; - /** TODO complete */ + /** + * TODO complete + */ address executor = address(0); - /** END complete */ - + /** + * END complete + */ for (uint256 i = 0; i < chainIds.length; i++) { _addExecutorRole(chainIds[i], executor); } - ( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas, - uint256[] memory chainIds2 - ) = _wrap(subCalls); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas, uint256[] memory chainIds2) = + _wrap(subCalls); _serializeJson(targets, values, calldatas, chainIds2, description); } } diff --git a/scripts/proposals/transmuter/README.md b/scripts/proposals/transmuter/README.md new file mode 100644 index 0000000..3704bf2 --- /dev/null +++ b/scripts/proposals/transmuter/README.md @@ -0,0 +1,50 @@ +# Guide to test facets update + +## Angle-Tranmuter repo + +To test that new facets are non breaking changes run: +```bash +yarn test --match-contract UpdateTransmuterFacets +``` + +If all tests are passing you can move on to deployment. + +You first need to make fork Ethereum: + +```bash +yarn fork +``` + +and then when prompted choose Ethereum. + +Open a new terminal and deploy the new facets with: + +```bash +yarn deploy:fork UpdateTransmuterFacets +``` + +Get the addresses for the deployed contracts, you will get a log of this format: + +```bash + Getters deployed at: 0x0.... + Redeemer deployed at: 0x0.... + SettersGovernor deployed at: 0x0.... + Swapper deployed at: 0x0.... + Oracle deployed at: 0x0.... +``` + +## Angle-Governance repo + +Update the address previously logged into `./TransmuterUtils.s.sol` and run: + +```bash +yarn create:proposal +``` + +You will be prompted to specify which proposal you want to submit, enter: + +```bash +TransmuterUpdateFacets +``` + +If will then propose to post the proposal --> Say NO \ No newline at end of file diff --git a/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol new file mode 100644 index 0000000..9d8402b --- /dev/null +++ b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.20; + +import {console} from "forge-std/console.sol"; +import {stdJson} from "forge-std/StdJson.sol"; +import {Wrapper} from "../Wrapper.s.sol"; +import {TransmuterUtils} from "./TransmuterUtils.s.sol"; +import "../../Constants.s.sol"; +import {OldTransmuter} from "../../interfaces/ITransmuter.sol"; + +import {IERC20} from "oz-v5/token/ERC20/IERC20.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import {Getters} from "transmuter/transmuter/facets/Getters.sol"; +import {Oracle} from "transmuter/transmuter/facets/Oracle.sol"; +// import {Redeemer} from "transmuter/transmuter/facets/Redeemer.sol"; +import {SettersGovernor} from "transmuter/transmuter/facets/SettersGovernor.sol"; +// import {Swapper} from "transmuter/transmuter/facets/Swapper.sol"; +import {ITransmuter, IDiamondCut, ISettersGovernor} from "transmuter/interfaces/ITransmuter.sol"; + +contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { + using stdJson for string; + + string[] facetNames; + string[] replaceFacetNames; + string[] addFacetNames; + address[] facetAddressList; + + ITransmuter transmuter; + IERC20 agEUR; + address governor; + + SubCall[] private subCalls; + + function _generateFacets() private { + // First generate the selectors + facetNames.push("DiamondCut"); + facetNames.push("DiamondLoupe"); + facetNames.push("Getters"); + facetNames.push("Oracle"); + facetNames.push("Redeemer"); + facetNames.push("RewardHandler"); + facetNames.push("SettersGovernor"); + facetNames.push("SettersGuardian"); + facetNames.push("Swapper"); + facetNames.push("DiamondEtherscan"); + + string memory json = ""; + for (uint256 i = 0; i < facetNames.length; ++i) { + bytes4[] memory selectors = _generateSelectors(facetNames[i]); + vm.serializeBytes32(json, facetNames[i], _arrayBytes4ToBytes32(selectors)); + } + string memory finalJson = vm.serializeString(json, "useless", ""); + vm.writeJson(finalJson, JSON_SELECTOR_PATH); + } + + function _updateFacets(uint256 chainId) private { + uint256 executionChainId = chainId; + chainId = chainId != 0 ? chainId : CHAIN_SOURCE; + + vm.selectFork(forkIdentifier[executionChainId]); + + transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + + Storage.FacetCut[] memory replaceCut; + Storage.FacetCut[] memory addCut; + + replaceFacetNames.push("Getters"); + facetAddressList.push(GETTERS); + + replaceFacetNames.push("Redeemer"); + facetAddressList.push(REDEEMER); + + replaceFacetNames.push("SettersGovernor"); + facetAddressList.push(SETTERS_GOVERNOR); + + replaceFacetNames.push("Swapper"); + facetAddressList.push(SWAPPER); + + addFacetNames.push("Oracle"); + facetAddressList.push(ORACLE); + + string memory json = vm.readFile(JSON_SELECTOR_PATH); + { + // Build appropriate payload + uint256 n = replaceFacetNames.length; + replaceCut = new Storage.FacetCut[](n); + for (uint256 i = 0; i < n; ++i) { + // Get Selectors from json + bytes4[] memory selectors = + _arrayBytes32ToBytes4(json.readBytes32Array(string.concat("$.", replaceFacetNames[i]))); + + replaceCut[i] = Storage.FacetCut({ + facetAddress: facetAddressList[i], + action: Storage.FacetCutAction.Replace, + functionSelectors: selectors + }); + } + } + + { + // Build appropriate payload + uint256 r = replaceFacetNames.length; + uint256 n = addFacetNames.length; + addCut = new Storage.FacetCut[](n); + for (uint256 i = 0; i < n; ++i) { + // Get Selectors from json + bytes4[] memory selectors = + _arrayBytes32ToBytes4(json.readBytes32Array(string.concat("$.", addFacetNames[i]))); + addCut[i] = Storage.FacetCut({ + facetAddress: facetAddressList[r + i], + action: Storage.FacetCutAction.Add, + functionSelectors: selectors + }); + } + } + + // Get the previous oracles configs + ( + Storage.OracleReadType oracleTypeEUROC, + Storage.OracleReadType targetTypeEUROC, + bytes memory oracleDataEUROC, + bytes memory targetDataEUROC + ) = OldTransmuter(address(transmuter)).getOracle(address(EUROC)); + + (Storage.OracleReadType oracleTypeBC3M,, bytes memory oracleDataBC3M,) = + OldTransmuter(address(transmuter)).getOracle(address(BC3M)); + + (,,,, uint256 currentBC3MPrice) = transmuter.getOracleValues(address(BC3M)); + + bytes memory callData; + // set the right implementations + subCalls.push( + SubCall( + chainId, + address(transmuter), + 0, + abi.encodeWithSelector(IDiamondCut.diamondCut.selector, replaceCut, address(0), callData) + ) + ); + subCalls.push( + SubCall( + chainId, + address(transmuter), + 0, + abi.encodeWithSelector(IDiamondCut.diamondCut.selector, addCut, address(0), callData) + ) + ); + + // update the oracles + subCalls.push( + SubCall( + chainId, + address(transmuter), + 0, + abi.encodeWithSelector( + ISettersGovernor.setOracle.selector, + EUROC, + abi.encode( + oracleTypeEUROC, + targetTypeEUROC, + oracleDataEUROC, + targetDataEUROC, + abi.encode(FIREWALL_MINT_EUROC, FIREWALL_BURN_EUROC) + ) + ) + ) + ); + + subCalls.push( + SubCall( + chainId, + address(transmuter), + 0, + abi.encodeWithSelector( + ISettersGovernor.setOracle.selector, + BC3M, + abi.encode( + oracleTypeBC3M, + Storage.OracleReadType.MAX, + oracleDataBC3M, + abi.encode(currentBC3MPrice, DEVIATION_THRESHOLD_BC3M, uint96(block.timestamp), HEARTBEAT), + abi.encode(FIREWALL_MINT_BC3M, FIREWALL_BURN_BC3M) + ) + ) + ) + ); + } + + function run() external { + uint256[] memory chainIds = vm.envUint("CHAIN_IDS", ","); + string memory description = "ipfs://"; + + _generateFacets(); + for (uint256 i = 0; i < chainIds.length; i++) { + _updateFacets(chainIds[i]); + } + + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas, uint256[] memory chainIds2) = + _wrap(subCalls); + _serializeJson(targets, values, calldatas, chainIds2, description); + } +} diff --git a/scripts/proposals/transmuter/TransmuterUtils.s.sol b/scripts/proposals/transmuter/TransmuterUtils.s.sol new file mode 100644 index 0000000..59b1251 --- /dev/null +++ b/scripts/proposals/transmuter/TransmuterUtils.s.sol @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +import "forge-std/Script.sol"; +import {StdAssertions} from "forge-std/Test.sol"; +import "stringutils/strings.sol"; + +import {CommonUtils} from "utils/src/CommonUtils.sol"; +import {ContractType, BASE_18} from "utils/src/Constants.sol"; + +contract TransmuterUtils is Script, CommonUtils { + using strings for *; + + string constant JSON_SELECTOR_PATH = "./selectors.json"; + uint256 constant BPS = 1e14; + + address constant EUROC = 0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c; + address constant EUROE = 0x820802Fa8a99901F52e39acD21177b0BE6EE2974; + address constant EURE = 0x3231Cb76718CDeF2155FC47b5286d82e6eDA273f; + address constant BC3M = 0x2F123cF3F37CE3328CC9B5b8415f9EC5109b45e7; + address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + + uint128 constant FIREWALL_MINT_EUROC = 0; + uint128 constant FIREWALL_BURN_EUROC = uint128(5 * BPS); + uint128 constant FIREWALL_MINT_BC3M = uint128(BASE_18); + uint128 constant FIREWALL_BURN_BC3M = uint128(100 * BPS); + uint96 constant DEVIATION_THRESHOLD_BC3M = uint96(100 * BPS); + uint32 constant HEARTBEAT = uint32(1 days); + + address constant GETTERS = 0x37eB0572eb61db3B819570Cf65114ff6dB6C06A2; + address constant REDEEMER = 0x028e1f0DB25DAF4ce8C895215deAfbCE7A873b24; + address constant SETTERS_GOVERNOR = 0xc3ef7ed4F97450Ae8dA2473068375788BdeB5c5c; + address constant SWAPPER = 0x954eC713a3915B504a6F288563e5218F597e1895; + address constant ORACLE = 0x44E3d3BBa34E16a67c633dAF86114284FC628819; + + /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + HELPERS + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + + function _bytes4ToBytes32(bytes4 _in) internal pure returns (bytes32 out) { + assembly { + out := _in + } + } + + function _arrayBytes4ToBytes32(bytes4[] memory _in) internal pure returns (bytes32[] memory out) { + out = new bytes32[](_in.length); + for (uint256 i = 0; i < _in.length; ++i) { + out[i] = _bytes4ToBytes32(_in[i]); + } + } + + function _arrayBytes32ToBytes4(bytes32[] memory _in) internal pure returns (bytes4[] memory out) { + out = new bytes4[](_in.length); + for (uint256 i = 0; i < _in.length; ++i) { + out[i] = bytes4(_in[i]); + } + } + + function consoleLogBytes4Array(bytes4[] memory _in) internal view { + for (uint256 i = 0; i < _in.length; ++i) { + console.logBytes4(_in[i]); + } + } +} diff --git a/test/Constants.t.sol b/test/Constants.t.sol index 4d6deb4..67f4040 100644 --- a/test/Constants.t.sol +++ b/test/Constants.t.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.9; -import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; +import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; uint48 constant initialVotingDelay = 1800; uint32 constant initialVotingPeriod = 36000; diff --git a/test/Fixture.t.sol b/test/Fixture.t.sol index a0c403a..5a5c2d9 100644 --- a/test/Fixture.t.sol +++ b/test/Fixture.t.sol @@ -2,23 +2,23 @@ pragma solidity ^0.8.19; -import { IveANGLEVotingDelegation } from "contracts/interfaces/IveANGLEVotingDelegation.sol"; -import { deployMockANGLE, deployVeANGLE } from "../scripts/test/DeployANGLE.s.sol"; -import { ERC20 } from "oz/token/ERC20/ERC20.sol"; +import {IveANGLEVotingDelegation} from "contracts/interfaces/IveANGLEVotingDelegation.sol"; +import {deployMockANGLE, deployVeANGLE} from "../scripts/test/DeployANGLE.s.sol"; +import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; import "contracts/interfaces/IveANGLE.sol"; import "./external/VyperDeployer.sol"; -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { VeANGLEVotingDelegation, ECDSA } from "contracts/VeANGLEVotingDelegation.sol"; -import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {VeANGLEVotingDelegation, ECDSA} from "contracts/VeANGLEVotingDelegation.sol"; +import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "./Constants.t.sol"; import "./Utils.t.sol"; -import { Test, stdError } from "forge-std/Test.sol"; -import { console } from "forge-std/console.sol"; +import {Test, stdError} from "forge-std/Test.sol"; +import {console} from "forge-std/console.sol"; contract Fixture is Test { uint256 public constant FORK_BLOCK_NUMBER = 1152; @@ -61,10 +61,10 @@ contract Fixture is Test { // Deploy necessary contracts - for governance to be deployed vyperDeployer = new VyperDeployer(); - (address _mockANGLE, , ) = deployMockANGLE(); + (address _mockANGLE,,) = deployMockANGLE(); ANGLE = ERC20(_mockANGLE); deal(address(ANGLE), mainnetMultisig, GOVERNOR_INIT_BALANCE); - (address _mockVeANGLE, , ) = deployVeANGLE(vyperDeployer, _mockANGLE, mainnetMultisig); + (address _mockVeANGLE,,) = deployVeANGLE(vyperDeployer, _mockANGLE, mainnetMultisig); veANGLE = IveANGLE(_mockVeANGLE); _setupDealAndLockANGLE(alice, 1_000_000 * 1e18, 365 days); _setupDealAndLockANGLE(bob, 333_000 * 1e18, 4 * 365 days); diff --git a/test/external/MockANGLE.sol b/test/external/MockANGLE.sol index 313c482..8c04719 100644 --- a/test/external/MockANGLE.sol +++ b/test/external/MockANGLE.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import { ERC20 } from "oz/token/ERC20/ERC20.sol"; +import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; contract MockANGLE is ERC20 { constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {} diff --git a/test/fuzz/GovernorCountingFractional.t.sol b/test/fuzz/GovernorCountingFractional.t.sol index ff8c32c..8befd79 100644 --- a/test/fuzz/GovernorCountingFractional.t.sol +++ b/test/fuzz/GovernorCountingFractional.t.sol @@ -1,23 +1,23 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.10; -import { IGovernor } from "oz/governance/IGovernor.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { SafeCast } from "oz/utils/math/SafeCast.sol"; -import { Strings } from "oz/utils/Strings.sol"; -import { MessageHashUtils } from "oz/utils/cryptography/MessageHashUtils.sol"; -import { GovernorCountingSimple } from "oz/governance/extensions/GovernorCountingSimple.sol"; -import { GovernorVotesQuorumFraction } from "oz/governance/extensions/GovernorVotesQuorumFraction.sol"; - -import { Test, stdError } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {SafeCast} from "oz-v5/utils/math/SafeCast.sol"; +import {Strings} from "oz-v5/utils/Strings.sol"; +import {MessageHashUtils} from "oz-v5/utils/cryptography/MessageHashUtils.sol"; +import {GovernorCountingSimple} from "oz-v5/governance/extensions/GovernorCountingSimple.sol"; +import {GovernorVotesQuorumFraction} from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; + +import {Test, stdError} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; import "forge-std/console.sol"; -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { VeANGLEVotingDelegation } from "contracts/VeANGLEVotingDelegation.sol"; -import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {VeANGLEVotingDelegation} from "contracts/VeANGLEVotingDelegation.sol"; +import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "../external/FixedPointMathLib.t.sol"; @@ -31,12 +31,7 @@ contract GovernorCountingFractionalTest is Test { event MockFunctionCalled(); event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason); event VoteCastWithParams( - address indexed voter, - uint256 proposalId, - uint8 support, - uint256 weight, - string reason, - bytes params + address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params ); event ProposalExecuted(uint256 proposalId); event ProposalCreated( @@ -129,11 +124,7 @@ contract GovernorCountingFractionalTest is Test { proposalSender = new ProposalSender(mainnetLzEndpoint); proposalSender.transferOwnership(address(governor)); - vm.mockCall( - address(token), - abi.encodeWithSelector(token.getPastTotalSupply.selector), - abi.encode(TOTAL_SUPPLY) - ); + vm.mockCall(address(token), abi.encodeWithSelector(token.getPastTotalSupply.selector), abi.encode(TOTAL_SUPPLY)); } /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -145,9 +136,8 @@ contract GovernorCountingFractionalTest is Test { } function _getQuorum() internal returns (uint256 _weight) { - _weight = - (token.getPastTotalSupply(block.number) * governor.quorumNumerator(block.timestamp)) / - governor.quorumDenominator(); + _weight = (token.getPastTotalSupply(block.number) * governor.quorumNumerator(block.timestamp)) + / governor.quorumDenominator(); // if the weight is too large (> type(uint128).max) decrease the totalSupply // for it to be enough to be above quorum @@ -155,9 +145,7 @@ contract GovernorCountingFractionalTest is Test { _weight = MAX_VOTE_WEIGHT; uint256 _tmpTotalSupply = _supplyInverseQuorum(_weight); vm.mockCall( - address(token), - abi.encodeWithSelector(token.getPastTotalSupply.selector), - abi.encode(_tmpTotalSupply) + address(token), abi.encodeWithSelector(token.getPastTotalSupply.selector), abi.encode(_tmpTotalSupply) ); } } @@ -167,9 +155,8 @@ contract GovernorCountingFractionalTest is Test { } function _buildDomainSeparator() private view returns (bytes32) { - bytes32 TYPE_HASH = keccak256( - "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" - ); + bytes32 TYPE_HASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); bytes32 _hashedName = keccak256(bytes("AngleGovernor")); bytes32 _hashedVersion = keccak256(bytes("1")); return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(governor))); @@ -278,10 +265,10 @@ contract GovernorCountingFractionalTest is Test { } // Sets up up a 4-Voter array with specified weights and voteSplits, and random supportTypes. - function _setupFractionalVoters( - uint256[4] memory weights, - FractionalVoteSplit[4] memory voteSplits - ) internal returns (Voter[4] memory voters) { + function _setupFractionalVoters(uint256[4] memory weights, FractionalVoteSplit[4] memory voteSplits) + internal + returns (Voter[4] memory voters) + { voters = _setupNominalVoters(weights); Voter memory voter; @@ -308,9 +295,10 @@ contract GovernorCountingFractionalTest is Test { ); } - function _mintAndDelegateToVoters( - Voter[4] memory voters - ) internal returns (uint256 forVotes, uint256 againstVotes, uint256 abstainVotes) { + function _mintAndDelegateToVoters(Voter[4] memory voters) + internal + returns (uint256 forVotes, uint256 againstVotes, uint256 abstainVotes) + { Voter memory voter; for (uint8 _i = 0; _i < voters.length; _i++) { @@ -354,14 +342,7 @@ contract GovernorCountingFractionalTest is Test { uint128(_voter.weight.mulWadDown(voteSplit.percentAbstain)) ); vm.expectEmit(true, true, true, true); - emit VoteCastWithParams( - _voter.addr, - _proposalId, - _voter.support, - _voter.weight, - "Yay", - fractionalizedVotes - ); + emit VoteCastWithParams(_voter.addr, _proposalId, _voter.support, _voter.weight, "Yay", fractionalizedVotes); } else { vm.expectEmit(true, true, true, true); emit VoteCast(_voter.addr, _proposalId, _voter.support, _voter.weight, "Yay"); @@ -391,9 +372,7 @@ contract GovernorCountingFractionalTest is Test { vm.warp(governor.proposalDeadline(_proposalId) + 1); vm.roll(governor.$snapshotTimestampToSnapshotBlockNumber(governor.proposalSnapshot(_proposalId)) + 1); - (uint256 againstVotesCast, uint256 forVotesCast, uint256 abstainVotesCast) = governor.proposalVotes( - _proposalId - ); + (uint256 againstVotesCast, uint256 forVotesCast, uint256 abstainVotesCast) = governor.proposalVotes(_proposalId); assertEq(againstVotes, againstVotesCast); assertEq(forVotes, forVotesCast); @@ -401,8 +380,8 @@ contract GovernorCountingFractionalTest is Test { IGovernor.ProposalState status = IGovernor.ProposalState(uint32(governor.state(_proposalId))); if ( - forVotes > againstVotes && - (forVotes + abstainVotes) >= governor.quorum(governor.proposalSnapshot(_proposalId)) + forVotes > againstVotes + && (forVotes + abstainVotes) >= governor.quorum(governor.proposalSnapshot(_proposalId)) ) { assertEq(uint8(status), uint8(IGovernor.ProposalState.Succeeded)); _executeProposal(); @@ -415,8 +394,8 @@ contract GovernorCountingFractionalTest is Test { IGovernor.GovernorUnexpectedProposalState.selector, _rawProposalInfo.id, IGovernor.ProposalState.Defeated, - _encodeStateBitmap(IGovernor.ProposalState.Succeeded) | - _encodeStateBitmap(IGovernor.ProposalState.Queued) + _encodeStateBitmap(IGovernor.ProposalState.Succeeded) + | _encodeStateBitmap(IGovernor.ProposalState.Queued) ) ); governor.execute( @@ -472,9 +451,8 @@ contract GovernorCountingFractionalTest is Test { _mintAndDelegateToVoter(_voter); uint256 _proposalId = _createAndSubmitProposal(); - bytes32 _voteMessage = keccak256( - abi.encode(governor.BALLOT_TYPEHASH(), _proposalId, _voter.support, _voter.addr, 0) - ); + bytes32 _voteMessage = + keccak256(abi.encode(governor.BALLOT_TYPEHASH(), _proposalId, _voter.support, _voter.addr, 0)); bytes memory signature; { @@ -485,9 +463,8 @@ contract GovernorCountingFractionalTest is Test { } governor.castVoteBySig(_proposalId, _voter.support, _voter.addr, signature); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( - _proposalId - ); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = + governor.proposalVotes(_proposalId); if (_voter.support == uint8(GovernorCountingSimple.VoteType.For)) { assertEq(_voter.weight, _actualForVotes); } @@ -499,10 +476,9 @@ contract GovernorCountingFractionalTest is Test { } } - function testFuzz_VotingWithFractionalizedParamsAndSignature( - uint256 _weight, - FractionalVoteSplit memory _voteSplit - ) public { + function testFuzz_VotingWithFractionalizedParamsAndSignature(uint256 _weight, FractionalVoteSplit memory _voteSplit) + public + { Voter memory _voter; uint256 _privateKey; (_voter.addr, _privateKey) = makeAddrAndKey("voter"); @@ -541,17 +517,11 @@ contract GovernorCountingFractionalTest is Test { } governor.castVoteWithReasonAndParamsBySig( - _proposalId, - _voter.support, - _voter.addr, - "I have my reasons", - _fractionalizedVotes, - signature + _proposalId, _voter.support, _voter.addr, "I have my reasons", _fractionalizedVotes, signature ); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( - _proposalId - ); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = + governor.proposalVotes(_proposalId); assertEq(_forVotes, _actualForVotes); assertEq(_againstVotes, _actualAgainstVotes); assertEq(_abstainVotes, _actualAbstainVotes); @@ -613,11 +583,7 @@ contract GovernorCountingFractionalTest is Test { // They must have weight at the time of the proposal snapshot. vm.mockCall(address(token), abi.encodeWithSelector(token.getVotes.selector, _voterAddr), abi.encode(100e18)); - vm.mockCall( - address(token), - abi.encodeWithSelector(token.getPastVotes.selector, _voterAddr), - abi.encode(100e18) - ); + vm.mockCall(address(token), abi.encodeWithSelector(token.getPastVotes.selector, _voterAddr), abi.encode(100e18)); uint256 _proposalId = _createAndSubmitProposal(); @@ -797,9 +763,11 @@ contract GovernorCountingFractionalTest is Test { _quorumTest(_voterAddr, _weight, _voteSplit, _wasQuorumReached); } - function _decodePackedVotes( - bytes memory voteData - ) internal pure returns (uint128 againstVotes, uint128 forVotes, uint128 abstainVotes) { + function _decodePackedVotes(bytes memory voteData) + internal + pure + returns (uint128 againstVotes, uint128 forVotes, uint128 abstainVotes) + { assembly { againstVotes := shr(128, mload(add(voteData, 0x20))) forVotes := and(0xffffffffffffffffffffffffffffffff, mload(add(voteData, 0x20))) @@ -836,11 +804,9 @@ contract GovernorCountingFractionalTest is Test { assertEq(_quorumReached(_proposalId), _isQuorumExpected); } - function testFuzz_CanCastWithPartialWeight( - address _voterAddr, - uint256 _salt, - FractionalVoteSplit memory _voteSplit - ) public { + function testFuzz_CanCastWithPartialWeight(address _voterAddr, uint256 _salt, FractionalVoteSplit memory _voteSplit) + public + { // Build a partial weight vote split. _voteSplit = _randomVoteSplit(_voteSplit); uint256 _percentKeep = bound(_salt, 0.9e18, 0.99e18); // 90% to 99% @@ -872,9 +838,8 @@ contract GovernorCountingFractionalTest is Test { vm.prank(_voter.addr); governor.castVoteWithReasonAndParams(_proposalId, _voter.support, "Lobster", fractionalizedVotes); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( - _proposalId - ); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = + governor.proposalVotes(_proposalId); assertEq(_forVotes, _actualForVotes); assertEq(_againstVotes, _actualAgainstVotes); assertEq(_abstainVotes, _actualAbstainVotes); @@ -883,12 +848,7 @@ contract GovernorCountingFractionalTest is Test { function test_CanCastPartialWeightMultipleTimesAddingToFullWeight() public { testFuzz_CanCastPartialWeightMultipleTimes( - _randomAddress(), - 42 ether, - 0.45e18, - 0.25e18, - 0.3e18, - FractionalVoteSplit(0.33e18, 0.33e18, 0.34e18) + _randomAddress(), 42 ether, 0.45e18, 0.25e18, 0.3e18, FractionalVoteSplit(0.33e18, 0.33e18, 0.34e18) ); } @@ -924,12 +884,10 @@ contract GovernorCountingFractionalTest is Test { // Calculate the vote amounts for the first vote. VoteData memory _firstVote; _firstVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage1)); - _firstVote.againstVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage1) - ); - _firstVote.abstainVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage1) - ); + _firstVote.againstVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage1)); + _firstVote.abstainVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage1)); // Cast votes the first time. vm.prank(_voter.addr); @@ -940,9 +898,8 @@ contract GovernorCountingFractionalTest is Test { abi.encodePacked(_firstVote.againstVotes, _firstVote.forVotes, _firstVote.abstainVotes) ); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( - _proposalId - ); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = + governor.proposalVotes(_proposalId); assertEq(_firstVote.forVotes, _actualForVotes); assertEq(_firstVote.againstVotes, _actualAgainstVotes); assertEq(_firstVote.abstainVotes, _actualAbstainVotes); @@ -957,12 +914,10 @@ contract GovernorCountingFractionalTest is Test { // Now cast votes again. VoteData memory _secondVote; _secondVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage2)); - _secondVote.againstVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage2) - ); - _secondVote.abstainVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage2) - ); + _secondVote.againstVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage2)); + _secondVote.abstainVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage2)); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( @@ -978,12 +933,8 @@ contract GovernorCountingFractionalTest is Test { assertEq(_firstVote.abstainVotes + _secondVote.abstainVotes, _actualAbstainVotes); assertEq( governor.voteWeightCast(_proposalId, _voter.addr), - _firstVote.againstVotes + - _firstVote.forVotes + - _firstVote.abstainVotes + - _secondVote.againstVotes + - _secondVote.forVotes + - _secondVote.abstainVotes + _firstVote.againstVotes + _firstVote.forVotes + _firstVote.abstainVotes + _secondVote.againstVotes + + _secondVote.forVotes + _secondVote.abstainVotes ); // If the entire weight was cast; further votes are not possible. @@ -992,12 +943,10 @@ contract GovernorCountingFractionalTest is Test { // Once more unto the breach! VoteData memory _thirdVote; _thirdVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage3)); - _thirdVote.againstVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage3) - ); - _thirdVote.abstainVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage3) - ); + _thirdVote.againstVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage3)); + _thirdVote.abstainVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage3)); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( @@ -1013,15 +962,9 @@ contract GovernorCountingFractionalTest is Test { assertEq(_firstVote.abstainVotes + _secondVote.abstainVotes + _thirdVote.abstainVotes, _actualAbstainVotes); assertEq( governor.voteWeightCast(_proposalId, _voter.addr), - _firstVote.againstVotes + - _firstVote.forVotes + - _firstVote.abstainVotes + - _secondVote.againstVotes + - _secondVote.forVotes + - _secondVote.abstainVotes + - _thirdVote.againstVotes + - _thirdVote.forVotes + - _thirdVote.abstainVotes + _firstVote.againstVotes + _firstVote.forVotes + _firstVote.abstainVotes + _secondVote.againstVotes + + _secondVote.forVotes + _secondVote.abstainVotes + _thirdVote.againstVotes + _thirdVote.forVotes + + _thirdVote.abstainVotes ); } @@ -1053,12 +996,10 @@ contract GovernorCountingFractionalTest is Test { // Calculate the vote amounts for the first vote. VoteData memory _firstVote; _firstVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage1)); - _firstVote.againstVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage1) - ); - _firstVote.abstainVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage1) - ); + _firstVote.againstVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage1)); + _firstVote.abstainVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage1)); // Cast votes the first time. vm.prank(_voter.addr); @@ -1069,9 +1010,8 @@ contract GovernorCountingFractionalTest is Test { abi.encodePacked(_firstVote.againstVotes, _firstVote.forVotes, _firstVote.abstainVotes) ); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( - _proposalId - ); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = + governor.proposalVotes(_proposalId); assertEq(_actualForVotes, 16 ether); // 100 * 20% * 80% assertEq(_actualAgainstVotes, 3 ether); // 100 * 20% * 15% assertEq(_actualAbstainVotes, 1 ether); // 100 * 20% * 5% @@ -1079,12 +1019,10 @@ contract GovernorCountingFractionalTest is Test { // Now cast votes again. VoteData memory _secondVote; _secondVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage2)); - _secondVote.againstVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage2) - ); - _secondVote.abstainVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage2) - ); + _secondVote.againstVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage2)); + _secondVote.abstainVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage2)); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( @@ -1102,12 +1040,10 @@ contract GovernorCountingFractionalTest is Test { // One more time! VoteData memory _thirdVote; _thirdVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage3)); - _thirdVote.againstVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage3) - ); - _thirdVote.abstainVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage3) - ); + _thirdVote.againstVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage3)); + _thirdVote.abstainVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage3)); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( @@ -1152,12 +1088,10 @@ contract GovernorCountingFractionalTest is Test { // Calculate the vote amounts for the first vote. VoteData memory _voteData; _voteData.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage)); - _voteData.againstVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage) - ); - _voteData.abstainVotes = uint128( - _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage) - ); + _voteData.againstVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage)); + _voteData.abstainVotes = + uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage)); // We're going to do this twice to try to exceed our vote weight. assertLt(_voter.weight, 2 * (uint256(_voteData.forVotes) + _voteData.againstVotes + _voteData.abstainVotes)); @@ -1171,9 +1105,8 @@ contract GovernorCountingFractionalTest is Test { abi.encodePacked(_voteData.againstVotes, _voteData.forVotes, _voteData.abstainVotes) ); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( - _proposalId - ); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = + governor.proposalVotes(_proposalId); assertEq(_voteData.forVotes, _actualForVotes); assertEq(_voteData.againstVotes, _actualAgainstVotes); assertEq(_voteData.abstainVotes, _actualAbstainVotes); @@ -1249,27 +1182,16 @@ contract GovernorCountingFractionalTest is Test { vm.expectRevert(Errors.GovernorCountingFractionalAllWeightCast.selector); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( - _proposalId, - _voter.support, - "Fractional vote", - _fractionalizedVoteData + _proposalId, _voter.support, "Fractional vote", _fractionalizedVoteData ); } else { vm.expectEmit(true, true, true, true); emit VoteCastWithParams( - _voter.addr, - _proposalId, - _voter.support, - _voter.weight, - "Fractional vote", - _fractionalizedVoteData + _voter.addr, _proposalId, _voter.support, _voter.weight, "Fractional vote", _fractionalizedVoteData ); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( - _proposalId, - _voter.support, - "Fractional vote", - _fractionalizedVoteData + _proposalId, _voter.support, "Fractional vote", _fractionalizedVoteData ); vm.prank(_voter.addr); @@ -1278,9 +1200,8 @@ contract GovernorCountingFractionalTest is Test { } // The voter should not have been able to increase his/her vote weight by voting twice. - (uint256 _againstVotesCast, uint256 _forVotesCast, uint256 _abstainVotesCast) = governor.proposalVotes( - _proposalId - ); + (uint256 _againstVotesCast, uint256 _forVotesCast, uint256 _abstainVotesCast) = + governor.proposalVotes(_proposalId); assertLe(_againstVotesCast + _forVotesCast + _abstainVotesCast, _voter.weight); } } diff --git a/test/fuzz/VeANGLEVotingDelegation.t.sol b/test/fuzz/VeANGLEVotingDelegation.t.sol index 566e115..0cd20dc 100644 --- a/test/fuzz/VeANGLEVotingDelegation.t.sol +++ b/test/fuzz/VeANGLEVotingDelegation.t.sol @@ -1,18 +1,18 @@ // SPDX-License-Identifier: ISC pragma solidity ^0.8.19; -import { IveANGLEVotingDelegation } from "contracts/interfaces/IveANGLEVotingDelegation.sol"; -import { Test, stdError } from "forge-std/Test.sol"; -import { deployMockANGLE, deployVeANGLE } from "../../scripts/test/DeployANGLE.s.sol"; -import { ERC20 } from "oz/token/ERC20/ERC20.sol"; +import {IveANGLEVotingDelegation} from "contracts/interfaces/IveANGLEVotingDelegation.sol"; +import {Test, stdError} from "forge-std/Test.sol"; +import {deployMockANGLE, deployVeANGLE} from "../../scripts/test/DeployANGLE.s.sol"; +import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; import "contracts/interfaces/IveANGLE.sol"; import "../external/VyperDeployer.sol"; -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { VeANGLEVotingDelegation, ECDSA } from "contracts/VeANGLEVotingDelegation.sol"; -import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {VeANGLEVotingDelegation, ECDSA} from "contracts/VeANGLEVotingDelegation.sol"; +import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Constants.t.sol"; import "../Utils.t.sol"; @@ -71,11 +71,11 @@ contract VeANGLEVotingDelegationTest is Test, Utils { vyperDeployer = new VyperDeployer(); - (address _mockANGLE, , ) = deployMockANGLE(); + (address _mockANGLE,,) = deployMockANGLE(); ANGLE = ERC20(_mockANGLE); deal(address(ANGLE), mainnetMultisig, 300_000_000e18); - (address _mockVeANGLE, , ) = deployVeANGLE(vyperDeployer, _mockANGLE, mainnetMultisig); + (address _mockVeANGLE,,) = deployVeANGLE(vyperDeployer, _mockANGLE, mainnetMultisig); veANGLE = IveANGLE(_mockVeANGLE); _setupDealAndLockANGLE(); @@ -170,9 +170,7 @@ contract VeANGLEVotingDelegationTest is Test, Utils { // Assert that this account has weight themselves when they haven't delegated function test_RevertWhen_NoDelegationHasWeight() public { assertEq( - token.getVotes(accounts[0]), - veANGLE.balanceOf(accounts[0]), - "getVotes and veANGLE balance are identical" + token.getVotes(accounts[0]), veANGLE.balanceOf(accounts[0]), "getVotes and veANGLE balance are identical" ); } @@ -261,11 +259,10 @@ contract VeANGLEVotingDelegationTest is Test, Utils { function test_DelegateBySig() public { dealCreateLockANGLE(eoaOwners[0], 100e18); - (, string memory name, string memory version, uint256 chainId, address verifyingContract, , ) = token - .eip712Domain(); - bytes32 TYPE_HASH = keccak256( - "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" - ); + (, string memory name, string memory version, uint256 chainId, address verifyingContract,,) = + token.eip712Domain(); + bytes32 TYPE_HASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); bytes32 domainSeparator = keccak256( abi.encode(TYPE_HASH, keccak256(bytes(name)), keccak256(bytes(version)), chainId, verifyingContract) ); @@ -389,11 +386,7 @@ contract VeANGLEVotingDelegationTest is Test, Utils { vm.warp(delegationStarts + 1 days - 1); assertGt(token.getVotes(bob, block.timestamp), 0, "Bob still has voting power until next epoch"); - assertEq( - 0, - token.getVotes(charlie, block.timestamp), - "Bill should still have no voting power until next epoch" - ); + assertEq(0, token.getVotes(charlie, block.timestamp), "Bill should still have no voting power until next epoch"); assertEq( 0, token.getVotes(accounts[0], block.timestamp), @@ -545,9 +538,7 @@ contract VeANGLEVotingDelegationTest is Test, Utils { vm.warp(expiration + 1 days); assertEq( - token.getVotes(bob), - veANGLE.balanceOf(accounts[0]), - "Self delegation is equivalent to veANGLE balance" + token.getVotes(bob), veANGLE.balanceOf(accounts[0]), "Self delegation is equivalent to veANGLE balance" ); } @@ -599,9 +590,7 @@ contract VeANGLEVotingDelegationTest is Test, Utils { token.delegate(bob); assertLe( - weight, - token.getVotes(accounts[0], block.timestamp - 1), - "accounts[0] still has weight before delegation" + weight, token.getVotes(accounts[0], block.timestamp - 1), "accounts[0] still has weight before delegation" ); assertEq( weight, @@ -610,9 +599,7 @@ contract VeANGLEVotingDelegationTest is Test, Utils { ); assertLe( - weightA, - token.getVotes(accounts[1], block.timestamp - 1), - "accounts[1] still has weight before delegation" + weightA, token.getVotes(accounts[1], block.timestamp - 1), "accounts[1] still has weight before delegation" ); assertEq( weightA, @@ -639,14 +626,10 @@ contract VeANGLEVotingDelegationTest is Test, Utils { vm.warp(tsRoundedToCheckpoint); assertEq( - 0, - token.getVotes(accounts[0], block.timestamp), - "accounts[0]'s delegation kicks in so they have no weight" + 0, token.getVotes(accounts[0], block.timestamp), "accounts[0]'s delegation kicks in so they have no weight" ); assertEq( - 0, - token.getVotes(accounts[1], block.timestamp), - "accounts[1]'s delegation kicks in so they have no weight" + 0, token.getVotes(accounts[1], block.timestamp), "accounts[1]'s delegation kicks in so they have no weight" ); uint256 bobWeight = token.getVotes(bob, block.timestamp); @@ -720,9 +703,7 @@ contract VeANGLEVotingDelegationTest is Test, Utils { assertEq(weight, 0, "Delegator has no weight"); assertEq(weightA, 0, "Delegator has no weight"); assertEq( - veANGLEBalance + veANGLEBalanceA, - delegateWeight, - "delegate's weight == veANGLE balance of both delegators" + veANGLEBalance + veANGLEBalanceA, delegateWeight, "delegate's weight == veANGLE balance of both delegators" ); } diff --git a/test/invariant/BasicInvariants.t.sol b/test/invariant/BasicInvariants.t.sol index 86f97a3..95f70b2 100644 --- a/test/invariant/BasicInvariants.t.sol +++ b/test/invariant/BasicInvariants.t.sol @@ -2,15 +2,15 @@ pragma solidity ^0.8.19; -import { IERC20 } from "oz/token/ERC20/IERC20.sol"; -import { IERC20Metadata } from "oz/token/ERC20/extensions/IERC20Metadata.sol"; -import "oz/utils/Strings.sol"; -import { Voter } from "./actors/Voter.t.sol"; -import { Fixture, AngleGovernor } from "../Fixture.t.sol"; -import { ProposalStore } from "./stores/ProposalStore.sol"; +import {IERC20} from "oz-v5/token/ERC20/IERC20.sol"; +import {IERC20Metadata} from "oz-v5/token/ERC20/extensions/IERC20Metadata.sol"; +import "oz-v5/utils/Strings.sol"; +import {Voter} from "./actors/Voter.t.sol"; +import {Fixture, AngleGovernor} from "../Fixture.t.sol"; +import {ProposalStore} from "./stores/ProposalStore.sol"; //solhint-disable -import { console } from "forge-std/console.sol"; +import {console} from "forge-std/console.sol"; contract BasicInvariants is Fixture { uint256 internal constant _NUM_VOTER = 10; diff --git a/test/invariant/DelegationInvariants.t.sol b/test/invariant/DelegationInvariants.t.sol index 73b259b..4ae661d 100644 --- a/test/invariant/DelegationInvariants.t.sol +++ b/test/invariant/DelegationInvariants.t.sol @@ -10,7 +10,7 @@ import { Param } from "./actors/Param.t.sol"; import { Fixture, AngleGovernor } from "../Fixture.t.sol"; //solhint-disable -import { console } from "forge-std/console.sol"; +import {console} from "forge-std/console.sol"; contract DelegationInvariants is Fixture { uint256 internal constant _NUM_DELEGATORS = 10; @@ -26,7 +26,7 @@ contract DelegationInvariants is Fixture { _paramHandler = new Param(_NUM_PARAMS, ANGLE); // Label newly created addresses - for (uint256 i; i < _NUM_DELEGATORS; i++) + for (uint256 i; i < _NUM_DELEGATORS; i++) { vm.label(_delegatorHandler.actors(i), string.concat("Delegator ", Strings.toString(i))); vm.label({ account: address(_paramHandler), newLabel: "Param" }); @@ -40,12 +40,12 @@ contract DelegationInvariants is Fixture { selectors[2] = Delegator.withdraw.selector; selectors[3] = Delegator.extendLockTime.selector; selectors[4] = Delegator.extendLockAmount.selector; - targetSelector(FuzzSelector({ addr: address(_delegatorHandler), selectors: selectors })); + targetSelector(FuzzSelector({addr: address(_delegatorHandler), selectors: selectors})); } { bytes4[] memory selectors = new bytes4[](1); selectors[0] = Param.wrap.selector; - targetSelector(FuzzSelector({ addr: address(_paramHandler), selectors: selectors })); + targetSelector(FuzzSelector({addr: address(_paramHandler), selectors: selectors})); } } @@ -54,9 +54,7 @@ contract DelegationInvariants is Fixture { address actor = _delegatorHandler.actors(i); assertEq( - token.delegates(actor), - _delegatorHandler.delegations(actor), - "delegatee should be the same as actor" + token.delegates(actor), _delegatorHandler.delegations(actor), "delegatee should be the same as actor" ); } for (uint256 i; i < _delegatorHandler.delegateesLength(); i++) { @@ -85,8 +83,9 @@ contract DelegationInvariants is Fixture { for (uint256 i; i < _NUM_DELEGATORS; i++) { address actor = _delegatorHandler.actors(i); address delegatee = _delegatorHandler.delegations(actor); - if (delegatee != address(0) && delegatee != actor) + if (delegatee != address(0) && delegatee != actor) { assertEq(token.getVotes(actor), 0, "Delegator should have null vote"); + } } } diff --git a/test/invariant/MainnetGovernorInvariants.t.sol b/test/invariant/MainnetGovernorInvariants.t.sol index 197dd0b..88c1170 100644 --- a/test/invariant/MainnetGovernorInvariants.t.sol +++ b/test/invariant/MainnetGovernorInvariants.t.sol @@ -2,18 +2,18 @@ pragma solidity ^0.8.19; -import { IERC20 } from "oz/token/ERC20/IERC20.sol"; -import { IERC20Metadata } from "oz/token/ERC20/extensions/IERC20Metadata.sol"; +import {IERC20} from "oz/token/ERC20/IERC20.sol"; +import {IERC20Metadata} from "oz/token/ERC20/extensions/IERC20Metadata.sol"; import "oz/utils/Strings.sol"; -import { Voter } from "./actors/Voter.t.sol"; -import { Proposer } from "./actors/Proposer.t.sol"; -import { BadVoter } from "./actors/BadVoter.t.sol"; -import { Fixture, AngleGovernor } from "../Fixture.t.sol"; -import { ProposalStore, Proposal } from "./stores/ProposalStore.sol"; -import { IGovernor } from "oz/governance/IGovernor.sol"; +import {Voter} from "./actors/Voter.t.sol"; +import {Proposer} from "./actors/Proposer.t.sol"; +import {BadVoter} from "./actors/BadVoter.t.sol"; +import {Fixture, AngleGovernor} from "../Fixture.t.sol"; +import {ProposalStore, Proposal} from "./stores/ProposalStore.sol"; +import {IGovernor} from "oz/governance/IGovernor.sol"; //solhint-disable -import { console } from "forge-std/console.sol"; +import {console} from "forge-std/console.sol"; contract MainnetGovernorInvariants is Fixture { uint256 internal constant _NUM_VOTER = 10; @@ -34,7 +34,7 @@ contract MainnetGovernorInvariants is Fixture { _badVoterHandler = new BadVoter(angleGovernor, ANGLE, _NUM_VOTER, _proposalStore); // Label newly created addresses - vm.label({ account: address(_proposalStore), newLabel: "ProposalStore" }); + vm.label({account: address(_proposalStore), newLabel: "ProposalStore"}); for (uint256 i; i < _NUM_VOTER; i++) { vm.label(_voterHandler.actors(i), string.concat("Voter ", Strings.toString(i))); _setupDealAndLockANGLE(_voterHandler.actors(i), 100000000e18, 4 * 365 days); @@ -58,7 +58,7 @@ contract MainnetGovernorInvariants is Fixture { { bytes4[] memory selectors = new bytes4[](1); selectors[0] = Voter.vote.selector; - targetSelector(FuzzSelector({ addr: address(_voterHandler), selectors: selectors })); + targetSelector(FuzzSelector({addr: address(_voterHandler), selectors: selectors})); } { bytes4[] memory selectors = new bytes4[](4); @@ -66,13 +66,13 @@ contract MainnetGovernorInvariants is Fixture { selectors[1] = Proposer.execute.selector; selectors[2] = Proposer.tryToExecute.selector; selectors[3] = Proposer.skipVotingDelay.selector; - targetSelector(FuzzSelector({ addr: address(_proposerHandler), selectors: selectors })); + targetSelector(FuzzSelector({addr: address(_proposerHandler), selectors: selectors})); } { bytes4[] memory selectors = new bytes4[](2); selectors[0] = BadVoter.voteNonExistantProposal.selector; selectors[1] = BadVoter.executeNonReadyProposals.selector; - targetSelector(FuzzSelector({ addr: address(_badVoterHandler), selectors: selectors })); + targetSelector(FuzzSelector({addr: address(_badVoterHandler), selectors: selectors})); } } @@ -81,12 +81,8 @@ contract MainnetGovernorInvariants is Fixture { Proposal[] memory proposals = _proposalStore.getProposals(); for (uint256 i; i < proposalLength; i++) { Proposal memory proposal = proposals[i]; - uint256 proposalHash = angleGovernor.hashProposal( - proposal.target, - proposal.value, - proposal.data, - proposal.description - ); + uint256 proposalHash = + angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); uint256 totalSupply = veANGLE.totalSupply(); (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) = angleGovernor.proposalVotes(proposalHash); assertLe(againstVotes + forVotes + abstainVotes, totalSupply, "Votes should be under total supply"); @@ -98,12 +94,8 @@ contract MainnetGovernorInvariants is Fixture { Proposal[] memory proposals = _proposalStore.getProposals(); for (uint256 i; i < proposalLength; i++) { Proposal memory proposal = proposals[i]; - uint256 proposalHash = angleGovernor.hashProposal( - proposal.target, - proposal.value, - proposal.data, - proposal.description - ); + uint256 proposalHash = + angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); IGovernor.ProposalState currentState = angleGovernor.state(proposalHash); uint256 snapshot = angleGovernor.proposalSnapshot(proposalHash); uint256 deadline = angleGovernor.proposalDeadline(proposalHash); @@ -133,20 +125,16 @@ contract MainnetGovernorInvariants is Fixture { Proposal[] memory oldProposals = _proposalStore.getOldProposals(); for (uint256 i; i < oldProposals.length; i++) { Proposal memory proposal = oldProposals[i]; - uint256 proposalHash = angleGovernor.hashProposal( - proposal.target, - proposal.value, - proposal.data, - proposal.description - ); + uint256 proposalHash = + angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); IGovernor.ProposalState currentState = angleGovernor.state(proposalHash); vm.expectRevert( abi.encodeWithSelector( IGovernor.GovernorUnexpectedProposalState.selector, proposalHash, currentState, - bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) | - bytes32(1 << uint8(IGovernor.ProposalState.Queued)) + bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) + | bytes32(1 << uint8(IGovernor.ProposalState.Queued)) ) ); angleGovernor.execute(proposal.target, proposal.value, proposal.data, proposal.description); @@ -157,12 +145,8 @@ contract MainnetGovernorInvariants is Fixture { Proposal[] memory oldProposals = _proposalStore.getOldProposals(); for (uint256 i; i < oldProposals.length; i++) { Proposal memory proposal = oldProposals[i]; - uint256 proposalHash = angleGovernor.hashProposal( - proposal.target, - proposal.value, - proposal.data, - proposal.description - ); + uint256 proposalHash = + angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); IGovernor.ProposalState currentState = angleGovernor.state(proposalHash); if (currentState != IGovernor.ProposalState.Active) { vm.expectRevert( diff --git a/test/invariant/actors/BadVoter.t.sol b/test/invariant/actors/BadVoter.t.sol index d34607d..3035321 100644 --- a/test/invariant/actors/BadVoter.t.sol +++ b/test/invariant/actors/BadVoter.t.sol @@ -1,21 +1,18 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import { BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage } from "./BaseActor.t.sol"; -import { console } from "forge-std/console.sol"; -import { ProposalStore, Proposal } from "../stores/ProposalStore.sol"; -import { IGovernor } from "oz/governance/IGovernor.sol"; +import {BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage} from "./BaseActor.t.sol"; +import {console} from "forge-std/console.sol"; +import {ProposalStore, Proposal} from "../stores/ProposalStore.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; contract BadVoter is BaseActor { AngleGovernor internal _angleGovernor; ProposalStore public proposalStore; - constructor( - AngleGovernor angleGovernor, - IERC20 angle, - uint256 nbrVoter, - ProposalStore _proposalStore - ) BaseActor(nbrVoter, "BadVoter", angle) { + constructor(AngleGovernor angleGovernor, IERC20 angle, uint256 nbrVoter, ProposalStore _proposalStore) + BaseActor(nbrVoter, "BadVoter", angle) + { _angleGovernor = angleGovernor; proposalStore = _proposalStore; } @@ -27,12 +24,8 @@ contract BadVoter is BaseActor { Proposal[] memory proposals = proposalStore.getProposals(); for (uint256 i; i < proposals.length; i++) { Proposal memory proposal = proposals[i]; - uint256 proposalHash = _angleGovernor.hashProposal( - proposal.target, - proposal.value, - proposal.data, - proposal.description - ); + uint256 proposalHash = + _angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); if (proposalHash != proposalId || proposalStore.doesOldProposalExists(proposalHash)) { return; } @@ -48,20 +41,16 @@ contract BadVoter is BaseActor { } Proposal[] memory proposals = proposalStore.getProposals(); Proposal memory proposal = proposalStore.getRandomProposal(proposalId); - uint256 proposalHash = _angleGovernor.hashProposal( - proposal.target, - proposal.value, - proposal.data, - proposal.description - ); + uint256 proposalHash = + _angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); if (_angleGovernor.state(proposalHash) != IGovernor.ProposalState.Succeeded) { vm.expectRevert( abi.encodeWithSelector( IGovernor.GovernorUnexpectedProposalState.selector, proposalHash, _angleGovernor.state(proposalHash), - bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) | - bytes32(1 << uint8(IGovernor.ProposalState.Queued)) + bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) + | bytes32(1 << uint8(IGovernor.ProposalState.Queued)) ) ); _angleGovernor.execute(proposal.target, proposal.value, proposal.data, proposal.description); diff --git a/test/invariant/actors/BaseActor.t.sol b/test/invariant/actors/BaseActor.t.sol index a3237c9..ff8407e 100644 --- a/test/invariant/actors/BaseActor.t.sol +++ b/test/invariant/actors/BaseActor.t.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import { IERC20 } from "oz/token/ERC20/IERC20.sol"; -import { IERC20Metadata } from "oz/token/ERC20/extensions/IERC20Metadata.sol"; -import { Test, stdMath, StdStorage, stdStorage } from "forge-std/Test.sol"; -import { IVotes } from "oz/governance/utils/IVotes.sol"; -import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import {IERC20} from "oz-v5/token/ERC20/IERC20.sol"; +import {IERC20Metadata} from "oz-v5/token/ERC20/extensions/IERC20Metadata.sol"; +import {Test, stdMath, StdStorage, stdStorage} from "forge-std/Test.sol"; +import {IVotes} from "oz-v5/governance/utils/IVotes.sol"; +import {AngleGovernor} from "contracts/AngleGovernor.sol"; import "contracts/utils/Errors.sol"; struct TestStorage { diff --git a/test/invariant/actors/Delegator.t.sol b/test/invariant/actors/Delegator.t.sol index 1b7a7c8..9a5f857 100644 --- a/test/invariant/actors/Delegator.t.sol +++ b/test/invariant/actors/Delegator.t.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.19; import "./BaseActor.t.sol"; -import { IERC5805 } from "oz/interfaces/IERC5805.sol"; -import { MockANGLE } from "../../external/MockANGLE.sol"; +import {IERC5805} from "oz-v5/interfaces/IERC5805.sol"; +import {MockANGLE} from "../../external/MockANGLE.sol"; import "contracts/interfaces/IveANGLE.sol"; import "contracts/utils/Errors.sol"; @@ -15,12 +15,9 @@ contract Delegator is BaseActor { mapping(address => address[]) public reverseDelegations; address[] public delegatees; - constructor( - uint256 _nbrActor, - IERC20 _agToken, - address _veToken, - address _veDelegation - ) BaseActor(_nbrActor, "Delegator", _agToken) { + constructor(uint256 _nbrActor, IERC20 _agToken, address _veToken, address _veDelegation) + BaseActor(_nbrActor, "Delegator", _agToken) + { veToken = IveANGLE(_veToken); veDelegation = IERC5805(_veDelegation); } @@ -60,9 +57,8 @@ contract Delegator is BaseActor { reverseDelegations[toDelegate].push(_currentActor); for (uint256 i; i < reverseDelegations[currentDelegatee].length; i++) { if (reverseDelegations[currentDelegatee][i] == _currentActor) { - reverseDelegations[currentDelegatee][i] = reverseDelegations[currentDelegatee][ - reverseDelegations[currentDelegatee].length - 1 - ]; + reverseDelegations[currentDelegatee][i] = + reverseDelegations[currentDelegatee][reverseDelegations[currentDelegatee].length - 1]; reverseDelegations[currentDelegatee].pop(); break; } diff --git a/test/invariant/actors/Param.t.sol b/test/invariant/actors/Param.t.sol index 11fe038..12e88ac 100644 --- a/test/invariant/actors/Param.t.sol +++ b/test/invariant/actors/Param.t.sol @@ -2,11 +2,11 @@ pragma solidity ^0.8.19; import "./BaseActor.t.sol"; -import { IERC5805 } from "oz/interfaces/IERC5805.sol"; -import { MockANGLE } from "../../external/MockANGLE.sol"; +import {IERC5805} from "oz-v5/interfaces/IERC5805.sol"; +import {MockANGLE} from "../../external/MockANGLE.sol"; import "contracts/interfaces/IveANGLE.sol"; import "contracts/utils/Errors.sol"; -import { console } from "forge-std/console.sol"; +import {console} from "forge-std/console.sol"; contract Param is BaseActor { IveANGLE public veToken; diff --git a/test/invariant/actors/Proposer.t.sol b/test/invariant/actors/Proposer.t.sol index 9cc9b13..3e089e2 100644 --- a/test/invariant/actors/Proposer.t.sol +++ b/test/invariant/actors/Proposer.t.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import { BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage } from "./BaseActor.t.sol"; -import { console } from "forge-std/console.sol"; -import { IGovernor } from "oz/governance/IGovernor.sol"; -import { ProposalStore, Proposal } from "../stores/ProposalStore.sol"; -import { IERC5805 } from "oz/interfaces/IERC5805.sol"; +import {BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage} from "./BaseActor.t.sol"; +import {console} from "forge-std/console.sol"; +import {IGovernor} from "oz/governance/IGovernor.sol"; +import {ProposalStore, Proposal} from "../stores/ProposalStore.sol"; +import {IERC5805} from "oz/interfaces/IERC5805.sol"; contract Proposer is BaseActor { AngleGovernor internal _angleGovernor; @@ -55,12 +55,8 @@ contract Proposer is BaseActor { return; } Proposal memory proposal = proposalStore.getRandomProposal(proposalId); - uint256 proposalHash = _angleGovernor.hashProposal( - proposal.target, - proposal.value, - proposal.data, - proposal.description - ); + uint256 proposalHash = + _angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); uint256 proposalSnapshot = _angleGovernor.proposalSnapshot(proposalHash); vm.warp(block.timestamp + _angleGovernor.proposalDeadline(proposalHash)); vm.roll(block.number + _angleGovernor.$snapshotTimestampToSnapshotBlockNumber(proposalSnapshot)); @@ -71,8 +67,8 @@ contract Proposer is BaseActor { IGovernor.GovernorUnexpectedProposalState.selector, proposalHash, currentState, - bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) | - bytes32(1 << uint8(IGovernor.ProposalState.Queued)) + bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) + | bytes32(1 << uint8(IGovernor.ProposalState.Queued)) ) ); } @@ -88,12 +84,8 @@ contract Proposer is BaseActor { return; } Proposal memory proposal = proposalStore.getRandomProposal(proposalId); - uint256 proposalHash = _angleGovernor.hashProposal( - proposal.target, - proposal.value, - proposal.data, - proposal.description - ); + uint256 proposalHash = + _angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); uint256 proposalSnapshot = _angleGovernor.proposalSnapshot(proposalHash); IGovernor.ProposalState currentState = _angleGovernor.state(proposalHash); if (currentState != IGovernor.ProposalState.Succeeded) { @@ -102,8 +94,8 @@ contract Proposer is BaseActor { IGovernor.GovernorUnexpectedProposalState.selector, proposalHash, currentState, - bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) | - bytes32(1 << uint8(IGovernor.ProposalState.Queued)) + bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) + | bytes32(1 << uint8(IGovernor.ProposalState.Queued)) ) ); } diff --git a/test/invariant/actors/Voter.t.sol b/test/invariant/actors/Voter.t.sol index 44a431c..d5506d2 100644 --- a/test/invariant/actors/Voter.t.sol +++ b/test/invariant/actors/Voter.t.sol @@ -1,21 +1,18 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import { BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage } from "./BaseActor.t.sol"; -import { console } from "forge-std/console.sol"; -import { ProposalStore, Proposal } from "../stores/ProposalStore.sol"; -import { IGovernor } from "oz/governance/IGovernor.sol"; +import {BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage} from "./BaseActor.t.sol"; +import {console} from "forge-std/console.sol"; +import {ProposalStore, Proposal} from "../stores/ProposalStore.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; contract Voter is BaseActor { AngleGovernor internal _angleGovernor; ProposalStore public proposalStore; - constructor( - AngleGovernor angleGovernor, - IERC20 angle, - uint256 nbrVoter, - ProposalStore _proposalStore - ) BaseActor(nbrVoter, "Voter", angle) { + constructor(AngleGovernor angleGovernor, IERC20 angle, uint256 nbrVoter, ProposalStore _proposalStore) + BaseActor(nbrVoter, "Voter", angle) + { _angleGovernor = angleGovernor; proposalStore = _proposalStore; } @@ -26,12 +23,8 @@ contract Voter is BaseActor { } voteOutcome = bound(voteOutcome, 0, 2); Proposal memory proposal = proposalStore.getRandomProposal(proposalSeed); - uint256 proposalHash = _angleGovernor.hashProposal( - proposal.target, - proposal.value, - proposal.data, - proposal.description - ); + uint256 proposalHash = + _angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); IGovernor.ProposalState currentState = _angleGovernor.state(proposalHash); if (currentState != IGovernor.ProposalState.Active) { vm.expectRevert( diff --git a/test/scripts/timelock/AddExecutor.t.sol b/test/scripts/timelock/AddExecutor.t.sol index 9d0827f..87127dc 100644 --- a/test/scripts/timelock/AddExecutor.t.sol +++ b/test/scripts/timelock/AddExecutor.t.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import { stdJson } from "forge-std/StdJson.sol"; -import { console } from "forge-std/console.sol"; -import { ScriptHelpers } from "../ScriptHelpers.t.sol"; -import { IAccessControl } from "oz/access/IAccessControl.sol"; -import { TimelockController } from "oz/governance/TimelockController.sol"; +import {stdJson} from "forge-std/StdJson.sol"; +import {console} from "forge-std/console.sol"; +import {ScriptHelpers} from "../ScriptHelpers.t.sol"; +import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; +import {TimelockController} from "oz-v5/governance/TimelockController.sol"; import "../../../scripts/Constants.s.sol"; -import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; +import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; contract AddExecutorTest is ScriptHelpers { using stdJson for string; @@ -25,9 +25,8 @@ contract AddExecutorTest is ScriptHelpers { // Now test that everything is as expected for (uint256 i; i < chainIds.length; i++) { uint256 chainId = chainIds[i]; - TimelockControllerWithCounter timelock = TimelockControllerWithCounter( - payable(_chainToContract(chainId, ContractType.Timelock)) - ); + TimelockControllerWithCounter timelock = + TimelockControllerWithCounter(payable(_chainToContract(chainId, ContractType.Timelock))); vm.selectFork(forkIdentifier[chainId]); bytes32 EXECUTOR_ROLE = timelock.EXECUTOR_ROLE(); diff --git a/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol new file mode 100644 index 0000000..ea76872 --- /dev/null +++ b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +import {stdJson} from "forge-std/StdJson.sol"; +import {console} from "forge-std/console.sol"; +import {ScriptHelpers} from "../ScriptHelpers.t.sol"; +import {TransmuterUtils} from "../../../scripts/proposals/transmuter/TransmuterUtils.s.sol"; +import "../../../scripts/Constants.s.sol"; +import {OldTransmuter} from "../../../scripts/interfaces/ITransmuter.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; + +contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { + using stdJson for string; + + ITransmuter transmuter; + bytes public oracleConfigEUROC; + bytes public oracleConfigBC3M; + + function setUp() public override { + super.setUp(); + } + + function testScript() external { + uint256[] memory chainIds = _executeProposal(); + + // Now test that everything is as expected + for (uint256 i; i < chainIds.length; i++) { + uint256 chainId = chainIds[i]; + transmuter = ITransmuter(payable(_chainToContract(chainId, ContractType.TransmuterAgEUR))); + vm.selectFork(forkIdentifier[chainId]); + _testAccessControlManager(); + _testAgToken(); + _testGetCollateralList(); + } + } + + function _testAccessControlManager() internal { + assertEq(address(transmuter.accessControlManager()), _chainToContract(CHAIN_SOURCE, ContractType.CoreBorrow)); + } + + function _testAgToken() internal { + assertEq(address(transmuter.agToken()), _chainToContract(CHAIN_SOURCE, ContractType.AgEUR)); + } + + function _testGetCollateralList() internal { + address[] memory collateralList = transmuter.getCollateralList(); + assertEq(collateralList.length, 2); + assertEq(collateralList[0], address(EUROC)); + assertEq(collateralList[1], address(BC3M)); + } + + function testUnit_Upgrade_GetCollateralInfo() external { + { + Storage.Collateral memory collatInfoEUROC = transmuter.getCollateralInfo(address(EUROC)); + assertEq(collatInfoEUROC.isManaged, 0); + assertEq(collatInfoEUROC.isMintLive, 1); + assertEq(collatInfoEUROC.isBurnLive, 1); + assertEq(collatInfoEUROC.decimals, 6); + assertEq(collatInfoEUROC.onlyWhitelisted, 0); + assertApproxEqRel(collatInfoEUROC.normalizedStables, 10893124 * BASE_18, 100 * BPS); + assertEq(collatInfoEUROC.oracleConfig, oracleConfigEUROC); + assertEq(collatInfoEUROC.whitelistData.length, 0); + assertEq(collatInfoEUROC.managerData.subCollaterals.length, 0); + assertEq(collatInfoEUROC.managerData.config.length, 0); + + { + assertEq(collatInfoEUROC.xFeeMint.length, 5); + assertEq(collatInfoEUROC.yFeeMint.length, 5); + assertEq(collatInfoEUROC.xFeeMint[0], 0); + assertEq(collatInfoEUROC.yFeeMint[0], 0); + assertEq(collatInfoEUROC.xFeeMint[1], 730000000); + assertEq(collatInfoEUROC.yFeeMint[1], 0); + assertEq(collatInfoEUROC.xFeeMint[2], 740000000); + assertEq(collatInfoEUROC.yFeeMint[2], 500000); + assertEq(collatInfoEUROC.xFeeMint[3], 745000000); + assertEq(collatInfoEUROC.yFeeMint[3], 1000000); + assertEq(collatInfoEUROC.xFeeMint[4], 750000000); + assertEq(collatInfoEUROC.yFeeMint[4], 1000000000000); + } + { + assertEq(collatInfoEUROC.xFeeBurn.length, 5); + assertEq(collatInfoEUROC.yFeeBurn.length, 5); + assertEq(collatInfoEUROC.xFeeBurn[0], 1000000000); + assertEq(collatInfoEUROC.yFeeBurn[0], 0); + assertEq(collatInfoEUROC.xFeeBurn[1], 670000000); + assertEq(collatInfoEUROC.yFeeBurn[1], 0); + assertEq(collatInfoEUROC.xFeeBurn[2], 590000000); + assertEq(collatInfoEUROC.yFeeBurn[2], 1000000); + assertEq(collatInfoEUROC.xFeeBurn[3], 505000000); + assertEq(collatInfoEUROC.yFeeBurn[3], 1000000); + assertEq(collatInfoEUROC.xFeeBurn[4], 500000000); + assertEq(collatInfoEUROC.yFeeBurn[4], 999000000); + } + } + + { + Storage.Collateral memory collatInfoBC3M = transmuter.getCollateralInfo(address(BC3M)); + assertEq(collatInfoBC3M.isManaged, 0); + assertEq(collatInfoBC3M.isMintLive, 1); + assertEq(collatInfoBC3M.isBurnLive, 1); + assertEq(collatInfoBC3M.decimals, 18); + assertEq(collatInfoBC3M.onlyWhitelisted, 1); + assertApproxEqRel(collatInfoBC3M.normalizedStables, 6236650 * BASE_18, 100 * BPS); + assertEq(collatInfoBC3M.oracleConfig, oracleConfigBC3M); + { + (Storage.WhitelistType whitelist, bytes memory data) = + abi.decode(collatInfoBC3M.whitelistData, (Storage.WhitelistType, bytes)); + address keyringGuard = abi.decode(data, (address)); + assertEq(uint8(whitelist), uint8(Storage.WhitelistType.BACKED)); + assertEq(keyringGuard, 0x9391B14dB2d43687Ea1f6E546390ED4b20766c46); + } + assertEq(collatInfoBC3M.managerData.subCollaterals.length, 0); + assertEq(collatInfoBC3M.managerData.config.length, 0); + + { + assertEq(collatInfoBC3M.xFeeMint.length, 4); + assertEq(collatInfoBC3M.yFeeMint.length, 4); + assertEq(collatInfoBC3M.xFeeMint[0], 0); + assertEq(collatInfoBC3M.yFeeMint[0], 0); + assertEq(collatInfoBC3M.xFeeMint[1], 400000000); + assertEq(collatInfoBC3M.yFeeMint[1], 0); + assertEq(collatInfoBC3M.xFeeMint[2], 495000000); + assertEq(collatInfoBC3M.yFeeMint[2], 2000000); + assertEq(collatInfoBC3M.xFeeMint[3], 500000000); + assertEq(collatInfoBC3M.yFeeMint[3], 1000000000000); + } + { + assertEq(collatInfoBC3M.xFeeBurn.length, 3); + assertEq(collatInfoBC3M.yFeeBurn.length, 3); + assertEq(collatInfoBC3M.xFeeBurn[0], 1000000000); + assertEq(collatInfoBC3M.yFeeBurn[0], 5000000); + assertEq(collatInfoBC3M.xFeeBurn[1], 260000000); + assertEq(collatInfoBC3M.yFeeBurn[1], 5000000); + assertEq(collatInfoBC3M.xFeeBurn[2], 250000000); + assertEq(collatInfoBC3M.yFeeBurn[2], 999000000); + } + } + } + + /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ORACLE + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + + function testUnit_Upgrade_getOracleValues_Success() external { + _checkOracleValues(address(EUROC), BASE_18, FIREWALL_MINT_EUROC, FIREWALL_BURN_EUROC); + _checkOracleValues(address(BC3M), (11944 * BASE_18) / 100, FIREWALL_MINT_BC3M, FIREWALL_BURN_BC3M); + } + + /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + CHECKS + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ + + function _checkOracleValues(address collateral, uint256 targetValue, uint128 firewallMint, uint128 firewallBurn) + internal + { + (uint256 mint, uint256 burn, uint256 ratio, uint256 minRatio, uint256 redemption) = + transmuter.getOracleValues(collateral); + assertApproxEqRel(targetValue, redemption, 200 * BPS); + assertEq(burn, redemption); + if (redemption * BASE_18 < targetValue * (BASE_18 - firewallBurn)) { + assertEq(mint, redemption); + assertEq(ratio, (redemption * BASE_18) / targetValue); + } else if (redemption < targetValue) { + assertEq(mint, redemption); + assertEq(ratio, BASE_18); + } else if (redemption * BASE_18 < targetValue * ((BASE_18 + firewallMint))) { + assertEq(mint, redemption); + assertEq(ratio, BASE_18); + } else { + assertEq(mint, targetValue); + assertEq(ratio, BASE_18); + } + } +} diff --git a/test/unit/AngleGovernor.t.sol b/test/unit/AngleGovernor.t.sol index 8be2108..266c741 100644 --- a/test/unit/AngleGovernor.t.sol +++ b/test/unit/AngleGovernor.t.sol @@ -2,18 +2,18 @@ pragma solidity ^0.8.9; -import { IGovernor } from "oz/governance/IGovernor.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { Strings } from "oz/utils/Strings.sol"; - -import { Test, stdError } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; - -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { VeANGLEVotingDelegation } from "contracts/VeANGLEVotingDelegation.sol"; -import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {Strings} from "oz-v5/utils/Strings.sol"; + +import {Test, stdError} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; + +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {VeANGLEVotingDelegation} from "contracts/VeANGLEVotingDelegation.sol"; +import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Utils.t.sol"; @@ -87,12 +87,8 @@ contract AngleGovernorTest is Test, Utils { executors[0] = address(0); // Means everyone can execute vm.startPrank(alice); - TimelockControllerWithCounter mainnetTimelock2 = new TimelockControllerWithCounter( - 1 days, - proposers, - executors, - address(this) - ); + TimelockControllerWithCounter mainnetTimelock2 = + new TimelockControllerWithCounter(1 days, proposers, executors, address(this)); vm.expectRevert(Errors.NotExecutor.selector); angleGovernor.updateTimelock(address(mainnetTimelock2)); vm.expectRevert(Errors.NotExecutor.selector); @@ -117,12 +113,8 @@ contract AngleGovernorTest is Test, Utils { address[] memory proposers = new address[](0); address[] memory executors = new address[](1); executors[0] = address(0); // Means everyone can execute - TimelockControllerWithCounter mainnetTimelock2 = new TimelockControllerWithCounter( - 1 days, - proposers, - executors, - address(this) - ); + TimelockControllerWithCounter mainnetTimelock2 = + new TimelockControllerWithCounter(1 days, proposers, executors, address(this)); vm.expectRevert(Errors.ZeroAddress.selector); hoax(address(mainnetTimelock)); diff --git a/test/unit/GovernorShortCircuit.t.sol b/test/unit/GovernorShortCircuit.t.sol index 26e3247..d2a1971 100644 --- a/test/unit/GovernorShortCircuit.t.sol +++ b/test/unit/GovernorShortCircuit.t.sol @@ -2,21 +2,21 @@ pragma solidity ^0.8.9; -import { IGovernor } from "oz/governance/IGovernor.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { GovernorCountingSimple } from "oz/governance/extensions/GovernorCountingSimple.sol"; -import { Strings } from "oz/utils/Strings.sol"; -import { ERC20 } from "oz/token/ERC20/ERC20.sol"; - -import { stdStorage, StdStorage, Test, stdError } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; - -import { deployMockANGLE, MockANGLE } from "../../scripts/test/DeployANGLE.s.sol"; -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { VeANGLEVotingDelegation } from "contracts/VeANGLEVotingDelegation.sol"; -import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {GovernorCountingSimple} from "oz-v5/governance/extensions/GovernorCountingSimple.sol"; +import {Strings} from "oz-v5/utils/Strings.sol"; +import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; + +import {stdStorage, StdStorage, Test, stdError} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; + +import {deployMockANGLE, MockANGLE} from "../../scripts/test/DeployANGLE.s.sol"; +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {VeANGLEVotingDelegation} from "contracts/VeANGLEVotingDelegation.sol"; +import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Utils.t.sol"; @@ -45,7 +45,7 @@ contract GovernorShortCircuitTest is Test, Utils { vm.roll(block.number + 1152); vm.warp(block.timestamp + 10 days); - (address _mockANGLE, , ) = deployMockANGLE(); + (address _mockANGLE,,) = deployMockANGLE(); ANGLE = MockANGLE(_mockANGLE); veANGLEDelegation = new VeANGLEVotingDelegation(address(veANGLE), "veANGLE Delegation", "1"); @@ -92,11 +92,10 @@ contract GovernorShortCircuitTest is Test, Utils { angleGovernor.castVote(proposalId, uint8(GovernorCountingSimple.VoteType.Against)); } - function _proposeTx( - address[] memory targets, - uint256[] memory values, - bytes[] memory calldatas - ) public returns (uint256 pid) { + function _proposeTx(address[] memory targets, uint256[] memory values, bytes[] memory calldatas) + public + returns (uint256 pid) + { vm.mockCall( address(veANGLEDelegation), abi.encodeWithSelector(veANGLEDelegation.getPastVotes.selector, address(proposer)), @@ -127,9 +126,7 @@ contract GovernorShortCircuitTest is Test, Utils { mineBlocksBySecond(angleGovernor.votingPeriod()); assertEq( - uint256(IGovernor.ProposalState.Succeeded), - uint256(angleGovernor.state(pid)), - "Proposal state is succeeded" + uint256(IGovernor.ProposalState.Succeeded), uint256(angleGovernor.state(pid)), "Proposal state is succeeded" ); stdstore.target(address(angleGovernor)).sig("timelock()").checked_write(address(angleGovernor)); @@ -190,9 +187,7 @@ contract GovernorShortCircuitTest is Test, Utils { _votePassingQuorum(pid); assertEq( - uint256(IGovernor.ProposalState.Succeeded), - uint256(angleGovernor.state(pid)), - "Proposal state is succeeded" + uint256(IGovernor.ProposalState.Succeeded), uint256(angleGovernor.state(pid)), "Proposal state is succeeded" ); // majorityFor allows skipping delay but still timelock @@ -201,9 +196,7 @@ contract GovernorShortCircuitTest is Test, Utils { assertEq(ANGLE.balanceOf(bob), amount, "Bob received ANGLE"); assertEq(ANGLE.balanceOf(address(angleGovernor)), 0, "angleGovernor has no ANGLE"); assertEq( - uint256(IGovernor.ProposalState.Executed), - uint256(angleGovernor.state(pid)), - "Proposal state is executed" + uint256(IGovernor.ProposalState.Executed), uint256(angleGovernor.state(pid)), "Proposal state is executed" ); } @@ -235,9 +228,7 @@ contract GovernorShortCircuitTest is Test, Utils { _voteDefeatQuorum(pid); assertEq( - uint256(IGovernor.ProposalState.Defeated), - uint256(angleGovernor.state(pid)), - "Proposal state is defeated" + uint256(IGovernor.ProposalState.Defeated), uint256(angleGovernor.state(pid)), "Proposal state is defeated" ); vm.expectRevert( diff --git a/test/unit/GovernorStateAndPropose.t.sol b/test/unit/GovernorStateAndPropose.t.sol index 9bfbe7f..d6033c5 100644 --- a/test/unit/GovernorStateAndPropose.t.sol +++ b/test/unit/GovernorStateAndPropose.t.sol @@ -2,18 +2,18 @@ pragma solidity ^0.8.9; -import { IGovernor } from "oz/governance/IGovernor.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { Strings } from "oz/utils/Strings.sol"; - -import { Test, stdError } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; - -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { VeANGLEVotingDelegation } from "contracts/VeANGLEVotingDelegation.sol"; -import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {Strings} from "oz-v5/utils/Strings.sol"; + +import {Test, stdError} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; + +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {VeANGLEVotingDelegation} from "contracts/VeANGLEVotingDelegation.sol"; +import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Utils.t.sol"; @@ -81,10 +81,7 @@ contract GovernorStateAndProposeTest is Test, Utils { vm.expectRevert( abi.encodeWithSelector( - IGovernor.GovernorInsufficientProposerVotes.selector, - whale, - votes, - angleGovernor.proposalThreshold() + IGovernor.GovernorInsufficientProposerVotes.selector, whale, votes, angleGovernor.proposalThreshold() ) ); hoax(whale); @@ -110,10 +107,7 @@ contract GovernorStateAndProposeTest is Test, Utils { vm.expectRevert( abi.encodeWithSelector( - IGovernor.GovernorInvalidProposalLength.selector, - targets.length, - calldatas.length, - values.length + IGovernor.GovernorInvalidProposalLength.selector, targets.length, calldatas.length, values.length ) ); hoax(whale); @@ -130,10 +124,7 @@ contract GovernorStateAndProposeTest is Test, Utils { vm.expectRevert( abi.encodeWithSelector( - IGovernor.GovernorInvalidProposalLength.selector, - targets.length, - calldatas.length, - values.length + IGovernor.GovernorInvalidProposalLength.selector, targets.length, calldatas.length, values.length ) ); hoax(whale); @@ -153,10 +144,7 @@ contract GovernorStateAndProposeTest is Test, Utils { vm.expectRevert( abi.encodeWithSelector( - IGovernor.GovernorInvalidProposalLength.selector, - targets.length, - calldatas.length, - values.length + IGovernor.GovernorInvalidProposalLength.selector, targets.length, calldatas.length, values.length ) ); hoax(whale); diff --git a/test/unit/ProposalLayerZeroRelayer.t.sol b/test/unit/ProposalLayerZeroRelayer.t.sol index 53607a1..fa3deb6 100644 --- a/test/unit/ProposalLayerZeroRelayer.t.sol +++ b/test/unit/ProposalLayerZeroRelayer.t.sol @@ -2,23 +2,23 @@ pragma solidity ^0.8.9; -import { IGovernor } from "oz/governance/IGovernor.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { IAccessControl } from "oz/access/IAccessControl.sol"; -import { Strings } from "oz/utils/Strings.sol"; - -import { console } from "forge-std/console.sol"; -import { Test, stdError } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; - -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender, Ownable } from "contracts/ProposalSender.sol"; -import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; - -import { SubCall } from "./Proposal.sol"; -import { SimulationSetup } from "./SimulationSetup.t.sol"; -import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; +import {Strings} from "oz-v5/utils/Strings.sol"; + +import {console} from "forge-std/console.sol"; +import {Test, stdError} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; + +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender, Ownable} from "contracts/ProposalSender.sol"; +import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; + +import {SubCall} from "./Proposal.sol"; +import {SimulationSetup} from "./SimulationSetup.t.sol"; +import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Constants.t.sol"; @@ -47,7 +47,7 @@ contract ProposalLayerZeroRelayer is SimulationSetup { timelock(destChain).grantRole.selector, timelock(destChain).PROPOSER_ROLE(), address(newReceiverOptimism) - ) + ) }); p[1] = SubCall({ chainId: destChain, @@ -57,7 +57,7 @@ contract ProposalLayerZeroRelayer is SimulationSetup { timelock(destChain).revokeRole.selector, timelock(destChain).PROPOSER_ROLE(), address(proposalReceiver(destChain)) - ) + ) }); string memory description = "Updating relayer receiver on Optimism"; _crossChainProposal(destChain, p, description, 0.1 ether, hex"", address(0)); @@ -114,24 +114,23 @@ contract ProposalLayerZeroRelayer is SimulationSetup { uint64 defaultBlockConfirmation = 0; - /** Can be modified */ + /** + * Can be modified + */ uint16 version = 2; uint16 chainId = 1; uint16 configType = 2; uint64 blockConfirmation = 365; - /** Stop */ - + /** + * Stop + */ address[] memory targets = new address[](1); uint256[] memory values = new uint256[](1); bytes[] memory calldatas = new bytes[](1); targets[0] = address(proposalSender()); values[0] = 0; calldatas[0] = abi.encodeWithSelector( - proposalSender().setConfig.selector, - version, - chainId, - configType, - abi.encode(blockConfirmation) + proposalSender().setConfig.selector, version, chainId, configType, abi.encode(blockConfirmation) ); string memory description = "Updating config on Mainnet"; @@ -146,10 +145,13 @@ contract ProposalLayerZeroRelayer is SimulationSetup { uint64 defaultVersion = 2; - /** Can be modified */ + /** + * Can be modified + */ uint16 version = 1; - /** Stop */ - + /** + * Stop + */ address[] memory targets = new address[](1); uint256[] memory values = new uint256[](1); bytes[] memory calldatas = new bytes[](1); @@ -176,17 +178,15 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), - abi.encodeWithSelector(_lzEndPoint(1).send.selector), - abi.encode("REVERT") + address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") ); assertEq(uint256(proposalSender().lastStoredPayloadNonce()), 0); _dummyProposal(1, p, description, 0.1 ether, hex""); assertEq(uint256(proposalSender().lastStoredPayloadNonce()), 1); - bytes - memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); - (uint nativeFee, uint zroFee) = proposalSender().estimateFees(_getLZChainId(137), payload, adapterParams); + (uint256 nativeFee, uint256 zroFee) = proposalSender().estimateFees(_getLZChainId(137), payload, adapterParams); assertEq(zroFee, 0); assertGt(nativeFee, 0); assertLe(nativeFee, 0.1 ether); @@ -212,9 +212,7 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), - abi.encodeWithSelector(_lzEndPoint(1).send.selector), - abi.encode("REVERT") + address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") ); _dummyProposal(1, p, description, 0.1 ether, hex""); vm.expectRevert(abi.encodeWithSelector(Errors.OmnichainProposalSenderInvalidExecParams.selector)); @@ -240,10 +238,10 @@ contract ProposalLayerZeroRelayer is SimulationSetup { abi.encodeWithSelector(_lzEndPoint(srcChain).send.selector), abi.encode("REVERT") ); - bytes - memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); - (uint256 nativeFee, ) = proposalSender().estimateFees(_getLZChainId(destChain), payload, adapterParams); + (uint256 nativeFee,) = proposalSender().estimateFees(_getLZChainId(destChain), payload, adapterParams); assertLe(nativeFee, 0.1 ether); _dummyProposal(srcChain, p, description, 0.1 ether, hex""); vm.clearMockedCalls(); @@ -256,18 +254,13 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(srcChain), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload + _getLZChainId(srcChain), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload ); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + timelock(destChain).getMinDelay() + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -287,12 +280,10 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), - abi.encodeWithSelector(_lzEndPoint(1).send.selector), - abi.encode("REVERT") + address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") ); - bytes - memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload1 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -302,14 +293,12 @@ contract ProposalLayerZeroRelayer is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, - timelock(1).PROPOSER_ROLE(), - address(alice) - ) + timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) + ) }); description = "Grant role on Optimism"; - bytes - memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload2 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -326,20 +315,15 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload1 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 ); uint256 oldDelay = timelock(destChain).getMinDelay(); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p1 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p1); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -347,18 +331,13 @@ contract ProposalLayerZeroRelayer is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload2 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 ); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p2 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p2); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -379,12 +358,10 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), - abi.encodeWithSelector(_lzEndPoint(1).send.selector), - abi.encode("REVERT") + address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") ); - bytes - memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload1 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -394,14 +371,12 @@ contract ProposalLayerZeroRelayer is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, - timelock(1).PROPOSER_ROLE(), - address(alice) - ) + timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) + ) }); description = "Grant role on Optimism"; - bytes - memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload2 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -418,20 +393,15 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload2 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 ); uint256 oldDelay = timelock(destChain).getMinDelay(); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p2 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p2); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -439,18 +409,13 @@ contract ProposalLayerZeroRelayer is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload1 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 ); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p1 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p1); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -471,12 +436,10 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), - abi.encodeWithSelector(_lzEndPoint(1).send.selector), - abi.encode("REVERT") + address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") ); - bytes - memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload1 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -486,14 +449,12 @@ contract ProposalLayerZeroRelayer is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, - timelock(1).PROPOSER_ROLE(), - address(alice) - ) + timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) + ) }); description = "Grant role on Optimism"; - bytes - memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload2 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -510,20 +471,15 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload1 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 ); uint256 oldDelay = timelock(destChain).getMinDelay(); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p1 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p1); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -531,18 +487,13 @@ contract ProposalLayerZeroRelayer is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload2 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 ); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p2 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p2); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -563,12 +514,10 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), - abi.encodeWithSelector(_lzEndPoint(1).send.selector), - abi.encode("REVERT") + address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") ); - bytes - memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload1 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -578,14 +527,12 @@ contract ProposalLayerZeroRelayer is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, - timelock(1).PROPOSER_ROLE(), - address(alice) - ) + timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) + ) }); description = "Grant role on Optimism"; - bytes - memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload2 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -602,20 +549,15 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload2 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 ); uint256 oldDelay = timelock(destChain).getMinDelay(); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p2 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p2); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -623,18 +565,13 @@ contract ProposalLayerZeroRelayer is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload1 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 ); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p1 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p1); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -656,21 +593,17 @@ contract ProposalLayerZeroRelayer is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, - timelock(1).PROPOSER_ROLE(), - address(alice) - ) + timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) + ) }); string memory description = "Batch delay and grantRole on Optimism"; vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), - abi.encodeWithSelector(_lzEndPoint(1).send.selector), - abi.encode("REVERT") + address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") ); - bytes - memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002c48f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002c48f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p, description, 0.1 ether, hex""); vm.clearMockedCalls(); @@ -683,18 +616,13 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload ); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + timelock(destChain).getMinDelay() + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).executeBatch(targets, values, calldatas, bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -706,12 +634,8 @@ contract ProposalLayerZeroRelayer is SimulationSetup { address[] memory proposers = new address[](0); address[] memory executors = new address[](1); executors[0] = address(0); // Means everyone can execute - TimelockControllerWithCounter timelock2 = new TimelockControllerWithCounter( - 1 days, - proposers, - executors, - address(this) - ); + TimelockControllerWithCounter timelock2 = + new TimelockControllerWithCounter(1 days, proposers, executors, address(this)); AngleGovernor governor2 = new AngleGovernor( veANGLEDelegation, address(timelock2), @@ -743,7 +667,7 @@ contract ProposalLayerZeroRelayer is SimulationSetup { proposalSender(), 0, abi.encodeWithSelector(proposalSender().transferOwnership.selector, address(governor2)) - ) + ) }); (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = wrap(p); @@ -798,31 +722,23 @@ contract ProposalLayerZeroRelayer is SimulationSetup { chainId: 137, target: address(timelock(137)), value: 0, - data: abi.encodeWithSelector( - timelock(1).grantRole.selector, - timelock(1).PROPOSER_ROLE(), - newProposalReceiver - ) + data: abi.encodeWithSelector(timelock(1).grantRole.selector, timelock(1).PROPOSER_ROLE(), newProposalReceiver) }); p[1] = SubCall({ chainId: 137, target: address(timelock(137)), value: 0, data: abi.encodeWithSelector( - timelock(1).revokeRole.selector, - timelock(1).PROPOSER_ROLE(), - address(proposalReceiver(137)) - ) + timelock(1).revokeRole.selector, timelock(1).PROPOSER_ROLE(), address(proposalReceiver(137)) + ) }); p[2] = SubCall({ chainId: 1, target: address(proposalSender()), value: 0, data: abi.encodeWithSelector( - proposalSender().setTrustedRemoteAddress.selector, - _getLZChainId(137), - abi.encodePacked(proposalReceiver2) - ) + proposalSender().setTrustedRemoteAddress.selector, _getLZChainId(137), abi.encodePacked(proposalReceiver2) + ) }); string memory description = "Updating Proposal receiver on Polygon"; @@ -839,14 +755,14 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.warp(block.timestamp + governor().votingPeriod() + 1); vm.recordLogs(); - governor().execute{ value: 0.1 ether }(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value + governor().execute{value: 0.1 ether}(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value Vm.Log[] memory entries = vm.getRecordedLogs(); bytes memory payload; for (uint256 i; i < entries.length; i++) { if ( - entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") && - entries[i].topics[1] == bytes32(uint256(_getLZChainId(137))) + entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") + && entries[i].topics[1] == bytes32(uint256(_getLZChainId(137))) ) { payload = abi.decode(entries[i].data, (bytes)); break; @@ -856,10 +772,7 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[137]); hoax(address(_lzEndPoint(137))); proposalReceiver(137).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(137)), - 0, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(137)), 0, payload ); // Final test @@ -889,8 +802,8 @@ contract ProposalLayerZeroRelayer is SimulationSetup { assertEq(uint256(proposalSender().lastStoredPayloadNonce()), 0); vm.selectFork(forkIdentifier[destChain]); - bytes - memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); bytes memory execution = abi.encode(_getLZChainId(destChain), payload, adapterParams, 0.1 ether); vm.mockCallRevert( @@ -900,42 +813,29 @@ contract ProposalLayerZeroRelayer is SimulationSetup { ); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload ); assertEq( proposalReceiver(destChain).failedMessages( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0 ), keccak256(payload) ); vm.expectRevert(Errors.OmnichainGovernanceExecutorTxExecReverted.selector); proposalReceiver(destChain).retryMessage( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload ); vm.clearMockedCalls(); assertEq(timelock(destChain).getMinDelay() != 100, true); proposalReceiver(destChain).retryMessage( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload ); vm.warp(block.timestamp + timelock(destChain).getMinDelay() + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); } @@ -966,8 +866,8 @@ contract ProposalLayerZeroRelayer is SimulationSetup { assertEq(uint256(proposalSender().lastStoredPayloadNonce()), 0); vm.selectFork(forkIdentifier[destChain]); - bytes - memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); bytes memory execution = abi.encode(_getLZChainId(destChain), payload, adapterParams, 0.1 ether); vm.mockCallRevert( @@ -977,42 +877,29 @@ contract ProposalLayerZeroRelayer is SimulationSetup { ); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 1, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1, payload ); assertEq( proposalReceiver(destChain).failedMessages( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 1 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1 ), keccak256(payload) ); vm.expectRevert(Errors.OmnichainGovernanceExecutorTxExecReverted.selector); proposalReceiver(destChain).retryMessage( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 1, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1, payload ); vm.clearMockedCalls(); assertEq(timelock(destChain).getMinDelay() != 100, true); proposalReceiver(destChain).retryMessage( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 1, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1, payload ); vm.warp(block.timestamp + oldDelay + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); } @@ -1047,8 +934,8 @@ contract ProposalLayerZeroRelayer is SimulationSetup { } vm.selectFork(forkIdentifier[destChain]); - bytes - memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; vm.mockCallRevert( address(timelock(destChain)), abi.encodeWithSelector(timelock(destChain).schedule.selector), @@ -1056,26 +943,18 @@ contract ProposalLayerZeroRelayer is SimulationSetup { ); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 1, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1, payload ); vm.clearMockedCalls(); assertEq(timelock(destChain).getMinDelay() != oldDelay, true); proposalReceiver(destChain).retryMessage( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 1, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1, payload ); vm.warp(block.timestamp + newDelay + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p); vm.expectRevert( abi.encodeWithSelector( TimelockController.TimelockUnexpectedOperationState.selector, @@ -1112,9 +991,7 @@ contract ProposalLayerZeroRelayer is SimulationSetup { string memory description = "Updating delay on Optimism"; bytes memory error = abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, - alice, - timelock(1).EXECUTOR_ROLE() + IAccessControl.AccessControlUnauthorizedAccount.selector, alice, timelock(1).EXECUTOR_ROLE() ); _crossChainProposal(destChain, p, description, 0.1 ether, error, alice); } diff --git a/test/unit/Scenarios.t.sol b/test/unit/Scenarios.t.sol index 5247327..948b257 100644 --- a/test/unit/Scenarios.t.sol +++ b/test/unit/Scenarios.t.sol @@ -2,22 +2,22 @@ pragma solidity ^0.8.9; -import { IGovernor } from "oz/governance/IGovernor.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { Strings } from "oz/utils/Strings.sol"; - -import { console } from "forge-std/console.sol"; -import { Test, stdError } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; - -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; - -import { SubCall } from "./Proposal.sol"; -import { SimulationSetup } from "./SimulationSetup.t.sol"; -import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {Strings} from "oz-v5/utils/Strings.sol"; + +import {console} from "forge-std/console.sol"; +import {Test, stdError} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; + +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; + +import {SubCall} from "./Proposal.sol"; +import {SimulationSetup} from "./SimulationSetup.t.sol"; +import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "../Constants.t.sol"; //solhint-disable @@ -125,14 +125,14 @@ contract Scenarios is SimulationSetup { vm.warp(block.timestamp + governor().votingPeriod() + 1); vm.recordLogs(); - governor().execute{ value: 0.1 ether }(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value + governor().execute{value: 0.1 ether}(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value Vm.Log[] memory entries = vm.getRecordedLogs(); bytes memory payload; for (uint256 i; i < entries.length; i++) { if ( - entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") && - entries[i].topics[1] == bytes32(uint256(_getLZChainId(137))) + entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") + && entries[i].topics[1] == bytes32(uint256(_getLZChainId(137))) ) { payload = abi.decode(entries[i].data, (bytes)); break; @@ -142,10 +142,7 @@ contract Scenarios is SimulationSetup { vm.selectFork(forkIdentifier[137]); hoax(address(_lzEndPoint(137))); proposalReceiver(137).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(137)), - 0, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(137)), 0, payload ); // Final test diff --git a/test/unit/Simulate.t.sol b/test/unit/Simulate.t.sol index 659dfd1..9af05cb 100644 --- a/test/unit/Simulate.t.sol +++ b/test/unit/Simulate.t.sol @@ -2,20 +2,20 @@ pragma solidity ^0.8.9; -import { IGovernor } from "oz/governance/IGovernor.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { Strings } from "oz/utils/Strings.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {Strings} from "oz-v5/utils/Strings.sol"; -import { console } from "forge-std/console.sol"; -import { Vm } from "forge-std/Vm.sol"; +import {console} from "forge-std/console.sol"; +import {Vm} from "forge-std/Vm.sol"; -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; -import { Proposal, SubCall } from "./Proposal.sol"; -import { SimulationSetup } from "./SimulationSetup.t.sol"; -import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import {Proposal, SubCall} from "./Proposal.sol"; +import {SimulationSetup} from "./SimulationSetup.t.sol"; +import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "stringutils/strings.sol"; import "../Constants.t.sol"; @@ -36,11 +36,11 @@ contract ProposalSimulateTest is SimulationSetup { vm.warp(block.timestamp + governor().votingPeriod() + 1); vm.recordLogs(); - governor().execute{ value: 1 ether }(targets, values, calldatas, keccak256(bytes(description))); + governor().execute{value: 1 ether}(targets, values, calldatas, keccak256(bytes(description))); Vm.Log[] memory entries = vm.getRecordedLogs(); // Mainnet execution - (address[] memory batchTargets, , ) = filterChainSubCalls(1, p); + (address[] memory batchTargets,,) = filterChainSubCalls(1, p); if (batchTargets.length > 0) { executeTimelock(1, p); } @@ -52,10 +52,7 @@ contract ProposalSimulateTest is SimulationSetup { vm.selectFork(forkIdentifier[chainId]); hoax(address(_lzEndPoint(chainId))); proposalReceiver(chainId).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(chainId)), - 0, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(chainId)), 0, payload ); // Final test diff --git a/test/unit/SimulationSetup.t.sol b/test/unit/SimulationSetup.t.sol index ef88db5..35c6d43 100644 --- a/test/unit/SimulationSetup.t.sol +++ b/test/unit/SimulationSetup.t.sol @@ -2,22 +2,22 @@ pragma solidity ^0.8.9; -import { IGovernor } from "oz/governance/IGovernor.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { Strings } from "oz/utils/Strings.sol"; - -import { console } from "forge-std/console.sol"; -import { Test, stdError } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; - -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { VeANGLEVotingDelegation } from "contracts/VeANGLEVotingDelegation.sol"; -import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; - -import { Proposal, SubCall } from "./Proposal.sol"; -import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {Strings} from "oz-v5/utils/Strings.sol"; + +import {console} from "forge-std/console.sol"; +import {Test, stdError} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; + +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender} from "contracts/ProposalSender.sol"; +import {VeANGLEVotingDelegation} from "contracts/VeANGLEVotingDelegation.sol"; +import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; + +import {Proposal, SubCall} from "./Proposal.sol"; +import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "stringutils/strings.sol"; import "utils/src/CommonUtils.sol"; @@ -68,12 +68,7 @@ contract SimulationSetup is Test, CommonUtils { address[] memory executors = new address[](1); executors[0] = address(0); // Means everyone can execute - _timelocks[chainIds[i]] = new TimelockControllerWithCounter( - 1 days, - proposers, - executors, - address(this) - ); + _timelocks[chainIds[i]] = new TimelockControllerWithCounter(1 days, proposers, executors, address(this)); _governor = new AngleGovernor( veANGLEDelegation, address(_timelocks[chainIds[i]]), @@ -95,29 +90,21 @@ contract SimulationSetup is Test, CommonUtils { address[] memory executors = new address[](1); executors[0] = address(0); // Means everyone can execute - _timelocks[chainIds[i]] = new TimelockControllerWithCounter( - 1 days, - proposers, - executors, - address(this) - ); + _timelocks[chainIds[i]] = new TimelockControllerWithCounter(1 days, proposers, executors, address(this)); _proposalReceivers[chainIds[i]] = new ProposalReceiver(address(_lzEndPoint(chainIds[i]))); _timelocks[chainIds[i]].grantRole( - _timelocks[chainIds[i]].PROPOSER_ROLE(), - address(_proposalReceivers[chainIds[i]]) + _timelocks[chainIds[i]].PROPOSER_ROLE(), address(_proposalReceivers[chainIds[i]]) ); _timelocks[chainIds[i]].grantRole(_timelocks[chainIds[i]].CANCELLER_ROLE(), multisig(chainIds[i])); vm.selectFork(forkIdentifier[1]); _proposalSender.setTrustedRemoteAddress( - _getLZChainId(chainIds[i]), - abi.encodePacked(_proposalReceivers[chainIds[i]]) + _getLZChainId(chainIds[i]), abi.encodePacked(_proposalReceivers[chainIds[i]]) ); vm.selectFork(forkIdentifier[chainIds[i]]); _proposalReceivers[chainIds[i]].setTrustedRemoteAddress( - _getLZChainId(1), - abi.encodePacked(_proposalSender) + _getLZChainId(1), abi.encodePacked(_proposalSender) ); _proposalReceivers[chainIds[i]].transferOwnership(address(_timelocks[chainIds[i]])); } @@ -163,9 +150,10 @@ contract SimulationSetup is Test, CommonUtils { // TODO USE IT /// @notice Build the governor proposal based on all the transaction that need to be executed - function wrap( - SubCall[] memory prop - ) internal returns (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) { + function wrap(SubCall[] memory prop) + internal + returns (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) + { targets = new address[](prop.length); values = new uint256[](prop.length); calldatas = new bytes[](prop.length); @@ -189,25 +177,17 @@ contract SimulationSetup is Test, CommonUtils { if (chainId == 1) { vm.selectFork(forkIdentifier[1]); - ( - address[] memory batchTargets, - uint256[] memory batchValues, - bytes[] memory batchCalldatas - ) = filterChainSubCalls(chainId, prop); - (targets[finalPropLength], values[finalPropLength], calldatas[finalPropLength]) = wrapTimelock( - chainId, - prop - ); + (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) = + filterChainSubCalls(chainId, prop); + (targets[finalPropLength], values[finalPropLength], calldatas[finalPropLength]) = + wrapTimelock(chainId, prop); finalPropLength += 1; i += count; } else { vm.selectFork(forkIdentifier[chainId]); - ( - address[] memory batchTargets, - uint256[] memory batchValues, - bytes[] memory batchCalldatas - ) = filterChainSubCalls(chainId, prop); + (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) = + filterChainSubCalls(chainId, prop); (address target, uint256 value, bytes memory data) = wrapTimelock(chainId, prop); batchTargets = new address[](1); @@ -238,10 +218,7 @@ contract SimulationSetup is Test, CommonUtils { vm.selectFork(forkIdentifier[1]); // Set back the fork to mainnet } - function filterChainSubCalls( - uint256 chainId, - SubCall[] memory prop - ) + function filterChainSubCalls(uint256 chainId, SubCall[] memory prop) internal pure returns (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) @@ -266,15 +243,13 @@ contract SimulationSetup is Test, CommonUtils { } } - function wrapTimelock( - uint256 chainId, - SubCall[] memory p - ) public view returns (address target, uint256 value, bytes memory data) { - ( - address[] memory batchTargets, - uint256[] memory batchValues, - bytes[] memory batchCalldatas - ) = filterChainSubCalls(chainId, p); + function wrapTimelock(uint256 chainId, SubCall[] memory p) + public + view + returns (address target, uint256 value, bytes memory data) + { + (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) = + filterChainSubCalls(chainId, p); if (batchTargets.length == 1) { // In case the operation has already been done add a salt uint256 salt = computeSalt(chainId, p); @@ -310,11 +285,8 @@ contract SimulationSetup is Test, CommonUtils { function executeTimelock(uint256 chainId, SubCall[] memory p) internal { vm.selectFork(forkIdentifier[chainId]); vm.warp(block.timestamp + timelock(chainId).getMinDelay() + 1); - ( - address[] memory batchTargets, - uint256[] memory batchValues, - bytes[] memory batchCalldatas - ) = filterChainSubCalls(chainId, p); + (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) = + filterChainSubCalls(chainId, p); uint256 salt = computeSalt(chainId, p); if (batchTargets.length == 1) { timelock(chainId).execute(batchTargets[0], batchValues[0], batchCalldatas[0], bytes32(0), 0); @@ -324,21 +296,14 @@ contract SimulationSetup is Test, CommonUtils { } function computeSalt(uint256 chainId, SubCall[] memory p) internal view returns (uint256 salt) { - ( - address[] memory batchTargets, - uint256[] memory batchValues, - bytes[] memory batchCalldatas - ) = filterChainSubCalls(chainId, p); + (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) = + filterChainSubCalls(chainId, p); if (batchTargets.length == 1) { salt = 0; while ( timelock(chainId).isOperation( timelock(chainId).hashOperation( - batchTargets[0], - batchValues[0], - batchCalldatas[0], - bytes32(0), - bytes32(salt) + batchTargets[0], batchValues[0], batchCalldatas[0], bytes32(0), bytes32(salt) ) ) ) { @@ -349,11 +314,7 @@ contract SimulationSetup is Test, CommonUtils { while ( timelock(chainId).isOperation( timelock(chainId).hashOperationBatch( - batchTargets, - batchValues, - batchCalldatas, - bytes32(0), - bytes32(salt) + batchTargets, batchValues, batchCalldatas, bytes32(0), bytes32(salt) ) ) ) { @@ -389,7 +350,7 @@ contract SimulationSetup is Test, CommonUtils { } vm.recordLogs(); - governor().execute{ value: valueEther }(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value + governor().execute{value: valueEther}(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value { bytes memory payload; @@ -397,8 +358,8 @@ contract SimulationSetup is Test, CommonUtils { Vm.Log[] memory entries = vm.getRecordedLogs(); for (uint256 i; i < entries.length; i++) { if ( - entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") && - entries[i].topics[1] == bytes32(uint256(_getLZChainId(chainId))) + entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") + && entries[i].topics[1] == bytes32(uint256(_getLZChainId(chainId))) ) { payload = abi.decode(entries[i].data, (bytes)); break; @@ -409,10 +370,7 @@ contract SimulationSetup is Test, CommonUtils { vm.selectFork(forkIdentifier[chainId]); hoax(address(_lzEndPoint(chainId))); proposalReceiver(chainId).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(chainId)), - 0, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(chainId)), 0, payload ); } @@ -452,7 +410,7 @@ contract SimulationSetup is Test, CommonUtils { governor().state(proposalId); if (keccak256(error) != keccak256(nullBytes)) vm.expectRevert(error); - governor().execute{ value: valueEther }(targets, values, calldatas, keccak256(bytes(description))); + governor().execute{value: valueEther}(targets, values, calldatas, keccak256(bytes(description))); vm.warp(block.timestamp + timelock(chainId).getMinDelay() + 1); } diff --git a/test/unit/TimelockControllerWithCounter.t.sol b/test/unit/TimelockControllerWithCounter.t.sol index 9bdc1fc..f2e74f6 100644 --- a/test/unit/TimelockControllerWithCounter.t.sol +++ b/test/unit/TimelockControllerWithCounter.t.sol @@ -2,23 +2,23 @@ pragma solidity ^0.8.9; -import { IGovernor } from "oz/governance/IGovernor.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.sol"; -import { IAccessControl } from "oz/access/IAccessControl.sol"; -import { Strings } from "oz/utils/Strings.sol"; - -import { console } from "forge-std/console.sol"; -import { Test, stdError } from "forge-std/Test.sol"; -import { Vm } from "forge-std/Vm.sol"; - -import { AngleGovernor } from "contracts/AngleGovernor.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender, Ownable } from "contracts/ProposalSender.sol"; -import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; - -import { SubCall } from "./Proposal.sol"; -import { SimulationSetup } from "./SimulationSetup.t.sol"; -import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; +import {Strings} from "oz-v5/utils/Strings.sol"; + +import {console} from "forge-std/console.sol"; +import {Test, stdError} from "forge-std/Test.sol"; +import {Vm} from "forge-std/Vm.sol"; + +import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; +import {ProposalSender, Ownable} from "contracts/ProposalSender.sol"; +import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; + +import {SubCall} from "./Proposal.sol"; +import {SimulationSetup} from "./SimulationSetup.t.sol"; +import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Constants.t.sol"; @@ -62,11 +62,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { assertEq(timelock(srcChain).proposalIds(0), 0); governor().execute(targets, values, calldatas, keccak256(bytes(description))); bytes32 txId = timelock(srcChain).hashOperation( - address(governor()), - 0, - abi.encodeWithSelector(governor().updateQuorumNumerator.selector, 11), - bytes32(0), - 0 + address(governor()), 0, abi.encodeWithSelector(governor().updateQuorumNumerator.selector, 11), bytes32(0), 0 ); assertEq(timelock(srcChain).counterProposals(), 1); assertEq(timelock(srcChain).proposalIds(0), txId); @@ -97,7 +93,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { timelock(destChain).grantRole.selector, timelock(destChain).PROPOSER_ROLE(), address(newReceiverOptimism) - ) + ) }); p[1] = SubCall({ chainId: destChain, @@ -107,7 +103,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { timelock(destChain).revokeRole.selector, timelock(destChain).PROPOSER_ROLE(), address(proposalReceiver(destChain)) - ) + ) }); string memory description = "Updating relayer receiver on Optimism"; vm.selectFork(forkIdentifier[srcChain]); @@ -199,10 +195,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { abi.encodeWithSelector(_lzEndPoint(srcChain).send.selector), abi.encode("REVERT") ); - bytes - memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); - (uint256 nativeFee, ) = proposalSender().estimateFees(_getLZChainId(destChain), payload, adapterParams); + (uint256 nativeFee,) = proposalSender().estimateFees(_getLZChainId(destChain), payload, adapterParams); assertLe(nativeFee, 0.1 ether); _dummyProposal(srcChain, p, description, 0.1 ether, hex""); vm.clearMockedCalls(); @@ -220,10 +216,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(srcChain), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload + _getLZChainId(srcChain), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload ); vm.selectFork(forkIdentifier[srcChain]); @@ -234,10 +227,8 @@ contract TimelockControllerWithCounterTest is SimulationSetup { assertGe(timelock(destChain).getTimestamp(timelock(destChain).proposalIds(0)), block.timestamp); vm.warp(block.timestamp + timelock(destChain).getMinDelay() + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).counterProposals(), 1); @@ -265,12 +256,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), - abi.encodeWithSelector(_lzEndPoint(1).send.selector), - abi.encode("REVERT") + address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") ); - bytes - memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload1 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -280,14 +269,12 @@ contract TimelockControllerWithCounterTest is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, - timelock(1).PROPOSER_ROLE(), - address(alice) - ) + timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) + ) }); description = "Grant role on Optimism"; - bytes - memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload2 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -310,10 +297,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload1 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 ); vm.selectFork(forkIdentifier[1]); @@ -327,10 +311,8 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p1 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p1); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -344,10 +326,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload2 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 ); vm.selectFork(forkIdentifier[1]); @@ -360,10 +339,8 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p2 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p2); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -384,12 +361,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), - abi.encodeWithSelector(_lzEndPoint(1).send.selector), - abi.encode("REVERT") + address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") ); - bytes - memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload1 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -399,14 +374,12 @@ contract TimelockControllerWithCounterTest is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, - timelock(1).PROPOSER_ROLE(), - address(alice) - ) + timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) + ) }); description = "Grant role on Optimism"; - bytes - memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload2 = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -429,10 +402,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload2 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 ); vm.selectFork(forkIdentifier[1]); @@ -446,10 +416,8 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p2 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p2); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -463,10 +431,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload1 + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 ); vm.selectFork(forkIdentifier[1]); assertEq(timelock(1).counterProposals(), 0); @@ -478,10 +443,8 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p1 - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p1); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -503,21 +466,17 @@ contract TimelockControllerWithCounterTest is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, - timelock(1).PROPOSER_ROLE(), - address(alice) - ) + timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) + ) }); string memory description = "Batch delay and grantRole on Optimism"; vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), - abi.encodeWithSelector(_lzEndPoint(1).send.selector), - abi.encode("REVERT") + address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") ); - bytes - memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002c48f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes memory payload = + hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002c48f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p, description, 0.1 ether, hex""); vm.clearMockedCalls(); @@ -535,10 +494,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), - abi.encodePacked(proposalSender(), proposalReceiver(destChain)), - 0, - payload + _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload ); vm.selectFork(forkIdentifier[1]); @@ -549,10 +505,8 @@ contract TimelockControllerWithCounterTest is SimulationSetup { assertEq(timelock(destChain).proposalIds(0), _decodeLzReceivePayload(payload, destChain, true)); vm.warp(block.timestamp + timelock(destChain).getMinDelay() + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( - destChain, - p - ); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = + filterChainSubCalls(destChain, p); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).executeBatch(targets, values, calldatas, bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -565,9 +519,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { uint256 minDelay = timelock(srcChain).getMinDelay(); vm.expectRevert( abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, - alice, - timelock(srcChain).PROPOSER_ROLE() + IAccessControl.AccessControlUnauthorizedAccount.selector, alice, timelock(srcChain).PROPOSER_ROLE() ) ); vm.prank(alice); @@ -595,9 +547,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { uint256 minDelay = timelock(srcChain).getMinDelay(); vm.expectRevert( abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, - alice, - timelock(srcChain).PROPOSER_ROLE() + IAccessControl.AccessControlUnauthorizedAccount.selector, alice, timelock(srcChain).PROPOSER_ROLE() ) ); vm.prank(alice); @@ -622,9 +572,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { string memory description = "Updating delay on Optimism"; bytes memory error = abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, - alice, - timelock(1).EXECUTOR_ROLE() + IAccessControl.AccessControlUnauthorizedAccount.selector, alice, timelock(1).EXECUTOR_ROLE() ); _crossChainProposal(destChain, p, description, 0.1 ether, error, alice); } @@ -653,37 +601,30 @@ contract TimelockControllerWithCounterTest is SimulationSetup { HELPERS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - function _decodeLzReceivePayload( - bytes memory payload, - uint256 chainId, - bool isBatch - ) internal view returns (bytes32) { - (, , , bytes[] memory calldatas) = abi.decode(payload, (address[], uint[], string[], bytes[])); + function _decodeLzReceivePayload(bytes memory payload, uint256 chainId, bool isBatch) + internal + view + returns (bytes32) + { + (,,, bytes[] memory calldatas) = abi.decode(payload, (address[], uint256[], string[], bytes[])); bytes memory higherData = calldatas[0]; if (isBatch) return this._decodePayloadTimelockScheduleBatch(higherData, chainId); else return this._decodePayloadTimelockSchedule(higherData, chainId); } function _decodePayloadTimelockSchedule(bytes calldata payload, uint256 chainId) public view returns (bytes32 id) { - (address target, uint256 value, bytes memory data, bytes32 predecessor, bytes32 salt, ) = abi.decode( - payload[4:], - (address, uint256, bytes, bytes32, bytes32, uint256) - ); + (address target, uint256 value, bytes memory data, bytes32 predecessor, bytes32 salt,) = + abi.decode(payload[4:], (address, uint256, bytes, bytes32, bytes32, uint256)); return timelock(chainId).hashOperation(target, value, data, predecessor, salt); } - function _decodePayloadTimelockScheduleBatch( - bytes calldata payload, - uint256 chainId - ) public view returns (bytes32 id) { - ( - address[] memory targets, - uint256[] memory values, - bytes[] memory datas, - bytes32 predecessor, - bytes32 salt, - - ) = abi.decode(payload[4:], (address[], uint256[], bytes[], bytes32, bytes32, uint256)); + function _decodePayloadTimelockScheduleBatch(bytes calldata payload, uint256 chainId) + public + view + returns (bytes32 id) + { + (address[] memory targets, uint256[] memory values, bytes[] memory datas, bytes32 predecessor, bytes32 salt,) = + abi.decode(payload[4:], (address[], uint256[], bytes[], bytes32, bytes32, uint256)); return timelock(chainId).hashOperationBatch(targets, values, datas, predecessor, salt); } } From 9efae99b493a36279a7895a5401a18918142dd8e Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 13:36:57 +0100 Subject: [PATCH 02/26] uninstalled oz upgradeable --- .gitmodules | 4 ---- lib/openzeppelin-contracts-upgradeable | 1 - 2 files changed, 5 deletions(-) delete mode 160000 lib/openzeppelin-contracts-upgradeable diff --git a/.gitmodules b/.gitmodules index 1a52370..2e1382f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,10 +6,6 @@ path = lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts version = v4.7.3 -[submodule "lib/openzeppelin-contracts-upgradeable"] - path = lib/openzeppelin-contracts-upgradeable - url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable - version = v4.7.3 [submodule "lib/solidity-examples"] path = lib/solidity-examples url = https://github.com/LayerZero-Labs/solidity-examples diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable deleted file mode 160000 index e3007cf..0000000 --- a/lib/openzeppelin-contracts-upgradeable +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e3007cfed2b6819decdd6f8217290f7cb12ff796 From c686ae545cefae80723d7bee61b75fc3b92cb11f Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 13:37:29 +0100 Subject: [PATCH 03/26] forge install: openzeppelin-contracts-upgradeable v4.7.3 --- .gitmodules | 3 +++ lib/openzeppelin-contracts-upgradeable | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/openzeppelin-contracts-upgradeable diff --git a/.gitmodules b/.gitmodules index 2e1382f..08402f9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -37,3 +37,6 @@ [submodule "lib/utils"] path = lib/utils url = https://github.com/AngleProtocol/utils +[submodule "lib/openzeppelin-contracts-upgradeable"] + path = lib/openzeppelin-contracts-upgradeable + url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable new file mode 160000 index 0000000..0a2cb9a --- /dev/null +++ b/lib/openzeppelin-contracts-upgradeable @@ -0,0 +1 @@ +Subproject commit 0a2cb9a445c365870ed7a8ab461b12acf3e27d63 From df9d83852417de8c956a79ecf8a65ceb5eac41c1 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 13:37:47 +0100 Subject: [PATCH 04/26] chore: remove oz lib --- .gitmodules | 4 ---- lib/openzeppelin-contracts | 1 - 2 files changed, 5 deletions(-) delete mode 160000 lib/openzeppelin-contracts diff --git a/.gitmodules b/.gitmodules index 08402f9..ad726cb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,10 +2,6 @@ path = lib/forge-std url = https://github.com/foundry-rs/forge-std ignore = dirty -[submodule "lib/openzeppelin-contracts"] - path = lib/openzeppelin-contracts - url = https://github.com/OpenZeppelin/openzeppelin-contracts - version = v4.7.3 [submodule "lib/solidity-examples"] path = lib/solidity-examples url = https://github.com/LayerZero-Labs/solidity-examples diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts deleted file mode 160000 index cffb2f1..0000000 --- a/lib/openzeppelin-contracts +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cffb2f1ddcd87efd68effc92cfd336c5145acabd From 4ef918e953e077348271d87d5d3fde10a3629f56 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 13:39:15 +0100 Subject: [PATCH 05/26] forge install: openzeppelin-contracts v4.7.3 --- .gitmodules | 3 +++ lib/openzeppelin-contracts | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/openzeppelin-contracts diff --git a/.gitmodules b/.gitmodules index ad726cb..c83265b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -36,3 +36,6 @@ [submodule "lib/openzeppelin-contracts-upgradeable"] path = lib/openzeppelin-contracts-upgradeable url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable +[submodule "lib/openzeppelin-contracts"] + path = lib/openzeppelin-contracts + url = https://github.com/OpenZeppelin/openzeppelin-contracts diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts new file mode 160000 index 0000000..ecd2ca2 --- /dev/null +++ b/lib/openzeppelin-contracts @@ -0,0 +1 @@ +Subproject commit ecd2ca2cd7cac116f7a37d0e474bbb3d7d5e1c4d From ca978bbe731c98e901f8eb4a586f1e5c7e348496 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:42:32 +0100 Subject: [PATCH 06/26] specify version for submodules --- .gitmodules | 2 ++ contracts/ProposalReceiver.sol | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index c83265b..54cc2f2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -36,6 +36,8 @@ [submodule "lib/openzeppelin-contracts-upgradeable"] path = lib/openzeppelin-contracts-upgradeable url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable + version = v4.7.3 [submodule "lib/openzeppelin-contracts"] path = lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts + version = v4.7.3 \ No newline at end of file diff --git a/contracts/ProposalReceiver.sol b/contracts/ProposalReceiver.sol index 73897ba..fb1928e 100644 --- a/contracts/ProposalReceiver.sol +++ b/contracts/ProposalReceiver.sol @@ -3,7 +3,8 @@ pragma solidity ^0.8.20; import "oz-v5/utils/ReentrancyGuard.sol"; -import "lz/lzApp/NonblockingLzApp.sol"; +import "oz-v5/access/Ownable.sol"; +import {BytesLib, ExcessivelySafeCall, NonblockingLzApp} from "lz/lzApp/NonblockingLzApp.sol"; import "./utils/Errors.sol"; /// @title ProposalReceiver From c119c2496e593808c39a96ceb23535a7a8562ee6 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:42:55 +0100 Subject: [PATCH 07/26] forge install: old-oz cffb2f1ddcd87efd68effc92cfd336c5145acabd --- .gitmodules | 5 ++++- lib/old-oz | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) create mode 160000 lib/old-oz diff --git a/.gitmodules b/.gitmodules index 54cc2f2..0ab03bd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,4 +40,7 @@ [submodule "lib/openzeppelin-contracts"] path = lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts - version = v4.7.3 \ No newline at end of file + version = v4.7.3 +[submodule "lib/old-oz"] + path = lib/old-oz + url = https://github.com/OpenZeppelin/openzeppelin-contracts diff --git a/lib/old-oz b/lib/old-oz new file mode 160000 index 0000000..cffb2f1 --- /dev/null +++ b/lib/old-oz @@ -0,0 +1 @@ +Subproject commit cffb2f1ddcd87efd68effc92cfd336c5145acabd From 4749cce006e027cc538f3a33b06693844b0d8b77 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:43:13 +0100 Subject: [PATCH 08/26] install an older version of OZ --- .gitmodules | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitmodules b/.gitmodules index 0ab03bd..ea0ce28 100644 --- a/.gitmodules +++ b/.gitmodules @@ -44,3 +44,4 @@ [submodule "lib/old-oz"] path = lib/old-oz url = https://github.com/OpenZeppelin/openzeppelin-contracts + version = cffb2f1ddcd87efd68effc92cfd336c5145acabd From f98f810744a773532c1925d00971affd1b1d4420 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:44:16 +0100 Subject: [PATCH 09/26] forge install: old-oz-upgradeable ebf264cc4b812e6557ed7d539e947211acd5670c --- .gitmodules | 3 +++ lib/old-oz-upgradeable | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/old-oz-upgradeable diff --git a/.gitmodules b/.gitmodules index ea0ce28..d5b5adb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -45,3 +45,6 @@ path = lib/old-oz url = https://github.com/OpenZeppelin/openzeppelin-contracts version = cffb2f1ddcd87efd68effc92cfd336c5145acabd +[submodule "lib/old-oz-upgradeable"] + path = lib/old-oz-upgradeable + url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable diff --git a/lib/old-oz-upgradeable b/lib/old-oz-upgradeable new file mode 160000 index 0000000..ebf264c --- /dev/null +++ b/lib/old-oz-upgradeable @@ -0,0 +1 @@ +Subproject commit ebf264cc4b812e6557ed7d539e947211acd5670c From 8cf995dec35ab2a40d7578d39757c6bc5cf53bcd Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:44:35 +0100 Subject: [PATCH 10/26] install old oz upgradeable library --- .gitmodules | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitmodules b/.gitmodules index d5b5adb..99feb2d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -48,3 +48,4 @@ [submodule "lib/old-oz-upgradeable"] path = lib/old-oz-upgradeable url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable + version = ebf264cc4b812e6557ed7d539e947211acd5670c From 795dc77be93d71392397e266d6ce447f742b2130 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 6 Mar 2024 17:48:00 +0100 Subject: [PATCH 11/26] feat: update-transmuter-facets --- contracts/ProposalReceiver.sol | 3 +- foundry.toml | 2 +- helpers/createProposal.sh | 2 +- remappings.txt | 4 +- scripts/proposals/payload.json | 4 +- .../transmuter/TransmuterUpdateFacets.s.sol | 11 ++- .../transmuter/TransmuterUtils.s.sol | 2 +- scripts/proposals/transmuter/selectors.json | 78 +++++++++++++++++++ test/scripts/ScriptHelpers.t.sol | 70 ++++++++--------- .../TransmuterUpdateFacetsTest.t.sol | 62 +++++++++++++-- 10 files changed, 181 insertions(+), 57 deletions(-) create mode 100644 scripts/proposals/transmuter/selectors.json diff --git a/contracts/ProposalReceiver.sol b/contracts/ProposalReceiver.sol index fb1928e..73897ba 100644 --- a/contracts/ProposalReceiver.sol +++ b/contracts/ProposalReceiver.sol @@ -3,8 +3,7 @@ pragma solidity ^0.8.20; import "oz-v5/utils/ReentrancyGuard.sol"; -import "oz-v5/access/Ownable.sol"; -import {BytesLib, ExcessivelySafeCall, NonblockingLzApp} from "lz/lzApp/NonblockingLzApp.sol"; +import "lz/lzApp/NonblockingLzApp.sol"; import "./utils/Errors.sol"; /// @title ProposalReceiver diff --git a/foundry.toml b/foundry.toml index ab5cec6..0483fde 100644 --- a/foundry.toml +++ b/foundry.toml @@ -12,7 +12,7 @@ optimizer = true optimizer_runs = 1000 solc_version = "0.8.23" ffi = true -fs_permissions = [{ access = "read-write", path = "./scripts/proposals/payload.json"}, { access = "read-write", path = "./scripts/roles.json"}] +fs_permissions = [{ access = "read-write", path = "./scripts/proposals/payload.json"}, { access = "read-write", path = "./scripts/roles.json"}, { access = "read-write", path = "./scripts/proposals/transmuter/selectors.json"}] [fuzz] runs = 10000 diff --git a/helpers/createProposal.sh b/helpers/createProposal.sh index ec5fb1e..e5191fc 100644 --- a/helpers/createProposal.sh +++ b/helpers/createProposal.sh @@ -97,7 +97,7 @@ function main { echo "Running on chains $chainIds" export CHAIN_IDS=$chainIds - FOUNDRY_PROFILE=dev forge script $script + FOUNDRY_PROFILE=dev forge script $script -vvvv if [ $? -ne 0 ]; then echo "" diff --git a/remappings.txt b/remappings.txt index db19fb7..6798424 100644 --- a/remappings.txt +++ b/remappings.txt @@ -9,8 +9,8 @@ transmuter/=lib/angle-transmuter/contracts router/=lib/angle-router/contracts contracts/=contracts test/=test -@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts -@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts +@openzeppelin/contracts-upgradeable/=lib/old-oz-upgradeable/contracts +@openzeppelin/contracts/=lib/old-oz/contracts oz-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts oz/=lib/openzeppelin-contracts/contracts @chainlink/=lib/chainlink diff --git a/scripts/proposals/payload.json b/scripts/proposals/payload.json index 6c2f61c..4c24892 100644 --- a/scripts/proposals/payload.json +++ b/scripts/proposals/payload.json @@ -1,11 +1,11 @@ { "calldatas": { - "0": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001517f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000748ba9cd5a5ddba5aba70a4ac861b2413dca4436000000000000000000000000748ba9cd5a5ddba5aba70a4ac861b2413dca44360000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002406f3f9e6000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002443ec3e09000000000000000000000000000000000000000000000000000000000000004b00000000000000000000000000000000000000000000000000000000" + "0": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000008641f931c1c0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000068000000000000000000000000037eb0572eb61db3b819570cf65114ff6db6c06a2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000016b4a0bdf300000000000000000000000000000000000000000000000000000000ee565a6300000000000000000000000000000000000000000000000000000000847da7be00000000000000000000000000000000000000000000000000000000eb7aac5f000000000000000000000000000000000000000000000000000000003335221000000000000000000000000000000000000000000000000000000000b718136100000000000000000000000000000000000000000000000000000000b85780bc00000000000000000000000000000000000000000000000000000000cd377c5300000000000000000000000000000000000000000000000000000000782513bd0000000000000000000000000000000000000000000000000000000094e35d9e000000000000000000000000000000000000000000000000000000004ea3e3430000000000000000000000000000000000000000000000000000000010d3d22e0000000000000000000000000000000000000000000000000000000038c269eb00000000000000000000000000000000000000000000000000000000adc9d1f7000000000000000000000000000000000000000000000000000000008db9653f000000000000000000000000000000000000000000000000000000000d1266270000000000000000000000000000000000000000000000000000000096d6487900000000000000000000000000000000000000000000000000000000fe7d0c540000000000000000000000000000000000000000000000000000000077dc342900000000000000000000000000000000000000000000000000000000f9839d8900000000000000000000000000000000000000000000000000000000a52aefd40000000000000000000000000000000000000000000000000000000099eeca4900000000000000000000000000000000000000000000000000000000000000000000000000000000028e1f0db25daf4ce8c895215deafbce7a873b24000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004d703a0cd00000000000000000000000000000000000000000000000000000000815822c1000000000000000000000000000000000000000000000000000000002e7639bc00000000000000000000000000000000000000000000000000000000fd7daaf800000000000000000000000000000000000000000000000000000000000000000000000000000000c3ef7ed4f97450ae8da2473068375788bdeb5c5c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000af0d2d5a800000000000000000000000000000000000000000000000000000000c1cdee7e0000000000000000000000000000000000000000000000000000000087c8ab7a000000000000000000000000000000000000000000000000000000005c3eebda000000000000000000000000000000000000000000000000000000001f0ec8ee000000000000000000000000000000000000000000000000000000000e32cb860000000000000000000000000000000000000000000000000000000081ee2deb00000000000000000000000000000000000000000000000000000000b13b0847000000000000000000000000000000000000000000000000000000001b0c7182000000000000000000000000000000000000000000000000000000007c0343a100000000000000000000000000000000000000000000000000000000000000000000000000000000954ec713a3915b504a6f288563e5218f597e18950000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000064583aea6000000000000000000000000000000000000000000000000000000009525f3ab000000000000000000000000000000000000000000000000000000003b6a1fe000000000000000000000000000000000000000000000000000000000d92c6cb200000000000000000000000000000000000000000000000000000000b92567fa00000000000000000000000000000000000000000000000000000000c10a62870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001641f931c1c0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000044e3d3bba34e16a67c633daf86114284fc6288190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011cb44dfc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364b13b08470000000000000000000000001abaea1f7c830bd89acc67ec4af516284b1bc33c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf526340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c4b13b08470000000000000000000000002f123cf3f37ce3328cc9b5b8415f9ec5109b45e7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006e27a25999b3c665e44d903b2139f5a4be2b6c260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000003f480000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000067a41c1ea336d0000000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000065e888dc000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000" }, "chainIds": { "0": 1 }, - "description": "ipfs://QmRSdyuXeemVEn97RPRSiit6UEUonvwVr9we7bEe2w8v2E", + "description": "ipfs://", "targets": { "0": "0x09D81464c7293C774203E46E3C921559c8E9D53f" }, diff --git a/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol index 9d8402b..5244090 100644 --- a/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol +++ b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol @@ -10,11 +10,17 @@ import {OldTransmuter} from "../../interfaces/ITransmuter.sol"; import {IERC20} from "oz-v5/token/ERC20/IERC20.sol"; import "transmuter/transmuter/Storage.sol" as Storage; +import {DiamondCut} from "transmuter/transmuter/facets/DiamondCut.sol"; +import {DiamondEtherscan} from "transmuter/transmuter/facets/DiamondEtherscan.sol"; +import {DiamondLoupe} from "transmuter/transmuter/facets/DiamondLoupe.sol"; +import {DiamondProxy} from "transmuter/transmuter/DiamondProxy.sol"; import {Getters} from "transmuter/transmuter/facets/Getters.sol"; import {Oracle} from "transmuter/transmuter/facets/Oracle.sol"; -// import {Redeemer} from "transmuter/transmuter/facets/Redeemer.sol"; +import {Redeemer} from "transmuter/transmuter/facets/Redeemer.sol"; +import {RewardHandler} from "transmuter/transmuter/facets/RewardHandler.sol"; import {SettersGovernor} from "transmuter/transmuter/facets/SettersGovernor.sol"; -// import {Swapper} from "transmuter/transmuter/facets/Swapper.sol"; +import {SettersGuardian} from "transmuter/transmuter/facets/SettersGuardian.sol"; +import {Swapper} from "transmuter/transmuter/facets/Swapper.sol"; import {ITransmuter, IDiamondCut, ISettersGovernor} from "transmuter/interfaces/ITransmuter.sol"; contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { @@ -178,6 +184,7 @@ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { oracleTypeBC3M, Storage.OracleReadType.MAX, oracleDataBC3M, + // We can hope that the oracleDataBC3M won't move much before the proposal is executed abi.encode(currentBC3MPrice, DEVIATION_THRESHOLD_BC3M, uint96(block.timestamp), HEARTBEAT), abi.encode(FIREWALL_MINT_BC3M, FIREWALL_BURN_BC3M) ) diff --git a/scripts/proposals/transmuter/TransmuterUtils.s.sol b/scripts/proposals/transmuter/TransmuterUtils.s.sol index 59b1251..dc9dbaf 100644 --- a/scripts/proposals/transmuter/TransmuterUtils.s.sol +++ b/scripts/proposals/transmuter/TransmuterUtils.s.sol @@ -11,7 +11,7 @@ import {ContractType, BASE_18} from "utils/src/Constants.sol"; contract TransmuterUtils is Script, CommonUtils { using strings for *; - string constant JSON_SELECTOR_PATH = "./selectors.json"; + string constant JSON_SELECTOR_PATH = "./scripts/proposals/transmuter/selectors.json"; uint256 constant BPS = 1e14; address constant EUROC = 0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c; diff --git a/scripts/proposals/transmuter/selectors.json b/scripts/proposals/transmuter/selectors.json new file mode 100644 index 0000000..0db1b01 --- /dev/null +++ b/scripts/proposals/transmuter/selectors.json @@ -0,0 +1,78 @@ +{ + "DiamondCut": [ + "0x1f931c1c00000000000000000000000000000000000000000000000000000000" + ], + "DiamondEtherscan": [ + "0x5c60da1b00000000000000000000000000000000000000000000000000000000", + "0xc39aa07d00000000000000000000000000000000000000000000000000000000" + ], + "DiamondLoupe": [ + "0xcdffacc600000000000000000000000000000000000000000000000000000000", + "0x52ef6b2c00000000000000000000000000000000000000000000000000000000", + "0xadfca15e00000000000000000000000000000000000000000000000000000000", + "0x7a0ed62700000000000000000000000000000000000000000000000000000000" + ], + "Getters": [ + "0xb4a0bdf300000000000000000000000000000000000000000000000000000000", + "0xee565a6300000000000000000000000000000000000000000000000000000000", + "0x847da7be00000000000000000000000000000000000000000000000000000000", + "0xeb7aac5f00000000000000000000000000000000000000000000000000000000", + "0x3335221000000000000000000000000000000000000000000000000000000000", + "0xb718136100000000000000000000000000000000000000000000000000000000", + "0xb85780bc00000000000000000000000000000000000000000000000000000000", + "0xcd377c5300000000000000000000000000000000000000000000000000000000", + "0x782513bd00000000000000000000000000000000000000000000000000000000", + "0x94e35d9e00000000000000000000000000000000000000000000000000000000", + "0x4ea3e34300000000000000000000000000000000000000000000000000000000", + "0x10d3d22e00000000000000000000000000000000000000000000000000000000", + "0x38c269eb00000000000000000000000000000000000000000000000000000000", + "0xadc9d1f700000000000000000000000000000000000000000000000000000000", + "0x8db9653f00000000000000000000000000000000000000000000000000000000", + "0x0d12662700000000000000000000000000000000000000000000000000000000", + "0x96d6487900000000000000000000000000000000000000000000000000000000", + "0xfe7d0c5400000000000000000000000000000000000000000000000000000000", + "0x77dc342900000000000000000000000000000000000000000000000000000000", + "0xf9839d8900000000000000000000000000000000000000000000000000000000", + "0xa52aefd400000000000000000000000000000000000000000000000000000000", + "0x99eeca4900000000000000000000000000000000000000000000000000000000" + ], + "Oracle": [ + "0x1cb44dfc00000000000000000000000000000000000000000000000000000000" + ], + "Redeemer": [ + "0xd703a0cd00000000000000000000000000000000000000000000000000000000", + "0x815822c100000000000000000000000000000000000000000000000000000000", + "0x2e7639bc00000000000000000000000000000000000000000000000000000000", + "0xfd7daaf800000000000000000000000000000000000000000000000000000000" + ], + "RewardHandler": [ + "0x05b4193400000000000000000000000000000000000000000000000000000000" + ], + "SettersGovernor": [ + "0xf0d2d5a800000000000000000000000000000000000000000000000000000000", + "0xc1cdee7e00000000000000000000000000000000000000000000000000000000", + "0x87c8ab7a00000000000000000000000000000000000000000000000000000000", + "0x5c3eebda00000000000000000000000000000000000000000000000000000000", + "0x1f0ec8ee00000000000000000000000000000000000000000000000000000000", + "0x0e32cb8600000000000000000000000000000000000000000000000000000000", + "0x81ee2deb00000000000000000000000000000000000000000000000000000000", + "0xb13b084700000000000000000000000000000000000000000000000000000000", + "0x1b0c718200000000000000000000000000000000000000000000000000000000", + "0x7c0343a100000000000000000000000000000000000000000000000000000000" + ], + "SettersGuardian": [ + "0x629feb6200000000000000000000000000000000000000000000000000000000", + "0x4eec47b900000000000000000000000000000000000000000000000000000000", + "0xa9e6a1a400000000000000000000000000000000000000000000000000000000", + "0xb607d09900000000000000000000000000000000000000000000000000000000" + ], + "Swapper": [ + "0x4583aea600000000000000000000000000000000000000000000000000000000", + "0x9525f3ab00000000000000000000000000000000000000000000000000000000", + "0x3b6a1fe000000000000000000000000000000000000000000000000000000000", + "0xd92c6cb200000000000000000000000000000000000000000000000000000000", + "0xb92567fa00000000000000000000000000000000000000000000000000000000", + "0xc10a628700000000000000000000000000000000000000000000000000000000" + ], + "useless": "" +} \ No newline at end of file diff --git a/test/scripts/ScriptHelpers.t.sol b/test/scripts/ScriptHelpers.t.sol index bf09152..5e318e5 100644 --- a/test/scripts/ScriptHelpers.t.sol +++ b/test/scripts/ScriptHelpers.t.sol @@ -2,11 +2,11 @@ pragma solidity ^0.8.9; -import { console } from "forge-std/console.sol"; -import { Vm } from "forge-std/Vm.sol"; -import { stdStorage, StdStorage, Test, stdError } from "forge-std/Test.sol"; +import {console} from "forge-std/console.sol"; +import {Vm} from "forge-std/Vm.sol"; +import {stdStorage, StdStorage, Test, stdError} from "forge-std/Test.sol"; -import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import {AngleGovernor} from "contracts/AngleGovernor.sol"; import "../../scripts/Constants.s.sol"; import "../../scripts/Utils.s.sol"; @@ -21,9 +21,8 @@ contract ScriptHelpers is Test, Utils { // TODO remove when on chain tx are passed to connect chains vm.selectFork(forkIdentifier[CHAIN_SOURCE]); - ProposalSender proposalSender = ProposalSender( - payable(_chainToContract(CHAIN_SOURCE, ContractType.ProposalSender)) - ); + ProposalSender proposalSender = + ProposalSender(payable(_chainToContract(CHAIN_SOURCE, ContractType.ProposalSender))); uint256[] memory ALL_CHAINS = new uint256[](10); ALL_CHAINS[0] = CHAIN_LINEA; ALL_CHAINS[1] = CHAIN_POLYGON; @@ -40,14 +39,21 @@ contract ScriptHelpers is Test, Utils { for (uint256 i; i < ALL_CHAINS.length; i++) { uint256 chainId = ALL_CHAINS[i]; proposalSender.setTrustedRemoteAddress( - _getLZChainId(chainId), - abi.encodePacked(_chainToContract(chainId, ContractType.ProposalReceiver)) + _getLZChainId(chainId), abi.encodePacked(_chainToContract(chainId, ContractType.ProposalReceiver)) ); } vm.stopPrank(); } + function _executeProposalWithFork() public returns (uint256[] memory) { + return _executeProposalInternal(true); + } + function _executeProposal() public returns (uint256[] memory) { + return _executeProposalInternal(false); + } + + function _executeProposalInternal(bool isFork) public returns (uint256[] memory) { ( bytes[] memory calldatas, string memory description, @@ -56,7 +62,7 @@ contract ScriptHelpers is Test, Utils { uint256[] memory chainIds ) = _deserializeJson(); - vm.selectFork(forkIdentifier[CHAIN_SOURCE]); + vm.selectFork(forkIdentifier[isFork ? CHAIN_FORK : CHAIN_SOURCE]); { AngleGovernor governor = AngleGovernor(payable(_chainToContract(CHAIN_SOURCE, ContractType.Governor))); @@ -73,34 +79,31 @@ contract ScriptHelpers is Test, Utils { vm.recordLogs(); hoax(whale); - governor.execute{ value: valueEther }(targets, values, calldatas, keccak256(bytes(description))); + governor.execute{value: valueEther}(targets, values, calldatas, keccak256(bytes(description))); } Vm.Log[] memory entries = vm.getRecordedLogs(); for (uint256 chainCount; chainCount < chainIds.length; chainCount++) { uint256 chainId = chainIds[chainCount]; - TimelockControllerWithCounter timelock = TimelockControllerWithCounter( - payable(_chainToContract(chainId, ContractType.Timelock)) - ); + TimelockControllerWithCounter timelock = + TimelockControllerWithCounter(payable(_chainToContract(chainId, ContractType.Timelock))); if (chainId == CHAIN_SOURCE) { vm.warp(block.timestamp + timelock.getMinDelay() + 1); _executeTimelock(chainId, timelock, targets[chainCount], calldatas[chainCount]); } else { { - ProposalSender proposalSender = ProposalSender( - payable(_chainToContract(CHAIN_SOURCE, ContractType.ProposalSender)) - ); - ProposalReceiver proposalReceiver = ProposalReceiver( - payable(_chainToContract(chainId, ContractType.ProposalReceiver)) - ); + ProposalSender proposalSender = + ProposalSender(payable(_chainToContract(CHAIN_SOURCE, ContractType.ProposalSender))); + ProposalReceiver proposalReceiver = + ProposalReceiver(payable(_chainToContract(chainId, ContractType.ProposalReceiver))); bytes memory payload; { for (uint256 i; i < entries.length; i++) { if ( - entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") && - entries[i].topics[1] == bytes32(uint256(_getLZChainId(chainId))) + entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") + && entries[i].topics[1] == bytes32(uint256(_getLZChainId(chainId))) ) { payload = abi.decode(entries[i].data, (bytes)); break; @@ -111,10 +114,7 @@ contract ScriptHelpers is Test, Utils { vm.selectFork(forkIdentifier[chainId]); hoax(address(_lzEndPoint(chainId))); proposalReceiver.lzReceive( - _getLZChainId(CHAIN_SOURCE), - abi.encodePacked(proposalSender, proposalReceiver), - 0, - payload + _getLZChainId(CHAIN_SOURCE), abi.encodePacked(proposalSender, proposalReceiver), 0, payload ); } @@ -123,16 +123,13 @@ contract ScriptHelpers is Test, Utils { bytes[] memory chainCalldatas; { console.logBytes(calldatas[chainCount]); - (, bytes memory senderData, ) = abi.decode( + (, bytes memory senderData,) = abi.decode( // calldatas[chainCount], _slice(calldatas[chainCount], 4, calldatas[chainCount].length - 4), (uint16, bytes, bytes) ); console.logBytes(senderData); - (chainTargets, , , chainCalldatas) = abi.decode( - senderData, - (address[], uint256[], string[], bytes[]) - ); + (chainTargets,,, chainCalldatas) = abi.decode(senderData, (address[], uint256[], string[], bytes[])); } for (uint256 i; i < chainTargets.length; i++) { @@ -153,9 +150,8 @@ contract ScriptHelpers is Test, Utils { if (target == address(timelock)) { vm.prank(_chainToContract(chainId, ContractType.GuardianMultisig)); if (TimelockControllerWithCounter.schedule.selector == bytes4(_slice(rawData, 0, 4))) { - (address target, uint256 value, bytes memory data, bytes32 predecessor, bytes32 salt, ) = abi.decode( - _slice(rawData, 4, rawData.length - 4), - (address, uint256, bytes, bytes32, bytes32, uint256) + (address target, uint256 value, bytes memory data, bytes32 predecessor, bytes32 salt,) = abi.decode( + _slice(rawData, 4, rawData.length - 4), (address, uint256, bytes, bytes32, bytes32, uint256) ); timelock.execute(target, value, data, predecessor, salt); } else { @@ -165,11 +161,9 @@ contract ScriptHelpers is Test, Utils { bytes[] memory tmpCalldatas, bytes32 predecessor, bytes32 salt, - ) = abi.decode( - _slice(rawData, 4, rawData.length - 4), - (address[], uint256[], bytes[], bytes32, bytes32, uint256) - ); + _slice(rawData, 4, rawData.length - 4), (address[], uint256[], bytes[], bytes32, bytes32, uint256) + ); timelock.executeBatch(tmpTargets, tmpValues, tmpCalldatas, predecessor, salt); } } diff --git a/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol index ea76872..ad0cfd9 100644 --- a/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol +++ b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol @@ -8,29 +8,46 @@ import {TransmuterUtils} from "../../../scripts/proposals/transmuter/TransmuterU import "../../../scripts/Constants.s.sol"; import {OldTransmuter} from "../../../scripts/interfaces/ITransmuter.sol"; import "transmuter/transmuter/Storage.sol" as Storage; +import {AggregatorV3Interface} from "transmuter/interfaces/external/chainlink/AggregatorV3Interface.sol"; contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { using stdJson for string; ITransmuter transmuter; - bytes public oracleConfigEUROC; - bytes public oracleConfigBC3M; + uint256[] chainIds; + + // TODO COMPLETE + bytes public oracleConfigEUROC = + hex"0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf52634000"; function setUp() public override { super.setUp(); + + // As there are calls to price feeds and there are delays to be respected we need to mock calls + // to escape from `InvalidChainlinkRate()` error + vm.mockCall( + address(0x6E27A25999B3C665E44D903B2139F5a4Be2B6C26), + abi.encodeWithSelector(AggregatorV3Interface.latestRoundData.selector), + abi.encode(uint80(0), int256(11949000000), uint256(1710170200), uint256(1710170200), uint80(0)) + ); + + chainIds = _executeProposalWithFork(); } - function testScript() external { - uint256[] memory chainIds = _executeProposal(); + function test_script() external { + // special case as we rely on the fork state + vm.selectFork(forkIdentifier[CHAIN_FORK]); // Now test that everything is as expected for (uint256 i; i < chainIds.length; i++) { uint256 chainId = chainIds[i]; transmuter = ITransmuter(payable(_chainToContract(chainId, ContractType.TransmuterAgEUR))); - vm.selectFork(forkIdentifier[chainId]); + _testAccessControlManager(); _testAgToken(); _testGetCollateralList(); + _testGetCollateralInfo(); + _testGetOracleValues(); } } @@ -49,7 +66,7 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { assertEq(collateralList[1], address(BC3M)); } - function testUnit_Upgrade_GetCollateralInfo() external { + function _testGetCollateralInfo() internal { { Storage.Collateral memory collatInfoEUROC = transmuter.getCollateralInfo(address(EUROC)); assertEq(collatInfoEUROC.isManaged, 0); @@ -101,7 +118,36 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { assertEq(collatInfoBC3M.decimals, 18); assertEq(collatInfoBC3M.onlyWhitelisted, 1); assertApproxEqRel(collatInfoBC3M.normalizedStables, 6236650 * BASE_18, 100 * BPS); - assertEq(collatInfoBC3M.oracleConfig, oracleConfigBC3M); + { + ( + Storage.OracleReadType oracleType, + Storage.OracleReadType targetType, + bytes memory oracleData, + bytes memory targetData, + bytes memory hyperparams + ) = abi.decode( + collatInfoBC3M.oracleConfig, (Storage.OracleReadType, Storage.OracleReadType, bytes, bytes, bytes) + ); + + assertEq(uint8(oracleType), uint8(0)); + assertEq(uint8(targetType), uint8(9)); + assertEq( + oracleData, + hex"00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006e27a25999b3c665e44d903b2139f5a4be2b6c260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000003f4800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000008" + ); + assertEq( + hyperparams, + hex"0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000002386f26fc10000" + ); + + (uint256 maxValue, uint96 deviationThreshold, uint96 lastUpdateTimestamp, uint32 heartbeat) = + abi.decode(targetData, (uint256, uint96, uint96, uint32)); + + assertApproxEqRel(maxValue, 1195 * BASE_18 / 10, 10 * BPS); + assertEq(deviationThreshold, DEVIATION_THRESHOLD_BC3M); + assertEq(heartbeat, HEARTBEAT); + } + { (Storage.WhitelistType whitelist, bytes memory data) = abi.decode(collatInfoBC3M.whitelistData, (Storage.WhitelistType, bytes)); @@ -141,7 +187,7 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { ORACLE //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - function testUnit_Upgrade_getOracleValues_Success() external { + function _testGetOracleValues() internal { _checkOracleValues(address(EUROC), BASE_18, FIREWALL_MINT_EUROC, FIREWALL_BURN_EUROC); _checkOracleValues(address(BC3M), (11944 * BASE_18) / 100, FIREWALL_MINT_BC3M, FIREWALL_BURN_BC3M); } From 5550f533c4608aeb34fd60c254a44c16b6d470a6 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Thu, 14 Mar 2024 09:19:48 +0100 Subject: [PATCH 12/26] fix: no Oracle facet movred to Setters --- foundry.toml | 2 +- scripts/proposals/transmuter/README.md | 16 +++- .../transmuter/TransmuterUpdateFacets.s.sol | 60 +++++---------- .../transmuter/TransmuterUtils.s.sol | 16 ++++ .../proposals/transmuter/selectors_add.json | 6 ++ .../transmuter/selectors_replace.json | 75 +++++++++++++++++++ 6 files changed, 131 insertions(+), 44 deletions(-) create mode 100644 scripts/proposals/transmuter/selectors_add.json create mode 100644 scripts/proposals/transmuter/selectors_replace.json diff --git a/foundry.toml b/foundry.toml index 0483fde..7039488 100644 --- a/foundry.toml +++ b/foundry.toml @@ -12,7 +12,7 @@ optimizer = true optimizer_runs = 1000 solc_version = "0.8.23" ffi = true -fs_permissions = [{ access = "read-write", path = "./scripts/proposals/payload.json"}, { access = "read-write", path = "./scripts/roles.json"}, { access = "read-write", path = "./scripts/proposals/transmuter/selectors.json"}] +fs_permissions = [{ access = "read-write", path = "./scripts/proposals/payload.json"}, { access = "read-write", path = "./scripts/roles.json"}, { access = "read-write", path = "./scripts/proposals/transmuter/selectors.json"}, { access = "read-write", path = "./scripts/proposals/transmuter/selectors_replace.json"}, { access = "read-write", path = "./scripts/proposals/transmuter/selectors_add.json"}] [fuzz] runs = 10000 diff --git a/scripts/proposals/transmuter/README.md b/scripts/proposals/transmuter/README.md index 3704bf2..c603807 100644 --- a/scripts/proposals/transmuter/README.md +++ b/scripts/proposals/transmuter/README.md @@ -1,8 +1,18 @@ # Guide to test facets update -## Angle-Tranmuter repo +## Angle-Transmuter repo -To test that new facets are non breaking changes run: +First you need to have `selectors_replace.json` and `selectors_add.json` in the script folder. As there is no direct way +to differentiate between the previous selectors and the one added, you first need to run: +```bash +yarn generate +``` + +This will populate the `scripts/selector.json` file, you then need to copy paste all selectors that needs to be replace in `scripts/selectors_replace.json`, +which are all except the `updateOracle(address)` one which should be `0x1cb44dfc00000000000000000000000000000000000000000000000000000000`. This one should be +put `scripts/selector_add.json`. + +You are all set to test that new facets are non breaking changes: ```bash yarn test --match-contract UpdateTransmuterFacets ``` @@ -35,6 +45,8 @@ Get the addresses for the deployed contracts, you will get a log of this format: ## Angle-Governance repo +First you need to copy paste the previous files `selectors_replace.json` and `selectors_add.json` into `./scripts/proposals/transmuter/selectors_replace.json` and `./scripts/proposals/transmuter/selectors_add.json` + Update the address previously logged into `./TransmuterUtils.s.sol` and run: ```bash diff --git a/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol index 5244090..64c5168 100644 --- a/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol +++ b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol @@ -15,7 +15,6 @@ import {DiamondEtherscan} from "transmuter/transmuter/facets/DiamondEtherscan.so import {DiamondLoupe} from "transmuter/transmuter/facets/DiamondLoupe.sol"; import {DiamondProxy} from "transmuter/transmuter/DiamondProxy.sol"; import {Getters} from "transmuter/transmuter/facets/Getters.sol"; -import {Oracle} from "transmuter/transmuter/facets/Oracle.sol"; import {Redeemer} from "transmuter/transmuter/facets/Redeemer.sol"; import {RewardHandler} from "transmuter/transmuter/facets/RewardHandler.sol"; import {SettersGovernor} from "transmuter/transmuter/facets/SettersGovernor.sol"; @@ -26,10 +25,10 @@ import {ITransmuter, IDiamondCut, ISettersGovernor} from "transmuter/interfaces/ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { using stdJson for string; - string[] facetNames; string[] replaceFacetNames; string[] addFacetNames; - address[] facetAddressList; + address[] replaceFacetAddressList; + address[] addFacetAddressList; ITransmuter transmuter; IERC20 agEUR; @@ -37,28 +36,6 @@ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { SubCall[] private subCalls; - function _generateFacets() private { - // First generate the selectors - facetNames.push("DiamondCut"); - facetNames.push("DiamondLoupe"); - facetNames.push("Getters"); - facetNames.push("Oracle"); - facetNames.push("Redeemer"); - facetNames.push("RewardHandler"); - facetNames.push("SettersGovernor"); - facetNames.push("SettersGuardian"); - facetNames.push("Swapper"); - facetNames.push("DiamondEtherscan"); - - string memory json = ""; - for (uint256 i = 0; i < facetNames.length; ++i) { - bytes4[] memory selectors = _generateSelectors(facetNames[i]); - vm.serializeBytes32(json, facetNames[i], _arrayBytes4ToBytes32(selectors)); - } - string memory finalJson = vm.serializeString(json, "useless", ""); - vm.writeJson(finalJson, JSON_SELECTOR_PATH); - } - function _updateFacets(uint256 chainId) private { uint256 executionChainId = chainId; chainId = chainId != 0 ? chainId : CHAIN_SOURCE; @@ -71,32 +48,33 @@ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { Storage.FacetCut[] memory addCut; replaceFacetNames.push("Getters"); - facetAddressList.push(GETTERS); + replaceFacetAddressList.push(GETTERS); replaceFacetNames.push("Redeemer"); - facetAddressList.push(REDEEMER); + replaceFacetAddressList.push(REDEEMER); replaceFacetNames.push("SettersGovernor"); - facetAddressList.push(SETTERS_GOVERNOR); + replaceFacetAddressList.push(SETTERS_GOVERNOR); replaceFacetNames.push("Swapper"); - facetAddressList.push(SWAPPER); + replaceFacetAddressList.push(SWAPPER); - addFacetNames.push("Oracle"); - facetAddressList.push(ORACLE); + addFacetNames.push("SettersGovernor"); + addFacetAddressList.push(SETTERS_GOVERNOR); - string memory json = vm.readFile(JSON_SELECTOR_PATH); { + string memory jsonReplace = vm.readFile(JSON_SELECTOR_PATH_REPLACE); // Build appropriate payload uint256 n = replaceFacetNames.length; replaceCut = new Storage.FacetCut[](n); for (uint256 i = 0; i < n; ++i) { // Get Selectors from json - bytes4[] memory selectors = - _arrayBytes32ToBytes4(json.readBytes32Array(string.concat("$.", replaceFacetNames[i]))); + bytes4[] memory selectors = _arrayBytes32ToBytes4( + jsonReplace.readBytes32Array(string.concat("$.", replaceFacetNames[i])) + ); replaceCut[i] = Storage.FacetCut({ - facetAddress: facetAddressList[i], + facetAddress: replaceFacetAddressList[i], action: Storage.FacetCutAction.Replace, functionSelectors: selectors }); @@ -104,19 +82,20 @@ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { } { + string memory jsonAdd = vm.readFile(JSON_SELECTOR_PATH_ADD); // Build appropriate payload - uint256 r = replaceFacetNames.length; uint256 n = addFacetNames.length; addCut = new Storage.FacetCut[](n); for (uint256 i = 0; i < n; ++i) { // Get Selectors from json - bytes4[] memory selectors = - _arrayBytes32ToBytes4(json.readBytes32Array(string.concat("$.", addFacetNames[i]))); + bytes4[] memory selectors = _arrayBytes32ToBytes4( + jsonAdd.readBytes32Array(string.concat("$.", addFacetNames[i])) + ); addCut[i] = Storage.FacetCut({ - facetAddress: facetAddressList[r + i], + facetAddress: addFacetAddressList[i], action: Storage.FacetCutAction.Add, functionSelectors: selectors - }); + }); } } @@ -197,7 +176,6 @@ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { uint256[] memory chainIds = vm.envUint("CHAIN_IDS", ","); string memory description = "ipfs://"; - _generateFacets(); for (uint256 i = 0; i < chainIds.length; i++) { _updateFacets(chainIds[i]); } diff --git a/scripts/proposals/transmuter/TransmuterUtils.s.sol b/scripts/proposals/transmuter/TransmuterUtils.s.sol index dc9dbaf..94c7fa3 100644 --- a/scripts/proposals/transmuter/TransmuterUtils.s.sol +++ b/scripts/proposals/transmuter/TransmuterUtils.s.sol @@ -12,6 +12,8 @@ contract TransmuterUtils is Script, CommonUtils { using strings for *; string constant JSON_SELECTOR_PATH = "./scripts/proposals/transmuter/selectors.json"; + string constant JSON_SELECTOR_PATH_REPLACE = "./scripts/proposals/transmuter/selectors_replace.json"; + string constant JSON_SELECTOR_PATH_ADD = "./scripts/proposals/transmuter/selectors_add.json"; uint256 constant BPS = 1e14; address constant EUROC = 0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c; @@ -50,6 +52,20 @@ contract TransmuterUtils is Script, CommonUtils { } } + function _arrayBytes32ToBytes4Exclude(bytes4[] memory _in, bytes4 toExclude) internal pure returns (bytes32[] memory out) { + out = new bytes32[](_in.length); + uint256 length = 0; + for (uint256 i = 0; i < _in.length; ++i) { + if(_in[i] != toExclude){ + out[length] = _bytes4ToBytes32(_in[i]); + length++; + } + } + assembly { + mstore(out, length) + } + } + function _arrayBytes32ToBytes4(bytes32[] memory _in) internal pure returns (bytes4[] memory out) { out = new bytes4[](_in.length); for (uint256 i = 0; i < _in.length; ++i) { diff --git a/scripts/proposals/transmuter/selectors_add.json b/scripts/proposals/transmuter/selectors_add.json new file mode 100644 index 0000000..ffec3de --- /dev/null +++ b/scripts/proposals/transmuter/selectors_add.json @@ -0,0 +1,6 @@ +{ + "SettersGovernor": [ + "0x1cb44dfc00000000000000000000000000000000000000000000000000000000" + ], + "useless": "" +} \ No newline at end of file diff --git a/scripts/proposals/transmuter/selectors_replace.json b/scripts/proposals/transmuter/selectors_replace.json new file mode 100644 index 0000000..f45a2e9 --- /dev/null +++ b/scripts/proposals/transmuter/selectors_replace.json @@ -0,0 +1,75 @@ +{ + "DiamondCut": [ + "0x1f931c1c00000000000000000000000000000000000000000000000000000000" + ], + "DiamondEtherscan": [ + "0x5c60da1b00000000000000000000000000000000000000000000000000000000", + "0xc39aa07d00000000000000000000000000000000000000000000000000000000" + ], + "DiamondLoupe": [ + "0xcdffacc600000000000000000000000000000000000000000000000000000000", + "0x52ef6b2c00000000000000000000000000000000000000000000000000000000", + "0xadfca15e00000000000000000000000000000000000000000000000000000000", + "0x7a0ed62700000000000000000000000000000000000000000000000000000000" + ], + "Getters": [ + "0xb4a0bdf300000000000000000000000000000000000000000000000000000000", + "0xee565a6300000000000000000000000000000000000000000000000000000000", + "0x847da7be00000000000000000000000000000000000000000000000000000000", + "0xeb7aac5f00000000000000000000000000000000000000000000000000000000", + "0x3335221000000000000000000000000000000000000000000000000000000000", + "0xb718136100000000000000000000000000000000000000000000000000000000", + "0xb85780bc00000000000000000000000000000000000000000000000000000000", + "0xcd377c5300000000000000000000000000000000000000000000000000000000", + "0x782513bd00000000000000000000000000000000000000000000000000000000", + "0x94e35d9e00000000000000000000000000000000000000000000000000000000", + "0x4ea3e34300000000000000000000000000000000000000000000000000000000", + "0x10d3d22e00000000000000000000000000000000000000000000000000000000", + "0x38c269eb00000000000000000000000000000000000000000000000000000000", + "0xadc9d1f700000000000000000000000000000000000000000000000000000000", + "0x8db9653f00000000000000000000000000000000000000000000000000000000", + "0x0d12662700000000000000000000000000000000000000000000000000000000", + "0x96d6487900000000000000000000000000000000000000000000000000000000", + "0xfe7d0c5400000000000000000000000000000000000000000000000000000000", + "0x77dc342900000000000000000000000000000000000000000000000000000000", + "0xf9839d8900000000000000000000000000000000000000000000000000000000", + "0xa52aefd400000000000000000000000000000000000000000000000000000000", + "0x99eeca4900000000000000000000000000000000000000000000000000000000" + ], + "Redeemer": [ + "0xd703a0cd00000000000000000000000000000000000000000000000000000000", + "0x815822c100000000000000000000000000000000000000000000000000000000", + "0x2e7639bc00000000000000000000000000000000000000000000000000000000", + "0xfd7daaf800000000000000000000000000000000000000000000000000000000" + ], + "RewardHandler": [ + "0x05b4193400000000000000000000000000000000000000000000000000000000" + ], + "SettersGovernor": [ + "0xf0d2d5a800000000000000000000000000000000000000000000000000000000", + "0xc1cdee7e00000000000000000000000000000000000000000000000000000000", + "0x87c8ab7a00000000000000000000000000000000000000000000000000000000", + "0x5c3eebda00000000000000000000000000000000000000000000000000000000", + "0x1f0ec8ee00000000000000000000000000000000000000000000000000000000", + "0x0e32cb8600000000000000000000000000000000000000000000000000000000", + "0x81ee2deb00000000000000000000000000000000000000000000000000000000", + "0xb13b084700000000000000000000000000000000000000000000000000000000", + "0x1b0c718200000000000000000000000000000000000000000000000000000000", + "0x7c0343a100000000000000000000000000000000000000000000000000000000" + ], + "SettersGuardian": [ + "0x629feb6200000000000000000000000000000000000000000000000000000000", + "0x4eec47b900000000000000000000000000000000000000000000000000000000", + "0xa9e6a1a400000000000000000000000000000000000000000000000000000000", + "0xb607d09900000000000000000000000000000000000000000000000000000000" + ], + "Swapper": [ + "0x4583aea600000000000000000000000000000000000000000000000000000000", + "0x9525f3ab00000000000000000000000000000000000000000000000000000000", + "0x3b6a1fe000000000000000000000000000000000000000000000000000000000", + "0xd92c6cb200000000000000000000000000000000000000000000000000000000", + "0xb92567fa00000000000000000000000000000000000000000000000000000000", + "0xc10a628700000000000000000000000000000000000000000000000000000000" + ], + "useless": "" +} \ No newline at end of file From c4334deef00d990eb921ab1c1da7a2aef6cfc934 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Thu, 14 Mar 2024 15:40:17 +0100 Subject: [PATCH 13/26] update with new oracle protections --- helpers/createProposal.sh | 10 ++--- scripts/proposals/payload.json | 2 +- .../transmuter/TransmuterUpdateFacets.s.sol | 4 +- .../transmuter/TransmuterUtils.s.sol | 13 +++---- .../TransmuterUpdateFacetsTest.t.sol | 37 +++++++++++-------- 5 files changed, 35 insertions(+), 31 deletions(-) diff --git a/helpers/createProposal.sh b/helpers/createProposal.sh index e5191fc..91c7909 100644 --- a/helpers/createProposal.sh +++ b/helpers/createProposal.sh @@ -7,6 +7,7 @@ function usage { echo "" echo -e "script: path to the script to run" echo -e "chain: chain(s) to run the script on (separate with commas)" + echo -e "\t0: Fork" echo -e "\t1: Ethereum Mainnet" echo -e "\t2: Arbitrum" echo -e "\t3: Polygon" @@ -18,7 +19,6 @@ function usage { echo -e "\t9: Polygon ZkEvm" echo -e "\t10: Optimism" echo -e "\t11: Linea" - echo -e "\t12: Fork" echo "" } @@ -54,6 +54,7 @@ function main { echo "" echo "Which chain(s) would you like to run the script on ? (separate with commas)" + echo "- 0: Fork" echo "- 1: Ethereum Mainnet" echo "- 2: Arbitrum" echo "- 3: Polygon" @@ -65,7 +66,6 @@ function main { echo "- 9: Polygon ZkEvm" echo "- 10: Optimism" echo "- 11: Linea" - echo "- 12: Fork" echo "- 100: All" read chains @@ -119,9 +119,9 @@ function main { echo "Would you like to create the proposal ? (yes/no)" read execute - if [[ $execute == "yes" ]]; then - FOUNDRY_PROFILE=dev forge script scripts/proposals/Propose.s.sol:Propose --fork-url $mainnet_uri --broadcast - fi + # if [[ $execute == "yes" ]]; then + # FOUNDRY_PROFILE=dev forge script scripts/proposals/Propose.s.sol:Propose --fork-url $mainnet_uri --broadcast + # fi } main $@ diff --git a/scripts/proposals/payload.json b/scripts/proposals/payload.json index 4c24892..80433dc 100644 --- a/scripts/proposals/payload.json +++ b/scripts/proposals/payload.json @@ -1,6 +1,6 @@ { "calldatas": { - "0": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000008641f931c1c0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000000000000000000000000000000000000000068000000000000000000000000037eb0572eb61db3b819570cf65114ff6db6c06a2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000016b4a0bdf300000000000000000000000000000000000000000000000000000000ee565a6300000000000000000000000000000000000000000000000000000000847da7be00000000000000000000000000000000000000000000000000000000eb7aac5f000000000000000000000000000000000000000000000000000000003335221000000000000000000000000000000000000000000000000000000000b718136100000000000000000000000000000000000000000000000000000000b85780bc00000000000000000000000000000000000000000000000000000000cd377c5300000000000000000000000000000000000000000000000000000000782513bd0000000000000000000000000000000000000000000000000000000094e35d9e000000000000000000000000000000000000000000000000000000004ea3e3430000000000000000000000000000000000000000000000000000000010d3d22e0000000000000000000000000000000000000000000000000000000038c269eb00000000000000000000000000000000000000000000000000000000adc9d1f7000000000000000000000000000000000000000000000000000000008db9653f000000000000000000000000000000000000000000000000000000000d1266270000000000000000000000000000000000000000000000000000000096d6487900000000000000000000000000000000000000000000000000000000fe7d0c540000000000000000000000000000000000000000000000000000000077dc342900000000000000000000000000000000000000000000000000000000f9839d8900000000000000000000000000000000000000000000000000000000a52aefd40000000000000000000000000000000000000000000000000000000099eeca4900000000000000000000000000000000000000000000000000000000000000000000000000000000028e1f0db25daf4ce8c895215deafbce7a873b24000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004d703a0cd00000000000000000000000000000000000000000000000000000000815822c1000000000000000000000000000000000000000000000000000000002e7639bc00000000000000000000000000000000000000000000000000000000fd7daaf800000000000000000000000000000000000000000000000000000000000000000000000000000000c3ef7ed4f97450ae8da2473068375788bdeb5c5c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000af0d2d5a800000000000000000000000000000000000000000000000000000000c1cdee7e0000000000000000000000000000000000000000000000000000000087c8ab7a000000000000000000000000000000000000000000000000000000005c3eebda000000000000000000000000000000000000000000000000000000001f0ec8ee000000000000000000000000000000000000000000000000000000000e32cb860000000000000000000000000000000000000000000000000000000081ee2deb00000000000000000000000000000000000000000000000000000000b13b0847000000000000000000000000000000000000000000000000000000001b0c7182000000000000000000000000000000000000000000000000000000007c0343a100000000000000000000000000000000000000000000000000000000000000000000000000000000954ec713a3915b504a6f288563e5218f597e18950000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000064583aea6000000000000000000000000000000000000000000000000000000009525f3ab000000000000000000000000000000000000000000000000000000003b6a1fe000000000000000000000000000000000000000000000000000000000d92c6cb200000000000000000000000000000000000000000000000000000000b92567fa00000000000000000000000000000000000000000000000000000000c10a62870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001641f931c1c0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000044e3d3bba34e16a67c633daf86114284fc6288190000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011cb44dfc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364b13b08470000000000000000000000001abaea1f7c830bd89acc67ec4af516284b1bc33c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf526340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c4b13b08470000000000000000000000002f123cf3f37ce3328cc9b5b8415f9ec5109b45e7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006e27a25999b3c665e44d903b2139f5a4be2b6c260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000003f480000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000067a41c1ea336d0000000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000065e888dc000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000002386f26fc1000000000000000000000000000000000000000000000000000000000000" + "0": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000008641f931c1c0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000680000000000000000000000000b55639fdcd12503fe85e3b4d4639142c9d7951aa000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000016b4a0bdf300000000000000000000000000000000000000000000000000000000ee565a6300000000000000000000000000000000000000000000000000000000847da7be00000000000000000000000000000000000000000000000000000000eb7aac5f000000000000000000000000000000000000000000000000000000003335221000000000000000000000000000000000000000000000000000000000b718136100000000000000000000000000000000000000000000000000000000b85780bc00000000000000000000000000000000000000000000000000000000cd377c5300000000000000000000000000000000000000000000000000000000782513bd0000000000000000000000000000000000000000000000000000000094e35d9e000000000000000000000000000000000000000000000000000000004ea3e3430000000000000000000000000000000000000000000000000000000010d3d22e0000000000000000000000000000000000000000000000000000000038c269eb00000000000000000000000000000000000000000000000000000000adc9d1f7000000000000000000000000000000000000000000000000000000008db9653f000000000000000000000000000000000000000000000000000000000d1266270000000000000000000000000000000000000000000000000000000096d6487900000000000000000000000000000000000000000000000000000000fe7d0c540000000000000000000000000000000000000000000000000000000077dc342900000000000000000000000000000000000000000000000000000000f9839d8900000000000000000000000000000000000000000000000000000000a52aefd40000000000000000000000000000000000000000000000000000000099eeca4900000000000000000000000000000000000000000000000000000000000000000000000000000000fe2ff814800bb1df4e415ac88338f07471c8c87b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004d703a0cd00000000000000000000000000000000000000000000000000000000815822c1000000000000000000000000000000000000000000000000000000002e7639bc00000000000000000000000000000000000000000000000000000000fd7daaf800000000000000000000000000000000000000000000000000000000000000000000000000000000b3047f769f8ae481f99a71c488037d31e1da670700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000af0d2d5a800000000000000000000000000000000000000000000000000000000c1cdee7e0000000000000000000000000000000000000000000000000000000087c8ab7a000000000000000000000000000000000000000000000000000000005c3eebda000000000000000000000000000000000000000000000000000000001f0ec8ee000000000000000000000000000000000000000000000000000000000e32cb860000000000000000000000000000000000000000000000000000000081ee2deb00000000000000000000000000000000000000000000000000000000b13b0847000000000000000000000000000000000000000000000000000000001b0c7182000000000000000000000000000000000000000000000000000000007c0343a100000000000000000000000000000000000000000000000000000000000000000000000000000000ef0b788d254a7cc0278fc61c52486db56dd743080000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000064583aea6000000000000000000000000000000000000000000000000000000009525f3ab000000000000000000000000000000000000000000000000000000003b6a1fe000000000000000000000000000000000000000000000000000000000d92c6cb200000000000000000000000000000000000000000000000000000000b92567fa00000000000000000000000000000000000000000000000000000000c10a62870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001641f931c1c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b3047f769f8ae481f99a71c488037d31e1da67070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011cb44dfc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364b13b08470000000000000000000000001abaea1f7c830bd89acc67ec4af516284b1bc33c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf526340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c4b13b08470000000000000000000000002f123cf3f37ce3328cc9b5b8415f9ec5109b45e7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006e27a25999b3c665e44d903b2139f5a4be2b6c260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000003f480000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000067a41c1ea336d0000000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000065f2b706000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000" }, "chainIds": { "0": 1 diff --git a/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol index 64c5168..22f927e 100644 --- a/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol +++ b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol @@ -145,7 +145,7 @@ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { targetTypeEUROC, oracleDataEUROC, targetDataEUROC, - abi.encode(FIREWALL_MINT_EUROC, FIREWALL_BURN_EUROC) + abi.encode(FIREWALL_MINT_EUROC, USER_PROTECTION_EUROC) ) ) ) @@ -165,7 +165,7 @@ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { oracleDataBC3M, // We can hope that the oracleDataBC3M won't move much before the proposal is executed abi.encode(currentBC3MPrice, DEVIATION_THRESHOLD_BC3M, uint96(block.timestamp), HEARTBEAT), - abi.encode(FIREWALL_MINT_BC3M, FIREWALL_BURN_BC3M) + abi.encode(FIREWALL_MINT_BC3M, USER_PROTECTION_BC3M) ) ) ) diff --git a/scripts/proposals/transmuter/TransmuterUtils.s.sol b/scripts/proposals/transmuter/TransmuterUtils.s.sol index 94c7fa3..cada02a 100644 --- a/scripts/proposals/transmuter/TransmuterUtils.s.sol +++ b/scripts/proposals/transmuter/TransmuterUtils.s.sol @@ -23,17 +23,16 @@ contract TransmuterUtils is Script, CommonUtils { address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; uint128 constant FIREWALL_MINT_EUROC = 0; - uint128 constant FIREWALL_BURN_EUROC = uint128(5 * BPS); + uint128 constant USER_PROTECTION_EUROC = uint128(5 * BPS); uint128 constant FIREWALL_MINT_BC3M = uint128(BASE_18); - uint128 constant FIREWALL_BURN_BC3M = uint128(100 * BPS); + uint128 constant USER_PROTECTION_BC3M = uint128(10 * BPS); uint96 constant DEVIATION_THRESHOLD_BC3M = uint96(100 * BPS); uint32 constant HEARTBEAT = uint32(1 days); - address constant GETTERS = 0x37eB0572eb61db3B819570Cf65114ff6dB6C06A2; - address constant REDEEMER = 0x028e1f0DB25DAF4ce8C895215deAfbCE7A873b24; - address constant SETTERS_GOVERNOR = 0xc3ef7ed4F97450Ae8dA2473068375788BdeB5c5c; - address constant SWAPPER = 0x954eC713a3915B504a6F288563e5218F597e1895; - address constant ORACLE = 0x44E3d3BBa34E16a67c633dAF86114284FC628819; + address constant GETTERS = 0xB55639FdcD12503fE85e3B4D4639142C9D7951aa; + address constant REDEEMER = 0xFE2Ff814800Bb1df4E415ac88338f07471C8c87B; + address constant SETTERS_GOVERNOR = 0xb3047F769f8ae481F99a71C488037D31e1dA6707; + address constant SWAPPER = 0xeF0B788D254a7CC0278FC61C52486Db56dd74308; /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HELPERS diff --git a/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol index ad0cfd9..666e39d 100644 --- a/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol +++ b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol @@ -18,7 +18,8 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { // TODO COMPLETE bytes public oracleConfigEUROC = - hex"0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf52634000"; + hex"0000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000"; + // function setUp() public override { super.setUp(); @@ -28,7 +29,7 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { vm.mockCall( address(0x6E27A25999B3C665E44D903B2139F5a4Be2B6C26), abi.encodeWithSelector(AggregatorV3Interface.latestRoundData.selector), - abi.encode(uint80(0), int256(11949000000), uint256(1710170200), uint256(1710170200), uint80(0)) + abi.encode(uint80(0), int256(11949000000), uint256(1710857504), uint256(1710857504), uint80(0)) ); chainIds = _executeProposalWithFork(); @@ -74,7 +75,7 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { assertEq(collatInfoEUROC.isBurnLive, 1); assertEq(collatInfoEUROC.decimals, 6); assertEq(collatInfoEUROC.onlyWhitelisted, 0); - assertApproxEqRel(collatInfoEUROC.normalizedStables, 10893124 * BASE_18, 100 * BPS); + assertApproxEqRel(collatInfoEUROC.normalizedStables, 10593543 * BASE_18, 100 * BPS); assertEq(collatInfoEUROC.oracleConfig, oracleConfigEUROC); assertEq(collatInfoEUROC.whitelistData.length, 0); assertEq(collatInfoEUROC.managerData.subCollaterals.length, 0); @@ -137,7 +138,8 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { ); assertEq( hyperparams, - hex"0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000002386f26fc10000" + abi.encode(FIREWALL_MINT_BC3M, USER_PROTECTION_BC3M) + // hex"0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000002386f26fc10000" ); (uint256 maxValue, uint96 deviationThreshold, uint96 lastUpdateTimestamp, uint32 heartbeat) = @@ -188,33 +190,36 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ function _testGetOracleValues() internal { - _checkOracleValues(address(EUROC), BASE_18, FIREWALL_MINT_EUROC, FIREWALL_BURN_EUROC); - _checkOracleValues(address(BC3M), (11944 * BASE_18) / 100, FIREWALL_MINT_BC3M, FIREWALL_BURN_BC3M); + _checkOracleValues(address(EUROC), BASE_18, FIREWALL_MINT_EUROC, USER_PROTECTION_EUROC); + _checkOracleValues(address(BC3M), (11949 * BASE_18) / 100, FIREWALL_MINT_BC3M, USER_PROTECTION_BC3M); } /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// CHECKS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - function _checkOracleValues(address collateral, uint256 targetValue, uint128 firewallMint, uint128 firewallBurn) + function _checkOracleValues(address collateral, uint256 targetValue, uint128 firewallMint, uint128 userProtection) internal { (uint256 mint, uint256 burn, uint256 ratio, uint256 minRatio, uint256 redemption) = transmuter.getOracleValues(collateral); assertApproxEqRel(targetValue, redemption, 200 * BPS); - assertEq(burn, redemption); - if (redemption * BASE_18 < targetValue * (BASE_18 - firewallBurn)) { + + if (targetValue * (BASE_18 - userProtection) < redemption * BASE_18 && redemption * BASE_18 < targetValue * (BASE_18 + userProtection) ) assertEq(burn, targetValue); + else assertEq(burn, redemption); + + if(targetValue * (BASE_18 - userProtection) < redemption * BASE_18 && redemption * BASE_18 < targetValue * (BASE_18 + userProtection)){ + assertEq(mint,targetValue); + assertEq(ratio,BASE_18); + } else if (redemption * BASE_18 > targetValue * (BASE_18 + firewallMint)) { + assertEq(mint, targetValue); + assertEq(ratio, BASE_18); + } else if(redemption < targetValue){ assertEq(mint, redemption); assertEq(ratio, (redemption * BASE_18) / targetValue); - } else if (redemption < targetValue) { + } else{ assertEq(mint, redemption); assertEq(ratio, BASE_18); - } else if (redemption * BASE_18 < targetValue * ((BASE_18 + firewallMint))) { - assertEq(mint, redemption); - assertEq(ratio, BASE_18); - } else { - assertEq(mint, targetValue); - assertEq(ratio, BASE_18); } } } From 70622a1ceab19539dfd51fc3a6070be05e08b3b0 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Thu, 14 Mar 2024 16:47:42 +0100 Subject: [PATCH 14/26] fix tests --- scripts/proposals/payload.json | 2 +- .../TransmuterUpdateFacetsTest.t.sol | 35 ++++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/scripts/proposals/payload.json b/scripts/proposals/payload.json index 80433dc..c038adf 100644 --- a/scripts/proposals/payload.json +++ b/scripts/proposals/payload.json @@ -1,6 +1,6 @@ { "calldatas": { - "0": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000008641f931c1c0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000680000000000000000000000000b55639fdcd12503fe85e3b4d4639142c9d7951aa000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000016b4a0bdf300000000000000000000000000000000000000000000000000000000ee565a6300000000000000000000000000000000000000000000000000000000847da7be00000000000000000000000000000000000000000000000000000000eb7aac5f000000000000000000000000000000000000000000000000000000003335221000000000000000000000000000000000000000000000000000000000b718136100000000000000000000000000000000000000000000000000000000b85780bc00000000000000000000000000000000000000000000000000000000cd377c5300000000000000000000000000000000000000000000000000000000782513bd0000000000000000000000000000000000000000000000000000000094e35d9e000000000000000000000000000000000000000000000000000000004ea3e3430000000000000000000000000000000000000000000000000000000010d3d22e0000000000000000000000000000000000000000000000000000000038c269eb00000000000000000000000000000000000000000000000000000000adc9d1f7000000000000000000000000000000000000000000000000000000008db9653f000000000000000000000000000000000000000000000000000000000d1266270000000000000000000000000000000000000000000000000000000096d6487900000000000000000000000000000000000000000000000000000000fe7d0c540000000000000000000000000000000000000000000000000000000077dc342900000000000000000000000000000000000000000000000000000000f9839d8900000000000000000000000000000000000000000000000000000000a52aefd40000000000000000000000000000000000000000000000000000000099eeca4900000000000000000000000000000000000000000000000000000000000000000000000000000000fe2ff814800bb1df4e415ac88338f07471c8c87b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004d703a0cd00000000000000000000000000000000000000000000000000000000815822c1000000000000000000000000000000000000000000000000000000002e7639bc00000000000000000000000000000000000000000000000000000000fd7daaf800000000000000000000000000000000000000000000000000000000000000000000000000000000b3047f769f8ae481f99a71c488037d31e1da670700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000af0d2d5a800000000000000000000000000000000000000000000000000000000c1cdee7e0000000000000000000000000000000000000000000000000000000087c8ab7a000000000000000000000000000000000000000000000000000000005c3eebda000000000000000000000000000000000000000000000000000000001f0ec8ee000000000000000000000000000000000000000000000000000000000e32cb860000000000000000000000000000000000000000000000000000000081ee2deb00000000000000000000000000000000000000000000000000000000b13b0847000000000000000000000000000000000000000000000000000000001b0c7182000000000000000000000000000000000000000000000000000000007c0343a100000000000000000000000000000000000000000000000000000000000000000000000000000000ef0b788d254a7cc0278fc61c52486db56dd743080000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000064583aea6000000000000000000000000000000000000000000000000000000009525f3ab000000000000000000000000000000000000000000000000000000003b6a1fe000000000000000000000000000000000000000000000000000000000d92c6cb200000000000000000000000000000000000000000000000000000000b92567fa00000000000000000000000000000000000000000000000000000000c10a62870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001641f931c1c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b3047f769f8ae481f99a71c488037d31e1da67070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011cb44dfc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364b13b08470000000000000000000000001abaea1f7c830bd89acc67ec4af516284b1bc33c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf526340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c4b13b08470000000000000000000000002f123cf3f37ce3328cc9b5b8415f9ec5109b45e7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006e27a25999b3c665e44d903b2139f5a4be2b6c260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000003f480000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000067a41c1ea336d0000000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000065f2b706000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000" + "0": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000008641f931c1c0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000680000000000000000000000000b55639fdcd12503fe85e3b4d4639142c9d7951aa000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000016b4a0bdf300000000000000000000000000000000000000000000000000000000ee565a6300000000000000000000000000000000000000000000000000000000847da7be00000000000000000000000000000000000000000000000000000000eb7aac5f000000000000000000000000000000000000000000000000000000003335221000000000000000000000000000000000000000000000000000000000b718136100000000000000000000000000000000000000000000000000000000b85780bc00000000000000000000000000000000000000000000000000000000cd377c5300000000000000000000000000000000000000000000000000000000782513bd0000000000000000000000000000000000000000000000000000000094e35d9e000000000000000000000000000000000000000000000000000000004ea3e3430000000000000000000000000000000000000000000000000000000010d3d22e0000000000000000000000000000000000000000000000000000000038c269eb00000000000000000000000000000000000000000000000000000000adc9d1f7000000000000000000000000000000000000000000000000000000008db9653f000000000000000000000000000000000000000000000000000000000d1266270000000000000000000000000000000000000000000000000000000096d6487900000000000000000000000000000000000000000000000000000000fe7d0c540000000000000000000000000000000000000000000000000000000077dc342900000000000000000000000000000000000000000000000000000000f9839d8900000000000000000000000000000000000000000000000000000000a52aefd40000000000000000000000000000000000000000000000000000000099eeca4900000000000000000000000000000000000000000000000000000000000000000000000000000000fe2ff814800bb1df4e415ac88338f07471c8c87b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004d703a0cd00000000000000000000000000000000000000000000000000000000815822c1000000000000000000000000000000000000000000000000000000002e7639bc00000000000000000000000000000000000000000000000000000000fd7daaf800000000000000000000000000000000000000000000000000000000000000000000000000000000b3047f769f8ae481f99a71c488037d31e1da670700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000af0d2d5a800000000000000000000000000000000000000000000000000000000c1cdee7e0000000000000000000000000000000000000000000000000000000087c8ab7a000000000000000000000000000000000000000000000000000000005c3eebda000000000000000000000000000000000000000000000000000000001f0ec8ee000000000000000000000000000000000000000000000000000000000e32cb860000000000000000000000000000000000000000000000000000000081ee2deb00000000000000000000000000000000000000000000000000000000b13b0847000000000000000000000000000000000000000000000000000000001b0c7182000000000000000000000000000000000000000000000000000000007c0343a100000000000000000000000000000000000000000000000000000000000000000000000000000000ef0b788d254a7cc0278fc61c52486db56dd743080000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000064583aea6000000000000000000000000000000000000000000000000000000009525f3ab000000000000000000000000000000000000000000000000000000003b6a1fe000000000000000000000000000000000000000000000000000000000d92c6cb200000000000000000000000000000000000000000000000000000000b92567fa00000000000000000000000000000000000000000000000000000000c10a62870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001641f931c1c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b3047f769f8ae481f99a71c488037d31e1da67070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011cb44dfc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364b13b08470000000000000000000000001abaea1f7c830bd89acc67ec4af516284b1bc33c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf526340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c4b13b08470000000000000000000000002f123cf3f37ce3328cc9b5b8415f9ec5109b45e7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006e27a25999b3c665e44d903b2139f5a4be2b6c260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000003f480000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000067b5df97db1750000000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000065f31a88000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000" }, "chainIds": { "0": 1 diff --git a/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol index 666e39d..90d3ed9 100644 --- a/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol +++ b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol @@ -17,7 +17,7 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { uint256[] chainIds; // TODO COMPLETE - bytes public oracleConfigEUROC = + bytes public oracleConfigDataEUROC = hex"0000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000"; // @@ -75,8 +75,33 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { assertEq(collatInfoEUROC.isBurnLive, 1); assertEq(collatInfoEUROC.decimals, 6); assertEq(collatInfoEUROC.onlyWhitelisted, 0); - assertApproxEqRel(collatInfoEUROC.normalizedStables, 10593543 * BASE_18, 100 * BPS); - assertEq(collatInfoEUROC.oracleConfig, oracleConfigEUROC); + assertApproxEqRel(collatInfoEUROC.normalizedStables, 10450179 * BASE_18, 100 * BPS); + { + ( + Storage.OracleReadType oracleType, + Storage.OracleReadType targetType, + bytes memory oracleData, + bytes memory targetData, + bytes memory hyperparams + ) = abi.decode( + collatInfoEUROC.oracleConfig, (Storage.OracleReadType, Storage.OracleReadType, bytes, bytes, bytes) + ); + + assertEq(uint8(oracleType), uint8(8)); + assertEq(uint8(targetType), uint8(3)); + assertEq( + oracleData, + hex"" + ); + assertEq( + targetData, + hex"" + ); + assertEq( + hyperparams, + abi.encode(FIREWALL_MINT_BC3M, USER_PROTECTION_BC3M) + ); + } assertEq(collatInfoEUROC.whitelistData.length, 0); assertEq(collatInfoEUROC.managerData.subCollaterals.length, 0); assertEq(collatInfoEUROC.managerData.config.length, 0); @@ -134,7 +159,7 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { assertEq(uint8(targetType), uint8(9)); assertEq( oracleData, - hex"00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006e27a25999b3c665e44d903b2139f5a4be2b6c260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000003f4800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000008" + oracleConfigDataEUROC ); assertEq( hyperparams, @@ -191,7 +216,7 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { function _testGetOracleValues() internal { _checkOracleValues(address(EUROC), BASE_18, FIREWALL_MINT_EUROC, USER_PROTECTION_EUROC); - _checkOracleValues(address(BC3M), (11949 * BASE_18) / 100, FIREWALL_MINT_BC3M, USER_PROTECTION_BC3M); + _checkOracleValues(address(BC3M), (11957 * BASE_18) / 100, FIREWALL_MINT_BC3M, USER_PROTECTION_BC3M); } /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// From afad6a608e1e75d084d02d2e04c527b88a82d731 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Fri, 22 Mar 2024 11:27:53 +0100 Subject: [PATCH 15/26] chore: prettier --- .vscode/settings.json | 1 - contracts/AngleGovernor.sol | 54 ++- contracts/ProposalReceiver.sol | 32 +- contracts/ProposalSender.sol | 42 +- contracts/TimelockControllerWithCounter.sol | 11 +- contracts/VeANGLEVotingDelegation.sol | 172 ++++---- .../external/GovernorCountingFractional.sol | 44 +- contracts/external/GovernorShortCircuit.sol | 33 +- scripts/Constants.s.sol | 20 +- scripts/Interfaces.s.sol | 4 +- scripts/Utils.s.sol | 12 +- .../deployment/DeployOnChainGovernance.s.sol | 20 +- .../DeploySideChainGovernance.s.sol | 12 +- scripts/interaction/CheckRoles.s.sol | 285 ++++++++----- scripts/interfaces/ITransmuter.sol | 7 +- .../angleGovernor/IncreaseQuorum.s.sol | 16 +- scripts/proposals/timelock/AddExecutor.s.sol | 19 +- .../transmuter/TransmuterUpdateFacets.s.sol | 50 +-- .../transmuter/TransmuterUtils.s.sol | 13 +- test/Constants.t.sol | 4 +- test/Fixture.t.sol | 24 +- test/external/MockANGLE.sol | 2 +- test/fuzz/GovernorCountingFractional.t.sol | 283 ++++++++----- test/fuzz/VeANGLEVotingDelegation.t.sol | 65 +-- test/invariant/BasicInvariants.t.sol | 12 +- test/invariant/DelegationInvariants.t.sol | 10 +- .../invariant/MainnetGovernorInvariants.t.sol | 62 +-- test/invariant/actors/BadVoter.t.sol | 37 +- test/invariant/actors/BaseActor.t.sol | 10 +- test/invariant/actors/Delegator.t.sol | 18 +- test/invariant/actors/Param.t.sol | 6 +- test/invariant/actors/Proposer.t.sol | 34 +- test/invariant/actors/Voter.t.sol | 25 +- test/scripts/ScriptHelpers.t.sol | 60 +-- test/scripts/timelock/AddExecutor.t.sol | 19 +- .../TransmuterUpdateFacetsTest.t.sol | 91 +++-- test/unit/AngleGovernor.t.sol | 40 +- test/unit/GovernorShortCircuit.t.sol | 57 +-- test/unit/GovernorStateAndPropose.t.sol | 44 +- test/unit/ProposalLayerZeroRelayer.t.sol | 379 ++++++++++++------ test/unit/Scenarios.t.sol | 43 +- test/unit/Simulate.t.sol | 31 +- test/unit/SimulationSetup.t.sol | 142 ++++--- test/unit/TimelockControllerWithCounter.t.sol | 215 ++++++---- 44 files changed, 1566 insertions(+), 994 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index ed5b591..261c161 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,5 @@ { "solidity.compileUsingRemoteVersion": "0.8.20", - "solidity.formatter": "forge", "[typescript]": { "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" }, diff --git a/contracts/AngleGovernor.sol b/contracts/AngleGovernor.sol index bdcf84c..7fead4d 100644 --- a/contracts/AngleGovernor.sol +++ b/contracts/AngleGovernor.sol @@ -2,16 +2,16 @@ pragma solidity ^0.8.20; -import {IVotes} from "oz-v5/governance/utils/IVotes.sol"; +import { IVotes } from "oz-v5/governance/utils/IVotes.sol"; -import {Governor} from "oz-v5/governance/Governor.sol"; -import {GovernorPreventLateQuorum} from "oz-v5/governance/extensions/GovernorPreventLateQuorum.sol"; -import {GovernorVotesQuorumFraction, GovernorVotes} from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; -import {GovernorSettings} from "oz-v5/governance/extensions/GovernorSettings.sol"; -import {IERC5805} from "oz-v5/interfaces/IERC5805.sol"; +import { Governor } from "oz-v5/governance/Governor.sol"; +import { GovernorPreventLateQuorum } from "oz-v5/governance/extensions/GovernorPreventLateQuorum.sol"; +import { GovernorVotesQuorumFraction, GovernorVotes } from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; +import { GovernorSettings } from "oz-v5/governance/extensions/GovernorSettings.sol"; +import { IERC5805 } from "oz-v5/interfaces/IERC5805.sol"; -import {GovernorCountingFractional} from "./external/GovernorCountingFractional.sol"; -import {GovernorShortCircuit} from "./external/GovernorShortCircuit.sol"; +import { GovernorCountingFractional } from "./external/GovernorCountingFractional.sol"; +import { GovernorShortCircuit } from "./external/GovernorShortCircuit.sol"; import "./utils/Errors.sol"; @@ -85,8 +85,9 @@ contract AngleGovernor is function state(uint256 proposalId) public view override(Governor) returns (ProposalState) { ProposalState currentState = super.state(proposalId); if ( - currentState == ProposalState.Executed || currentState == ProposalState.Canceled - || currentState == ProposalState.Pending + currentState == ProposalState.Executed || + currentState == ProposalState.Canceled || + currentState == ProposalState.Pending ) return currentState; uint256 snapshot = proposalSnapshot(proposalId); @@ -104,26 +105,21 @@ contract AngleGovernor is } /// @inheritdoc GovernorVotesQuorumFraction - function quorum(uint256 timepoint) - public - view - override(Governor, GovernorVotesQuorumFraction) - returns (uint256 quorumAtTimepoint) - { + function quorum( + uint256 timepoint + ) public view override(Governor, GovernorVotesQuorumFraction) returns (uint256 quorumAtTimepoint) { uint256 snapshotBlockNumber = $snapshotTimestampToSnapshotBlockNumber[timepoint]; if (snapshotBlockNumber == 0 || snapshotBlockNumber >= block.number) revert InvalidTimepoint(); quorumAtTimepoint = - (token().getPastTotalSupply(snapshotBlockNumber) * quorumNumerator(timepoint)) / quorumDenominator(); + (token().getPastTotalSupply(snapshotBlockNumber) * quorumNumerator(timepoint)) / + quorumDenominator(); } /// @inheritdoc GovernorPreventLateQuorum - function proposalDeadline(uint256 proposalId) - public - view - override(Governor, GovernorPreventLateQuorum) - returns (uint256) - { + function proposalDeadline( + uint256 proposalId + ) public view override(Governor, GovernorPreventLateQuorum) returns (uint256) { return GovernorPreventLateQuorum.proposalDeadline(proposalId); } @@ -174,11 +170,13 @@ contract AngleGovernor is } /// @inheritdoc GovernorPreventLateQuorum - function _castVote(uint256 proposalId, address account, uint8 support, string memory reason, bytes memory params) - internal - override(Governor, GovernorPreventLateQuorum) - returns (uint256) - { + function _castVote( + uint256 proposalId, + address account, + uint8 support, + string memory reason, + bytes memory params + ) internal override(Governor, GovernorPreventLateQuorum) returns (uint256) { return GovernorPreventLateQuorum._castVote(proposalId, account, support, reason, params); } diff --git a/contracts/ProposalReceiver.sol b/contracts/ProposalReceiver.sol index 73897ba..d6a53f7 100644 --- a/contracts/ProposalReceiver.sol +++ b/contracts/ProposalReceiver.sol @@ -25,11 +25,12 @@ contract ProposalReceiver is NonblockingLzApp, ReentrancyGuard { constructor(address _endpoint) NonblockingLzApp(_endpoint) Ownable(msg.sender) {} // overriding the virtual function in LzReceiver - function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) - internal - virtual - override - { + function _blockingLzReceive( + uint16 _srcChainId, + bytes memory _srcAddress, + uint64 _nonce, + bytes memory _payload + ) internal virtual override { bytes32 hashedPayload = keccak256(_payload); uint256 gasToStoreAndEmit = 30000; // enough gas to ensure we can store the payload and emit the event @@ -49,8 +50,8 @@ contract ProposalReceiver is NonblockingLzApp, ReentrancyGuard { /// @notice Executes the proposal /// @dev Called by LayerZero Endpoint when a message from the source is received function _nonblockingLzReceive(uint16, bytes memory, uint64, bytes memory _payload) internal virtual override { - (address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas) = - abi.decode(_payload, (address[], uint256[], string[], bytes[])); + (address[] memory targets, uint256[] memory values, string[] memory signatures, bytes[] memory calldatas) = abi + .decode(_payload, (address[], uint256[], string[], bytes[])); for (uint256 i = 0; i < targets.length; i++) { _executeTransaction(targets[i], values[i], signatures[i], calldatas[i]); @@ -58,15 +59,18 @@ contract ProposalReceiver is NonblockingLzApp, ReentrancyGuard { emit ProposalExecuted(_payload); } - function _executeTransaction(address target, uint256 value, string memory signature, bytes memory data) - private - nonReentrant - { - bytes memory callData = - bytes(signature).length == 0 ? data : abi.encodePacked(bytes4(keccak256(bytes(signature))), data); + function _executeTransaction( + address target, + uint256 value, + string memory signature, + bytes memory data + ) private nonReentrant { + bytes memory callData = bytes(signature).length == 0 + ? data + : abi.encodePacked(bytes4(keccak256(bytes(signature))), data); // solium-disable-next-line security/no-call-value - (bool success,) = target.call{value: value}(callData); + (bool success, ) = target.call{ value: value }(callData); if (!success) revert OmnichainGovernanceExecutorTxExecReverted(); } diff --git a/contracts/ProposalSender.sol b/contracts/ProposalSender.sol index 21a1b48..12f59c0 100644 --- a/contracts/ProposalSender.sol +++ b/contracts/ProposalSender.sol @@ -66,11 +66,11 @@ contract ProposalSender is Ownable, ReentrancyGuard { /// on the destination /// @return nativeFee The amount of fee in the native gas token (e.g. ETH) /// @return zroFee The amount of fee in ZRO token - function estimateFees(uint16 remoteChainId, bytes calldata payload, bytes calldata adapterParams) - external - view - returns (uint256 nativeFee, uint256 zroFee) - { + function estimateFees( + uint16 remoteChainId, + bytes calldata payload, + bytes calldata adapterParams + ) external view returns (uint256 nativeFee, uint256 zroFee) { return lzEndpoint.estimateFees(remoteChainId, address(this), payload, false, adapterParams); } @@ -81,17 +81,24 @@ contract ProposalSender is Ownable, ReentrancyGuard { /// payload = abi.encode(targets, values, signatures, calldatas) /// @param adapterParams The params used to specify the custom amount of gas required for the execution /// on the destination - function execute(uint16 remoteChainId, bytes calldata payload, bytes calldata adapterParams) - external - payable - onlyOwner - { + function execute( + uint16 remoteChainId, + bytes calldata payload, + bytes calldata adapterParams + ) external payable onlyOwner { bytes memory trustedRemote = trustedRemoteLookup[remoteChainId]; if (trustedRemote.length == 0) revert OmnichainProposalSenderDestinationChainNotTrustedSource(); - try lzEndpoint.send{value: msg.value}( - remoteChainId, trustedRemote, payload, payable(tx.origin), address(0), adapterParams - ) { + try + lzEndpoint.send{ value: msg.value }( + remoteChainId, + trustedRemote, + payload, + payable(tx.origin), + address(0), + adapterParams + ) + { emit ExecuteRemoteProposal(remoteChainId, payload); } catch (bytes memory reason) { uint64 _lastStoredPayloadNonce = ++lastStoredPayloadNonce; @@ -125,8 +132,13 @@ contract ProposalSender is Ownable, ReentrancyGuard { delete storedExecutionHashes[nonce]; - lzEndpoint.send{value: originalValue + msg.value}( - remoteChainId, trustedRemoteLookup[remoteChainId], payload, payable(msg.sender), address(0), adapterParams + lzEndpoint.send{ value: originalValue + msg.value }( + remoteChainId, + trustedRemoteLookup[remoteChainId], + payload, + payable(msg.sender), + address(0), + adapterParams ); emit ClearPayload(nonce, hash); } diff --git a/contracts/TimelockControllerWithCounter.sol b/contracts/TimelockControllerWithCounter.sol index 2efd7ca..97d0010 100644 --- a/contracts/TimelockControllerWithCounter.sol +++ b/contracts/TimelockControllerWithCounter.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.20; -import {TimelockController} from "oz-v5/governance/TimelockController.sol"; +import { TimelockController } from "oz-v5/governance/TimelockController.sol"; /// @title AngleGovernor /// @author Angle Labs, Inc @@ -24,9 +24,12 @@ contract TimelockControllerWithCounter is TimelockController { CONSTRUCTOR //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - constructor(uint256 minDelay, address[] memory proposers, address[] memory executors, address admin) - TimelockController(minDelay, proposers, executors, admin) - {} + constructor( + uint256 minDelay, + address[] memory proposers, + address[] memory executors, + address admin + ) TimelockController(minDelay, proposers, executors, admin) {} /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// EXTERNAL OVERRIDES diff --git a/contracts/VeANGLEVotingDelegation.sol b/contracts/VeANGLEVotingDelegation.sol index f1a40fe..1c723de 100644 --- a/contracts/VeANGLEVotingDelegation.sol +++ b/contracts/VeANGLEVotingDelegation.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: ISC pragma solidity ^0.8.20; -import {ECDSA} from "oz-v5/utils/cryptography/ECDSA.sol"; -import {EIP712} from "oz-v5/utils/cryptography/EIP712.sol"; -import {Math} from "oz-v5/utils/math/Math.sol"; -import {SafeCast} from "oz-v5/utils/math/SafeCast.sol"; -import {IERC5805} from "oz-v5/interfaces/IERC5805.sol"; -import {IveANGLE} from "./interfaces/IveANGLE.sol"; -import {IveANGLEVotingDelegation} from "./interfaces/IveANGLEVotingDelegation.sol"; +import { ECDSA } from "oz-v5/utils/cryptography/ECDSA.sol"; +import { EIP712 } from "oz-v5/utils/cryptography/EIP712.sol"; +import { Math } from "oz-v5/utils/math/Math.sol"; +import { SafeCast } from "oz-v5/utils/math/SafeCast.sol"; +import { IERC5805 } from "oz-v5/interfaces/IERC5805.sol"; +import { IveANGLE } from "./interfaces/IveANGLE.sol"; +import { IveANGLEVotingDelegation } from "./interfaces/IveANGLEVotingDelegation.sol"; /// @title VeANGLEVotingDelegation /// @notice Contract that keeps track of voting weights and delegations, leveraging veANGLE @@ -45,7 +45,8 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @notice Mapping from delegate to weekly rounded time of expiry to the aggregated values at time of expiration. /// Mirrors veANGLE expiration. - mapping(address delegate => mapping(uint256 week => IveANGLEVotingDelegation.Expiration)) public $expiredDelegations; + mapping(address delegate => mapping(uint256 week => IveANGLEVotingDelegation.Expiration)) + public $expiredDelegations; /// @notice Constructor of the contract, called on deployment /// @param veANGLE Address of veANGLE contract @@ -57,11 +58,10 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param delegateAddress Address of delegate /// @param index Integer index of the checkpoint /// @return delegateCheckpoint DelegateCheckpoint of ```delegate``` at ```index``` - function getCheckpoint(address delegateAddress, uint32 index) - external - view - returns (IveANGLEVotingDelegation.DelegateCheckpoint memory) - { + function getCheckpoint( + address delegateAddress, + uint32 index + ) external view returns (IveANGLEVotingDelegation.DelegateCheckpoint memory) { return $delegateCheckpoints[delegateAddress][index]; } @@ -71,14 +71,15 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param voter Address of voter /// @param timestamp A block.timestamp, typically corresponding to a proposal snapshot /// @return delegatedWeight Voting weight corresponding to all ```delegateAccount```'s received delegations - function _calculateDelegatedWeight(address voter, uint256 timestamp) - internal - view - returns (uint256 delegatedWeight) - { + function _calculateDelegatedWeight( + address voter, + uint256 timestamp + ) internal view returns (uint256 delegatedWeight) { // Check if delegate account has any delegations - IveANGLEVotingDelegation.DelegateCheckpoint memory checkpoint = - _checkpointBinarySearch({_$checkpoints: $delegateCheckpoints[voter], timestamp: timestamp}); + IveANGLEVotingDelegation.DelegateCheckpoint memory checkpoint = _checkpointBinarySearch({ + _$checkpoints: $delegateCheckpoints[voter], + timestamp: timestamp + }); // If checkpoint is empty, short circuit and return 0 delegated weight if (checkpoint.timestamp == 0) { @@ -87,8 +88,12 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // It's possible that some delegated veANGLE has expired. // Add up all expirations during this time period, week by week. - (uint256 totalExpiredBias, uint256 totalExpiredSlope) = - _calculateExpirations({account: voter, start: checkpoint.timestamp, end: timestamp, checkpoint: checkpoint}); + (uint256 totalExpiredBias, uint256 totalExpiredSlope) = _calculateExpirations({ + account: voter, + start: checkpoint.timestamp, + end: timestamp, + checkpoint: checkpoint + }); uint256 expirationAdjustedBias = checkpoint.normalizedBias - totalExpiredBias; uint256 expirationAdjustedSlope = checkpoint.normalizedSlope - totalExpiredSlope; @@ -114,7 +119,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { uint256 firstDelegationTimestamp = $delegations[voter].firstDelegationTimestamp; // Never delegated OR this timestamp is before the first delegation by account if (firstDelegationTimestamp == 0 || timestamp < firstDelegationTimestamp) { - try VE_ANGLE.balanceOf({addr: voter, _t: timestamp}) returns (uint256 _balance) { + try VE_ANGLE.balanceOf({ addr: voter, _t: timestamp }) returns (uint256 _balance) { return _balance; } catch {} } @@ -127,13 +132,12 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @dev See _calculateExpirations /// @param delegateAddress Address of delegate /// @return calculatedCheckpoint A new DelegateCheckpoint to write based on expirations since previous checkpoint - function calculateExpiredDelegations(address delegateAddress) - public - view - returns (IveANGLEVotingDelegation.DelegateCheckpoint memory calculatedCheckpoint) - { - IveANGLEVotingDelegation.DelegateCheckpoint[] storage $userDelegationCheckpoints = - $delegateCheckpoints[delegateAddress]; + function calculateExpiredDelegations( + address delegateAddress + ) public view returns (IveANGLEVotingDelegation.DelegateCheckpoint memory calculatedCheckpoint) { + IveANGLEVotingDelegation.DelegateCheckpoint[] storage $userDelegationCheckpoints = $delegateCheckpoints[ + delegateAddress + ]; // This ensures that checkpoints take effect at the next epoch uint256 checkpointTimestamp = ((block.timestamp / 1 days) * 1 days) + 1 days; @@ -142,8 +146,9 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // Nothing to expire if no one delegated to you if (checkpointsLength == 0) return calculatedCheckpoint; - IveANGLEVotingDelegation.DelegateCheckpoint memory lastCheckpoint = - $userDelegationCheckpoints[checkpointsLength - 1]; + IveANGLEVotingDelegation.DelegateCheckpoint memory lastCheckpoint = $userDelegationCheckpoints[ + checkpointsLength - 1 + ]; // Nothing expired because the most recent checkpoint is already written if (lastCheckpoint.timestamp == checkpointTimestamp) { @@ -196,8 +201,9 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param timestamp A block.timestamp, typically corresponding to a proposal snapshot /// @return totalVotingWeight Voting weight of ```voter``` at ```timestamp``` function _getVotingWeight(address voter, uint256 timestamp) internal view returns (uint256 totalVotingWeight) { - totalVotingWeight = _calculateVotingWeight({voter: voter, timestamp: timestamp}) - + _calculateDelegatedWeight({voter: voter, timestamp: timestamp}); + totalVotingWeight = + _calculateVotingWeight({ voter: voter, timestamp: timestamp }) + + _calculateDelegatedWeight({ voter: voter, timestamp: timestamp }); } /// @notice Calculates a voter's weight at ```timestamp``` @@ -205,14 +211,14 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param timepoint A block.timestamp, typically corresponding to a proposal snapshot /// @return votingWeight Voting weight of ```voterAddress``` at ```timepoint``` function getVotes(address voter, uint256 timepoint) external view returns (uint256) { - return _getVotingWeight({voter: voter, timestamp: timepoint}); + return _getVotingWeight({ voter: voter, timestamp: timepoint }); } /// @notice Calculates a voter's weight at the current block.timestamp /// @param voter Address of voter /// @return votingWeight Voting weight of ```voterAddress``` at ```block.timestamp``` function getVotes(address voter) external view returns (uint256 votingWeight) { - votingWeight = _getVotingWeight({voter: voter, timestamp: block.timestamp}); + votingWeight = _getVotingWeight({ voter: voter, timestamp: block.timestamp }); } /// @notice Calculates a voter's weight at ```timepoint``` @@ -222,7 +228,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { function getPastVotes(address voter, uint256 timepoint) external view returns (uint256 pastVotingWeight) { if (timepoint >= block.timestamp) revert IveANGLEVotingDelegation.TimestampInFuture(); - pastVotingWeight = _getVotingWeight({voter: voter, timestamp: timepoint}); + pastVotingWeight = _getVotingWeight({ voter: voter, timestamp: timepoint }); } /// @notice Retrieves the total supply of veANGLE at ```blockNumber``` @@ -250,7 +256,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @notice Delegates votes from signer to ```delegatee``` at the next epoch /// @param delegatee Address to delegate to function delegate(address delegatee) external { - _delegate({delegator: msg.sender, delegatee: delegatee}); + _delegate({ delegator: msg.sender, delegatee: delegatee }); } /// @notice Delegates votes from signer to ```delegatee``` @@ -260,16 +266,22 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param v Recovery ID /// @param r Output of an ECDSA signature /// @param s Output of an ECDSA signature - function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) - public - virtual - override - { + function delegateBySig( + address delegatee, + uint256 nonce, + uint256 expiry, + uint8 v, + bytes32 r, + bytes32 s + ) public virtual override { // Revert if signature is expired if (block.timestamp > expiry) revert IveANGLEVotingDelegation.SignatureExpired(); address signer = ECDSA.recover( - _hashTypedDataV4(keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry))), v, r, s + _hashTypedDataV4(keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry))), + v, + r, + s ); // Increment nonce and check against incremented value @@ -291,8 +303,11 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // This ensures that checkpoints take effect at the next epoch uint256 checkpointTimestamp = ((block.timestamp / 1 days) * 1 days) + 1 days; - IveANGLEVotingDelegation.NormalizedVeANGLELockInfo memory normalizedDelegatorVeANGLELockInfo = - _getNormalizedveANGLELockInfo({delegator: delegator, checkpointTimestamp: checkpointTimestamp}); + IveANGLEVotingDelegation.NormalizedVeANGLELockInfo + memory normalizedDelegatorVeANGLELockInfo = _getNormalizedveANGLELockInfo({ + delegator: delegator, + checkpointTimestamp: checkpointTimestamp + }); _moveVotingPowerFromPreviousDelegate({ previousDelegation: previousDelegation, @@ -316,7 +331,11 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { slope: uint64(normalizedDelegatorVeANGLELockInfo.slope) }); - emit DelegateChanged({delegator: delegator, fromDelegate: previousDelegation.delegate, toDelegate: delegatee}); + emit DelegateChanged({ + delegator: delegator, + fromDelegate: previousDelegation.delegate, + toDelegate: delegatee + }); } /// @notice Retrieves lock information from veANGLE. @@ -324,11 +343,10 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { /// @param delegator Address of the delegator /// @param checkpointTimestamp block.timestamp of the next checkpoint epoch /// @return normalizedVeANGLELockInfo Information about delegator's lock from veANGLE contract, normalized - function _getNormalizedveANGLELockInfo(address delegator, uint256 checkpointTimestamp) - private - view - returns (IveANGLEVotingDelegation.NormalizedVeANGLELockInfo memory normalizedVeANGLELockInfo) - { + function _getNormalizedveANGLELockInfo( + address delegator, + uint256 checkpointTimestamp + ) private view returns (IveANGLEVotingDelegation.NormalizedVeANGLELockInfo memory normalizedVeANGLELockInfo) { // Check expiry in case we need to revert uint256 expiry = VE_ANGLE.locked(delegator).end; if (expiry <= checkpointTimestamp) revert IveANGLEVotingDelegation.CantDelegateLockExpired(); @@ -336,9 +354,9 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // Most recent epoch uint256 epoch = VE_ANGLE.user_point_epoch(delegator); // Values for delegator at the most recent epoch - (int128 userBias, int128 userSlope,,) = VE_ANGLE.user_point_history({_addr: delegator, _idx: epoch}); + (int128 userBias, int128 userSlope, , ) = VE_ANGLE.user_point_history({ _addr: delegator, _idx: epoch }); // Get the timestamp of the last update in veANGLE user history - uint256 lastUpdate = VE_ANGLE.user_point_history__ts({_addr: delegator, _idx: epoch}); + uint256 lastUpdate = VE_ANGLE.user_point_history__ts({ _addr: delegator, _idx: epoch }); // Set return values normalizedVeANGLELockInfo.slope = SafeCast.toUint256(userSlope); @@ -396,13 +414,15 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // Remove voting power from previous delegate, if they exist if (previousDelegation.delegate != address(0)) { // Get the last Checkpoint for previous delegate - IveANGLEVotingDelegation.DelegateCheckpoint[] storage $previousDelegationCheckpoints = - $delegateCheckpoints[previousDelegation.delegate]; + IveANGLEVotingDelegation.DelegateCheckpoint[] storage $previousDelegationCheckpoints = $delegateCheckpoints[ + previousDelegation.delegate + ]; uint256 accountCheckpointsLength = $previousDelegationCheckpoints.length; // NOTE: we know that _accountsCheckpointLength > 0 // because we have already checked that the previous delegation exists - IveANGLEVotingDelegation.DelegateCheckpoint memory lastCheckpoint = - $previousDelegationCheckpoints[accountCheckpointsLength - 1]; + IveANGLEVotingDelegation.DelegateCheckpoint memory lastCheckpoint = $previousDelegationCheckpoints[ + accountCheckpointsLength - 1 + ]; uint256 oldWeightOldDelegate = _getVotingWeight(previousDelegation.delegate, checkpointTimestamp); // Handle Expirations @@ -413,8 +433,9 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // See testExpiredLockRedelegateNoVotingWeight(). if (previousDelegation.expiry > checkpointTimestamp) { // Calculations - IveANGLEVotingDelegation.Expiration memory expiration = - $expiredDelegations[previousDelegation.delegate][previousDelegation.expiry]; + IveANGLEVotingDelegation.Expiration memory expiration = $expiredDelegations[ + previousDelegation.delegate + ][previousDelegation.expiry]; // All expiration fields will never exceed their size so subtraction doesnt need to be checked // and they can be unsafely cast unchecked { @@ -452,7 +473,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { emit DelegateVotesChanged({ delegate: previousDelegation.delegate, previousVotes: oldWeightOldDelegate, - newVotes: _getVotingWeight({voter: previousDelegation.delegate, timestamp: checkpointTimestamp}) + newVotes: _getVotingWeight({ voter: previousDelegation.delegate, timestamp: checkpointTimestamp }) }); } } @@ -467,8 +488,9 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { uint256 checkpointTimestamp ) private { // Get the last checkpoint for the new delegate - IveANGLEVotingDelegation.DelegateCheckpoint[] storage $newDelegateCheckpoints = - $delegateCheckpoints[newDelegate]; + IveANGLEVotingDelegation.DelegateCheckpoint[] storage $newDelegateCheckpoints = $delegateCheckpoints[ + newDelegate + ]; uint256 accountCheckpointsLength = $newDelegateCheckpoints.length; IveANGLEVotingDelegation.DelegateCheckpoint memory lastCheckpoint = accountCheckpointsLength == 0 ? IveANGLEVotingDelegation.DelegateCheckpoint(0, 0, 0) @@ -477,8 +499,9 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { // Handle expiration // Calculations - IveANGLEVotingDelegation.Expiration memory expiration = - $expiredDelegations[newDelegate][delegatorVeANGLELockInfo.expiry]; + IveANGLEVotingDelegation.Expiration memory expiration = $expiredDelegations[newDelegate][ + delegatorVeANGLELockInfo.expiry + ]; // NOTE: All expiration fields will never exceed their size so addition doesnt need to be checked // and can be unsafely cast @@ -513,7 +536,7 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { emit DelegateVotesChanged({ delegate: newDelegate, previousVotes: oldWeightNewDelegate, - newVotes: _getVotingWeight({voter: newDelegate, timestamp: checkpointTimestamp}) + newVotes: _getVotingWeight({ voter: newDelegate, timestamp: checkpointTimestamp }) }); } @@ -537,12 +560,13 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { ) private view returns (IveANGLEVotingDelegation.DelegateCheckpoint memory newCheckpoint) { // If this is the first checkpoint, create a new one and early return if (previousCheckpoint.timestamp == 0) { - return IveANGLEVotingDelegation.DelegateCheckpoint({ - // can be unsafely cast because values will never exceed uint128 max - timestamp: uint128(checkpointTimestamp), - normalizedBias: uint128(deltaBias), - normalizedSlope: uint128(deltaSlope) - }); + return + IveANGLEVotingDelegation.DelegateCheckpoint({ + // can be unsafely cast because values will never exceed uint128 max + timestamp: uint128(checkpointTimestamp), + normalizedBias: uint128(deltaBias), + normalizedSlope: uint128(deltaSlope) + }); } newCheckpoint.timestamp = previousCheckpoint.timestamp; @@ -622,8 +646,8 @@ contract VeANGLEVotingDelegation is EIP712, IERC5805 { } else { // Total values will always be less than or equal to a checkpoint's values uint256 currentWeek = WEEK + (start / WEEK) * WEEK; - mapping(uint256 => IveANGLEVotingDelegation.Expiration) storage $delegateExpirations = - $expiredDelegations[account]; + mapping(uint256 => IveANGLEVotingDelegation.Expiration) + storage $delegateExpirations = $expiredDelegations[account]; // Sum values from currentWeek until end while (currentWeek <= end) { IveANGLEVotingDelegation.Expiration memory expiration = $delegateExpirations[currentWeek]; diff --git a/contracts/external/GovernorCountingFractional.sol b/contracts/external/GovernorCountingFractional.sol index 7d26af3..66288cf 100644 --- a/contracts/external/GovernorCountingFractional.sol +++ b/contracts/external/GovernorCountingFractional.sol @@ -2,9 +2,9 @@ pragma solidity ^0.8.20; -import {Governor} from "oz-v5/governance/Governor.sol"; -import {GovernorCountingSimple} from "oz-v5/governance/extensions/GovernorCountingSimple.sol"; -import {SafeCast} from "oz-v5/utils/math/SafeCast.sol"; +import { Governor } from "oz-v5/governance/Governor.sol"; +import { GovernorCountingSimple } from "oz-v5/governance/extensions/GovernorCountingSimple.sol"; +import { SafeCast } from "oz-v5/utils/math/SafeCast.sol"; import "../utils/Errors.sol"; @@ -64,12 +64,9 @@ abstract contract GovernorCountingFractional is Governor { /** * @dev Accessor to the internal vote counts. */ - function proposalVotes(uint256 proposalId) - public - view - virtual - returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) - { + function proposalVotes( + uint256 proposalId + ) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) { ProposalVote storage proposalVote = _proposalVotes[proposalId]; return (proposalVote.againstVotes, proposalVote.forVotes, proposalVote.abstainVotes); } @@ -112,11 +109,13 @@ abstract contract GovernorCountingFractional is Governor { * * See `_countVoteNominal` and `_countVoteFractional` for more details. */ - function _countVote(uint256 proposalId, address account, uint8 support, uint256 totalWeight, bytes memory voteData) - internal - virtual - override - { + function _countVote( + uint256 proposalId, + address account, + uint8 support, + uint256 totalWeight, + bytes memory voteData + ) internal virtual override { if (totalWeight == 0) revert GovernorCountingFractionalNoWeight(); if (_proposalVotersWeightCast[proposalId][account] >= totalWeight) { revert GovernorCountingFractionalAllWeightCast(); @@ -177,9 +176,12 @@ abstract contract GovernorCountingFractional is Governor { * Note that if partial votes are cast, all remaining weight must be cast * with _countVoteFractional: _countVoteNominal will revert. */ - function _countVoteFractional(uint256 proposalId, address account, uint128 totalWeight, bytes memory voteData) - internal - { + function _countVoteFractional( + uint256 proposalId, + address account, + uint128 totalWeight, + bytes memory voteData + ) internal { if (voteData.length != 48) revert GovernorCountingFractionalInvalidVoteData(); (uint128 _againstVotes, uint128 _forVotes, uint128 _abstainVotes) = _decodePackedVotes(voteData); @@ -210,11 +212,9 @@ abstract contract GovernorCountingFractional is Governor { * language limitation which prevents slicing bytes stored in memory, rather * than calldata. */ - function _decodePackedVotes(bytes memory voteData) - internal - pure - returns (uint128 againstVotes, uint128 forVotes, uint128 abstainVotes) - { + function _decodePackedVotes( + bytes memory voteData + ) internal pure returns (uint128 againstVotes, uint128 forVotes, uint128 abstainVotes) { assembly { againstVotes := shr(128, mload(add(voteData, 0x20))) forVotes := and(_VOTEMASK, mload(add(voteData, 0x20))) diff --git a/contracts/external/GovernorShortCircuit.sol b/contracts/external/GovernorShortCircuit.sol index 985deee..d592bb5 100644 --- a/contracts/external/GovernorShortCircuit.sol +++ b/contracts/external/GovernorShortCircuit.sol @@ -2,11 +2,11 @@ pragma solidity ^0.8.20; -import {Checkpoints} from "oz-v5/utils/structs/Checkpoints.sol"; -import {IERC5805} from "oz-v5/interfaces/IERC5805.sol"; -import {GovernorVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {GovernorVotesQuorumFraction} from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; -import {GovernorCountingFractional, SafeCast} from "./GovernorCountingFractional.sol"; +import { Checkpoints } from "oz-v5/utils/structs/Checkpoints.sol"; +import { IERC5805 } from "oz-v5/interfaces/IERC5805.sol"; +import { GovernorVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { GovernorVotesQuorumFraction } from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; +import { GovernorCountingFractional, SafeCast } from "./GovernorCountingFractional.sol"; import "../utils/Errors.sol"; @@ -83,8 +83,9 @@ abstract contract GovernorShortCircuit is GovernorVotes, GovernorCountingFractio } // Otherwise, do the binary search - shortCircuitNumeratorAtTimepoint = - _$shortCircuitNumeratorHistory.upperLookupRecent(SafeCast.toUint32(timepoint)); + shortCircuitNumeratorAtTimepoint = _$shortCircuitNumeratorHistory.upperLookupRecent( + SafeCast.toUint32(timepoint) + ); } /// @notice Returns the latest short circuit numerator @@ -96,7 +97,8 @@ abstract contract GovernorShortCircuit is GovernorVotes, GovernorCountingFractio if (snapshotBlockNumber == 0 || snapshotBlockNumber >= block.number) revert InvalidTimepoint(); shortCircuitThresholdAtTimepoint = - (token().getPastTotalSupply(snapshotBlockNumber) * shortCircuitNumerator(timepoint)) / quorumDenominator(); + (token().getPastTotalSupply(snapshotBlockNumber) * shortCircuitNumerator(timepoint)) / + quorumDenominator(); } /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -121,12 +123,10 @@ abstract contract GovernorShortCircuit is GovernorVotes, GovernorCountingFractio /// @param proposalId Proposal ID /// @return isShortCircuitFor Represents if short circuit threshold for votes were reached or not /// @return isShortCircuitAgainst Represents if short circuit threshold against votes were reached or not - function _shortCircuit(uint256 proposalId) - internal - view - returns (bool isShortCircuitFor, bool isShortCircuitAgainst) - { - (uint256 againstVoteWeight, uint256 forVoteWeight,) = proposalVotes(proposalId); + function _shortCircuit( + uint256 proposalId + ) internal view returns (bool isShortCircuitFor, bool isShortCircuitAgainst) { + (uint256 againstVoteWeight, uint256 forVoteWeight, ) = proposalVotes(proposalId); uint256 proposalVoteStart = proposalSnapshot(proposalId); uint256 shortCircuitThresholdValue = shortCircuitThreshold(proposalVoteStart); @@ -160,6 +160,9 @@ abstract contract GovernorShortCircuit is GovernorVotes, GovernorCountingFractio function _setVotingDelayBlocks(uint256 votingDelayBlocks) internal { uint256 oldVotingDelayBlocks = $votingDelayBlocks; $votingDelayBlocks = votingDelayBlocks; - emit VotingDelayBlocksSet({oldVotingDelayBlocks: oldVotingDelayBlocks, newVotingDelayBlocks: votingDelayBlocks}); + emit VotingDelayBlocksSet({ + oldVotingDelayBlocks: oldVotingDelayBlocks, + newVotingDelayBlocks: votingDelayBlocks + }); } } diff --git a/scripts/Constants.s.sol b/scripts/Constants.s.sol index 1ad7eab..a58a671 100644 --- a/scripts/Constants.s.sol +++ b/scripts/Constants.s.sol @@ -2,16 +2,16 @@ pragma solidity ^0.8.9; -import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {ITransmuter} from "transmuter/interfaces/ITransmuter.sol"; -import {IAgToken} from "borrow/interfaces/IAgToken.sol"; -import {ProxyAdmin} from "oz-v5/proxy/transparent/ProxyAdmin.sol"; -import {Ownable} from "oz-v5/access/Ownable.sol"; -import {CoreBorrow} from "borrow/coreBorrow/CoreBorrow.sol"; -import {ITreasury} from "borrow/interfaces/ITreasury.sol"; -import {TimelockController} from "oz-v5/governance/TimelockController.sol"; -import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { ITransmuter } from "transmuter/interfaces/ITransmuter.sol"; +import { IAgToken } from "borrow/interfaces/IAgToken.sol"; +import { ProxyAdmin } from "oz-v5/proxy/transparent/ProxyAdmin.sol"; +import { Ownable } from "oz-v5/access/Ownable.sol"; +import { CoreBorrow } from "borrow/coreBorrow/CoreBorrow.sol"; +import { ITreasury } from "borrow/interfaces/ITreasury.sol"; +import { TimelockController } from "oz-v5/governance/TimelockController.sol"; +import { AngleGovernor } from "contracts/AngleGovernor.sol"; import "utils/src/Constants.sol"; import "./Interfaces.s.sol"; diff --git a/scripts/Interfaces.s.sol b/scripts/Interfaces.s.sol index 44f8574..a03e311 100644 --- a/scripts/Interfaces.s.sol +++ b/scripts/Interfaces.s.sol @@ -1,7 +1,7 @@ pragma solidity ^0.8.19; -import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; -import {IAccessControlManager} from "interfaces/IAccessControlManager.sol"; +import { IAccessControl } from "oz-v5/access/IAccessControl.sol"; +import { IAccessControlManager } from "interfaces/IAccessControlManager.sol"; interface IAccessControlCore { function core() external returns (address); diff --git a/scripts/Utils.s.sol b/scripts/Utils.s.sol index 59bde27..42b68f7 100644 --- a/scripts/Utils.s.sol +++ b/scripts/Utils.s.sol @@ -2,12 +2,12 @@ pragma solidity ^0.8.19; import "forge-std/Script.sol"; -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; -import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; -import {ITreasury} from "borrow/interfaces/ITreasury.sol"; +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; +import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import { ITreasury } from "borrow/interfaces/ITreasury.sol"; import "utils/src/CommonUtils.sol"; import "./Constants.s.sol"; diff --git a/scripts/deployment/DeployOnChainGovernance.s.sol b/scripts/deployment/DeployOnChainGovernance.s.sol index 7f6d2c7..fc142ba 100644 --- a/scripts/deployment/DeployOnChainGovernance.s.sol +++ b/scripts/deployment/DeployOnChainGovernance.s.sol @@ -1,23 +1,23 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import {console} from "forge-std/console.sol"; -import {stdJson} from "forge-std/StdJson.sol"; +import { console } from "forge-std/console.sol"; +import { stdJson } from "forge-std/StdJson.sol"; import "stringutils/strings.sol"; import "../Utils.s.sol"; import "oz-v5/interfaces/IERC20.sol"; -import {IveANGLEVotingDelegation} from "contracts/interfaces/IveANGLEVotingDelegation.sol"; -import {deployMockANGLE, deployVeANGLE} from "../test/DeployANGLE.s.sol"; -import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; +import { IveANGLEVotingDelegation } from "contracts/interfaces/IveANGLEVotingDelegation.sol"; +import { deployMockANGLE, deployVeANGLE } from "../test/DeployANGLE.s.sol"; +import { ERC20 } from "oz-v5/token/ERC20/ERC20.sol"; import "contracts/interfaces/IveANGLE.sol"; import "../../test/external/VyperDeployer.sol"; -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; -import {VeANGLEVotingDelegation, ECDSA} from "contracts/VeANGLEVotingDelegation.sol"; +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; +import { VeANGLEVotingDelegation, ECDSA } from "contracts/VeANGLEVotingDelegation.sol"; /// @dev To deploy on a different chain, just replace the import of the `Constants.s.sol` file by a file which has the /// constants defined for the chain of your choice. diff --git a/scripts/deployment/DeploySideChainGovernance.s.sol b/scripts/deployment/DeploySideChainGovernance.s.sol index ab21196..1cce3c9 100644 --- a/scripts/deployment/DeploySideChainGovernance.s.sol +++ b/scripts/deployment/DeploySideChainGovernance.s.sol @@ -1,17 +1,17 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import {console} from "forge-std/console.sol"; -import {stdJson} from "forge-std/StdJson.sol"; +import { console } from "forge-std/console.sol"; +import { stdJson } from "forge-std/StdJson.sol"; import "stringutils/strings.sol"; import "../Utils.s.sol"; import "oz-v5/interfaces/IERC20.sol"; -import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; -import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; +import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; +import { ERC20 } from "oz-v5/token/ERC20/ERC20.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; /// @dev To deploy on a different chain, just replace the import of the `Constants.s.sol` file by a file which has the /// constants defined for the chain of your choice. diff --git a/scripts/interaction/CheckRoles.s.sol b/scripts/interaction/CheckRoles.s.sol index d30cdc2..60aa7aa 100644 --- a/scripts/interaction/CheckRoles.s.sol +++ b/scripts/interaction/CheckRoles.s.sol @@ -1,16 +1,16 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import {console} from "forge-std/console.sol"; -import {IVaultManager} from "borrow/interfaces/IVaultManager.sol"; -import {ITreasury} from "borrow/interfaces/ITreasury.sol"; -import {IAgToken} from "borrow/interfaces/IAgToken.sol"; -import {IERC721Metadata} from "oz-v5/token/ERC721/extensions/IERC721Metadata.sol"; -import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; -import {Utils} from "../Utils.s.sol"; +import { console } from "forge-std/console.sol"; +import { IVaultManager } from "borrow/interfaces/IVaultManager.sol"; +import { ITreasury } from "borrow/interfaces/ITreasury.sol"; +import { IAgToken } from "borrow/interfaces/IAgToken.sol"; +import { IERC721Metadata } from "oz-v5/token/ERC721/extensions/IERC721Metadata.sol"; +import { IAccessControl } from "oz-v5/access/IAccessControl.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; +import { Utils } from "../Utils.s.sol"; import "../Constants.s.sol"; import "stringutils/strings.sol"; @@ -108,16 +108,20 @@ contract CheckRoles is Utils { ITransmuter transmuterEUR = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); ITransmuter transmuterUSD = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgUSD)); IAngle angle = IAngle(_chainToContract(chainId, ContractType.Angle)); - ProposalSender proposalSender = - ProposalSender(payable(_chainToContract(chainId, ContractType.ProposalSender))); - IGaugeController gaugeController = - IGaugeController(_chainToContract(chainId, ContractType.GaugeController)); - ISmartWalletWhitelist smartWalletWhitelist = - ISmartWalletWhitelist(_chainToContract(chainId, ContractType.SmartWalletWhitelist)); + ProposalSender proposalSender = ProposalSender( + payable(_chainToContract(chainId, ContractType.ProposalSender)) + ); + IGaugeController gaugeController = IGaugeController( + _chainToContract(chainId, ContractType.GaugeController) + ); + ISmartWalletWhitelist smartWalletWhitelist = ISmartWalletWhitelist( + _chainToContract(chainId, ContractType.SmartWalletWhitelist) + ); IVeAngle veAngle = IVeAngle(_chainToContract(chainId, ContractType.veANGLE)); IVeBoostProxy veBoostProxy = IVeBoostProxy(_chainToContract(chainId, ContractType.veBoostProxy)); - IGenericAccessControl merklMiddleman = - IGenericAccessControl(_chainToContract(chainId, ContractType.MerklMiddleman)); + IGenericAccessControl merklMiddleman = IGenericAccessControl( + _chainToContract(chainId, ContractType.MerklMiddleman) + ); if (!_authorizedCore(chainId, address(transmuterEUR.accessControlManager()))) { output = vm.serializeString( @@ -181,7 +185,8 @@ contract CheckRoles is Utils { json, vm.toString(jsonIndex), string.concat( - "Gauge Controller - future admin role: ", vm.toString(gaugeController.future_admin()) + "Gauge Controller - future admin role: ", + vm.toString(gaugeController.future_admin()) ) ); jsonIndex++; @@ -199,14 +204,17 @@ contract CheckRoles is Utils { json, vm.toString(jsonIndex), string.concat( - "Smart Wallet Whitelist - future admin: ", vm.toString(smartWalletWhitelist.future_admin()) + "Smart Wallet Whitelist - future admin: ", + vm.toString(smartWalletWhitelist.future_admin()) ) ); jsonIndex++; } if (!_authorizedOwner(chainId, veAngle.admin())) { output = vm.serializeString( - json, vm.toString(jsonIndex), string.concat("veANGLE - admin: ", vm.toString(veAngle.admin())) + json, + vm.toString(jsonIndex), + string.concat("veANGLE - admin: ", vm.toString(veAngle.admin())) ); jsonIndex++; } @@ -235,8 +243,9 @@ contract CheckRoles is Utils { jsonIndex++; } } else { - ProposalReceiver proposalReceiver = - ProposalReceiver(payable(_chainToContract(chainId, ContractType.ProposalReceiver))); + ProposalReceiver proposalReceiver = ProposalReceiver( + payable(_chainToContract(chainId, ContractType.ProposalReceiver)) + ); if (!_authorizedOwner(chainId, proposalReceiver.owner())) { output = vm.serializeString( json, @@ -248,7 +257,9 @@ contract CheckRoles is Utils { } if (_isCoreChain(chainId)) { - IAccessControlCore angleRouter = IAccessControlCore(_chainToContract(chainId, ContractType.AngleRouter)); + IAccessControlCore angleRouter = IAccessControlCore( + _chainToContract(chainId, ContractType.AngleRouter) + ); if (!_authorizedCore(chainId, angleRouter.core())) { output = vm.serializeString( json, @@ -270,9 +281,12 @@ contract CheckRoles is Utils { } if (_isMerklDeployed(chainId)) { - IAccessControlCore distributionCreator = - IAccessControlCore(_chainToContract(chainId, ContractType.DistributionCreator)); - IAccessControlCore distributor = IAccessControlCore(_chainToContract(chainId, ContractType.Distributor)); + IAccessControlCore distributionCreator = IAccessControlCore( + _chainToContract(chainId, ContractType.DistributionCreator) + ); + IAccessControlCore distributor = IAccessControlCore( + _chainToContract(chainId, ContractType.Distributor) + ); if (!_authorizedCoreMerkl(chainId, address(distributionCreator.core()))) { output = vm.serializeString( json, @@ -299,7 +313,8 @@ contract CheckRoles is Utils { json, vm.toString(jsonIndex), string.concat( - "StEUR - wrong access control manager: ", vm.toString(stEUR.accessControlManager()) + "StEUR - wrong access control manager: ", + vm.toString(stEUR.accessControlManager()) ) ); jsonIndex++; @@ -309,7 +324,8 @@ contract CheckRoles is Utils { json, vm.toString(jsonIndex), string.concat( - "StUSD - wrong access control manager: ", vm.toString(stUSD.accessControlManager()) + "StUSD - wrong access control manager: ", + vm.toString(stUSD.accessControlManager()) ) ); jsonIndex++; @@ -354,8 +370,9 @@ contract CheckRoles is Utils { IAgToken agEUR = IAgToken(_chainToContract(chainId, ContractType.AgEUR)); IAgToken agUSD = IAgToken(_chainToContract(chainId, ContractType.AgUSD)); CoreBorrow core = CoreBorrow(_chainToContract(chainId, ContractType.CoreBorrow)); - TimelockControllerWithCounter timelock = - TimelockControllerWithCounter(payable(_chainToContract(chainId, ContractType.Timelock))); + TimelockControllerWithCounter timelock = TimelockControllerWithCounter( + payable(_chainToContract(chainId, ContractType.Timelock)) + ); for (uint256 i = 0; i < listAddressToCheck.length; i++) { outputActor = ""; jsonActor = vm.toString(listAddressToCheck[i]); @@ -378,7 +395,11 @@ contract CheckRoles is Utils { jsonActorIndex++; } if (core.hasRole(FLASHLOANER_TREASURY_ROLE, actor) && !_authorizedFlashloaner(chainId, actor)) { - outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Borrow - flashloan role"); + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + "Core Borrow - flashloan role" + ); jsonActorIndex++; } if (timelock.hasRole(PROPOSER_ROLE, actor) && !_authorizedProposer(chainId, actor)) { @@ -394,8 +415,11 @@ contract CheckRoles is Utils { jsonActorIndex++; } if (timelock.hasRole(DEFAULT_ADMIN_ROLE, actor) && !_authorizeDefaultAdmin(chainId, actor)) { - outputActor = - vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Timelock - default admin role"); + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + "Timelock - default admin role" + ); jsonActorIndex++; } @@ -408,34 +432,50 @@ contract CheckRoles is Utils { if (_isMerklDeployed(chainId)) { CoreBorrow coreMerkl = CoreBorrow(_chainToContract(chainId, ContractType.CoreMerkl)); if (coreMerkl.hasRole(GOVERNOR_ROLE, actor) && !_authorizedGovernor(chainId, actor)) { - outputActor = - vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Merkl - governor role"); + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + "Core Merkl - governor role" + ); jsonActorIndex++; } if (coreMerkl.hasRole(GUARDIAN_ROLE, actor) && !_authorizedGuardian(chainId, actor)) { - outputActor = - vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Merkl - guardian role"); + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + "Core Merkl - guardian role" + ); jsonActorIndex++; } // No one should have this role if (coreMerkl.hasRole(FLASHLOANER_TREASURY_ROLE, actor)) { - outputActor = - vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Merkl - flashloan role"); + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + "Core Merkl - flashloan role" + ); jsonActorIndex++; } } if (chainId == CHAIN_ETHEREUM) { - IAccessControl angleDistributor = - IAccessControl(_chainToContract(chainId, ContractType.AngleDistributor)); + IAccessControl angleDistributor = IAccessControl( + _chainToContract(chainId, ContractType.AngleDistributor) + ); if (angleDistributor.hasRole(GOVERNOR_ROLE, actor) && !_authorizedGovernor(chainId, actor)) { - outputActor = - vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Angle distributor - governor role"); + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + "Angle distributor - governor role" + ); jsonActorIndex++; } if (angleDistributor.hasRole(GUARDIAN_ROLE, actor) && !_authorizedGuardian(chainId, actor)) { - outputActor = - vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Angle distributor - guardian role"); + outputActor = vm.serializeString( + jsonActor, + vm.toString(jsonActorIndex), + "Angle distributor - guardian role" + ); jsonActorIndex++; } } @@ -590,9 +630,11 @@ contract CheckRoles is Utils { } catch {} } - function _checkAddressAccessControl(uint256 chainId, IGenericAccessControl contractToCheck, address addressToCheck) - public - { + function _checkAddressAccessControl( + uint256 chainId, + IGenericAccessControl contractToCheck, + address addressToCheck + ) public { try contractToCheck.isMinter(addressToCheck) returns (bool isMinter) { if (isMinter && !_authorizedMinter(chainId, addressToCheck)) { outputActor = vm.serializeString( @@ -683,27 +725,54 @@ contract CheckRoles is Utils { } function _isCoreChain(uint256 chainId) internal pure returns (bool) { - return chainId == CHAIN_ETHEREUM || chainId == CHAIN_ARBITRUM || chainId == CHAIN_AVALANCHE - || chainId == CHAIN_OPTIMISM || chainId == CHAIN_POLYGON || chainId == CHAIN_GNOSIS; + return + chainId == CHAIN_ETHEREUM || + chainId == CHAIN_ARBITRUM || + chainId == CHAIN_AVALANCHE || + chainId == CHAIN_OPTIMISM || + chainId == CHAIN_POLYGON || + chainId == CHAIN_GNOSIS; } function _isAngleDeployed(uint256 chainId) internal pure returns (bool) { - return chainId == CHAIN_ETHEREUM || chainId == CHAIN_ARBITRUM || chainId == CHAIN_AURORA - || chainId == CHAIN_AVALANCHE || chainId == CHAIN_BNB || chainId == CHAIN_FANTOM || chainId == CHAIN_OPTIMISM - || chainId == CHAIN_POLYGON; + return + chainId == CHAIN_ETHEREUM || + chainId == CHAIN_ARBITRUM || + chainId == CHAIN_AURORA || + chainId == CHAIN_AVALANCHE || + chainId == CHAIN_BNB || + chainId == CHAIN_FANTOM || + chainId == CHAIN_OPTIMISM || + chainId == CHAIN_POLYGON; } function _isMerklDeployed(uint256 chainId) internal pure returns (bool) { - return chainId == CHAIN_ETHEREUM || chainId == CHAIN_ARBITRUM || chainId == CHAIN_AVALANCHE - || chainId == CHAIN_BASE || chainId == CHAIN_BNB || chainId == CHAIN_GNOSIS || chainId == CHAIN_LINEA - || chainId == CHAIN_MANTLE || chainId == CHAIN_OPTIMISM || chainId == CHAIN_POLYGON - || chainId == CHAIN_POLYGONZKEVM; + return + chainId == CHAIN_ETHEREUM || + chainId == CHAIN_ARBITRUM || + chainId == CHAIN_AVALANCHE || + chainId == CHAIN_BASE || + chainId == CHAIN_BNB || + chainId == CHAIN_GNOSIS || + chainId == CHAIN_LINEA || + chainId == CHAIN_MANTLE || + chainId == CHAIN_OPTIMISM || + chainId == CHAIN_POLYGON || + chainId == CHAIN_POLYGONZKEVM; } function _isSavingsDeployed(uint256 chainId) internal pure returns (bool) { - return chainId == CHAIN_ETHEREUM || chainId == CHAIN_ARBITRUM || chainId == CHAIN_AVALANCHE - || chainId == CHAIN_BASE || chainId == CHAIN_BNB || chainId == CHAIN_CELO || chainId == CHAIN_GNOSIS - || chainId == CHAIN_OPTIMISM || chainId == CHAIN_POLYGON || chainId == CHAIN_POLYGONZKEVM; + return + chainId == CHAIN_ETHEREUM || + chainId == CHAIN_ARBITRUM || + chainId == CHAIN_AVALANCHE || + chainId == CHAIN_BASE || + chainId == CHAIN_BNB || + chainId == CHAIN_CELO || + chainId == CHAIN_GNOSIS || + chainId == CHAIN_OPTIMISM || + chainId == CHAIN_POLYGON || + chainId == CHAIN_POLYGONZKEVM; } function _revertOnWrongFunctioCall(uint256 chainId) internal pure returns (bool) { @@ -715,35 +784,43 @@ contract CheckRoles is Utils { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ function _authorizedOwner(uint256 chainId, address owner) internal returns (bool) { - return owner == address(0) || owner == _chainToContract(chainId, ContractType.GovernorMultisig) - // owner == _chainToContract(chainId, ContractType.GuardianMultisig) || - || owner == _chainToContract(chainId, ContractType.Timelock) - || owner == _chainToContract(chainId, ContractType.CoreBorrow) - || owner == _chainToContract(chainId, ContractType.ProxyAdmin) - || ((chainId == CHAIN_SOURCE) ? owner == _chainToContract(chainId, ContractType.Governor) : false); + return + owner == address(0) || + owner == _chainToContract(chainId, ContractType.GovernorMultisig) || + // owner == _chainToContract(chainId, ContractType.GuardianMultisig) || + owner == _chainToContract(chainId, ContractType.Timelock) || + owner == _chainToContract(chainId, ContractType.CoreBorrow) || + owner == _chainToContract(chainId, ContractType.ProxyAdmin) || + ((chainId == CHAIN_SOURCE) ? owner == _chainToContract(chainId, ContractType.Governor) : false); } function _authorizedGovernor(uint256 chainId, address governor) internal returns (bool) { - return governor == address(0) || governor == _chainToContract(chainId, ContractType.GovernorMultisig) - || governor == _chainToContract(chainId, ContractType.Timelock) - || governor == _chainToContract(chainId, ContractType.CoreBorrow) - || governor == _chainToContract(chainId, ContractType.ProxyAdmin) - || ((chainId == CHAIN_SOURCE) ? governor == _chainToContract(chainId, ContractType.Governor) : false); + return + governor == address(0) || + governor == _chainToContract(chainId, ContractType.GovernorMultisig) || + governor == _chainToContract(chainId, ContractType.Timelock) || + governor == _chainToContract(chainId, ContractType.CoreBorrow) || + governor == _chainToContract(chainId, ContractType.ProxyAdmin) || + ((chainId == CHAIN_SOURCE) ? governor == _chainToContract(chainId, ContractType.Governor) : false); } function _authorizedGuardian(uint256 chainId, address guardian) internal returns (bool) { - return guardian == address(0) || guardian == _chainToContract(chainId, ContractType.GovernorMultisig) - || guardian == _chainToContract(chainId, ContractType.GuardianMultisig) - || guardian == _chainToContract(chainId, ContractType.Timelock) - || guardian == _chainToContract(chainId, ContractType.CoreBorrow) - || guardian == _chainToContract(chainId, ContractType.ProxyAdmin) - || ((chainId == CHAIN_SOURCE) ? guardian == _chainToContract(chainId, ContractType.Governor) : false); + return + guardian == address(0) || + guardian == _chainToContract(chainId, ContractType.GovernorMultisig) || + guardian == _chainToContract(chainId, ContractType.GuardianMultisig) || + guardian == _chainToContract(chainId, ContractType.Timelock) || + guardian == _chainToContract(chainId, ContractType.CoreBorrow) || + guardian == _chainToContract(chainId, ContractType.ProxyAdmin) || + ((chainId == CHAIN_SOURCE) ? guardian == _chainToContract(chainId, ContractType.Governor) : false); } /// @notice Vault Managers are also minter function _authorizedMinter(uint256 chainId, address minter) internal returns (bool) { - return minter == address(0) || minter == _chainToContract(chainId, ContractType.GovernorMultisig) - || minter == _chainToContract(chainId, ContractType.Timelock); + return + minter == address(0) || + minter == _chainToContract(chainId, ContractType.GovernorMultisig) || + minter == _chainToContract(chainId, ContractType.Timelock); } function _authorizedCore(uint256 chainId, address core) internal returns (bool) { @@ -757,14 +834,17 @@ contract CheckRoles is Utils { // TODO need to be fine grained for multiple stablecoins function _authorizedFlashloaner(uint256 chainId, address loaner) internal returns (bool) { - return loaner == address(0) || loaner == _chainToContract(chainId, ContractType.TreasuryAgEUR) - || loaner == _chainToContract(chainId, ContractType.TreasuryAgUSD); + return + loaner == address(0) || + loaner == _chainToContract(chainId, ContractType.TreasuryAgEUR) || + loaner == _chainToContract(chainId, ContractType.TreasuryAgUSD); } function _authorizedProposer(uint256 chainId, address proposer) internal returns (bool) { - return (chainId == CHAIN_SOURCE) - ? proposer == _chainToContract(chainId, ContractType.Governor) - : proposer == _chainToContract(chainId, ContractType.ProposalReceiver); + return + (chainId == CHAIN_SOURCE) + ? proposer == _chainToContract(chainId, ContractType.Governor) + : proposer == _chainToContract(chainId, ContractType.ProposalReceiver); } function _authorizedExecutor(uint256 chainId, address executor) internal returns (bool) { @@ -793,23 +873,25 @@ contract CheckRoles is Utils { } function _authorizedTrusted(uint256 chainId, address trusted) internal returns (bool) { - return trusted == _chainToContract(chainId, ContractType.GovernorMultisig) - || trusted == _chainToContract(chainId, ContractType.GuardianMultisig) - || trusted == _chainToContract(chainId, ContractType.Timelock) - || trusted == _chainToContract(chainId, ContractType.CoreBorrow) - || trusted == _chainToContract(chainId, ContractType.ProxyAdmin) - // trusted == oldDeployer || - // trusted == oldKeeper || - // trusted == oldKeeperPolygon || - // trusted == oldKeeperPolygon2 || - // trusted == merklKeeper || - || ((chainId == CHAIN_SOURCE) ? trusted == _chainToContract(chainId, ContractType.Governor) : false); + return + trusted == _chainToContract(chainId, ContractType.GovernorMultisig) || + trusted == _chainToContract(chainId, ContractType.GuardianMultisig) || + trusted == _chainToContract(chainId, ContractType.Timelock) || + trusted == _chainToContract(chainId, ContractType.CoreBorrow) || + trusted == _chainToContract(chainId, ContractType.ProxyAdmin) || + // trusted == oldDeployer || + // trusted == oldKeeper || + // trusted == oldKeeperPolygon || + // trusted == oldKeeperPolygon2 || + // trusted == merklKeeper || + ((chainId == CHAIN_SOURCE) ? trusted == _chainToContract(chainId, ContractType.Governor) : false); } function _authorizedDistributor(uint256 chainId, address distributor) internal returns (bool) { - return (chainId == CHAIN_ETHEREUM) - ? distributor == _chainToContract(chainId, ContractType.AngleDistributor) - : false; + return + (chainId == CHAIN_ETHEREUM) + ? distributor == _chainToContract(chainId, ContractType.AngleDistributor) + : false; } function _authorizedProxyAdminOwner(uint256 chainId, address owner) internal returns (bool) { @@ -817,7 +899,8 @@ contract CheckRoles is Utils { } function _authorizedTreasury(uint256 chainId, address treasury) internal returns (bool) { - return treasury == _chainToContract(chainId, ContractType.TreasuryAgEUR) - || treasury == _chainToContract(chainId, ContractType.TreasuryAgUSD); + return + treasury == _chainToContract(chainId, ContractType.TreasuryAgEUR) || + treasury == _chainToContract(chainId, ContractType.TreasuryAgUSD); } } diff --git a/scripts/interfaces/ITransmuter.sol b/scripts/interfaces/ITransmuter.sol index 867505f..aa2f888 100644 --- a/scripts/interfaces/ITransmuter.sol +++ b/scripts/interfaces/ITransmuter.sol @@ -5,8 +5,7 @@ pragma solidity ^0.8.19; import "transmuter/transmuter/Storage.sol" as Storage; interface OldTransmuter { - function getOracle(address) - external - view - returns (Storage.OracleReadType, Storage.OracleReadType, bytes memory, bytes memory); + function getOracle( + address + ) external view returns (Storage.OracleReadType, Storage.OracleReadType, bytes memory, bytes memory); } diff --git a/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol b/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol index 72db6f0..1f9deda 100644 --- a/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol +++ b/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol @@ -1,10 +1,10 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.20; -import {console} from "forge-std/console.sol"; -import {Wrapper} from "../Wrapper.s.sol"; -import {GovernorVotesQuorumFraction} from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; -import {GovernorShortCircuit} from "contracts/external/GovernorShortCircuit.sol"; +import { console } from "forge-std/console.sol"; +import { Wrapper } from "../Wrapper.s.sol"; +import { GovernorVotesQuorumFraction } from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; +import { GovernorShortCircuit } from "contracts/external/GovernorShortCircuit.sol"; import "../../Constants.s.sol"; contract IncreaseQuorum is Wrapper { @@ -55,8 +55,12 @@ contract IncreaseQuorum is Wrapper { _setQuorumShortCircuit(chainIds[i], quorumShortCircuit); } - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas, uint256[] memory chainIds2) = - _wrap(subCalls); + ( + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + uint256[] memory chainIds2 + ) = _wrap(subCalls); _serializeJson(targets, values, calldatas, chainIds2, description); } } diff --git a/scripts/proposals/timelock/AddExecutor.s.sol b/scripts/proposals/timelock/AddExecutor.s.sol index 4e3be01..4f66bfd 100644 --- a/scripts/proposals/timelock/AddExecutor.s.sol +++ b/scripts/proposals/timelock/AddExecutor.s.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.20; -import {console} from "forge-std/console.sol"; -import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; -import {Wrapper} from "../Wrapper.s.sol"; +import { console } from "forge-std/console.sol"; +import { IAccessControl } from "oz-v5/access/IAccessControl.sol"; +import { Wrapper } from "../Wrapper.s.sol"; import "../../Constants.s.sol"; contract AddExecutor is Wrapper { @@ -16,7 +16,10 @@ contract AddExecutor is Wrapper { bytes32 EXECUTOR_ROLE = TimelockController(payable(timelock)).EXECUTOR_ROLE(); subCalls.push( SubCall( - chainId, timelock, 0, abi.encodeWithSelector(IAccessControl.grantRole.selector, EXECUTOR_ROLE, executor) + chainId, + timelock, + 0, + abi.encodeWithSelector(IAccessControl.grantRole.selector, EXECUTOR_ROLE, executor) ) ); } @@ -36,8 +39,12 @@ contract AddExecutor is Wrapper { _addExecutorRole(chainIds[i], executor); } - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas, uint256[] memory chainIds2) = - _wrap(subCalls); + ( + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + uint256[] memory chainIds2 + ) = _wrap(subCalls); _serializeJson(targets, values, calldatas, chainIds2, description); } } diff --git a/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol index 22f927e..905ff38 100644 --- a/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol +++ b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol @@ -1,26 +1,26 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.20; -import {console} from "forge-std/console.sol"; -import {stdJson} from "forge-std/StdJson.sol"; -import {Wrapper} from "../Wrapper.s.sol"; -import {TransmuterUtils} from "./TransmuterUtils.s.sol"; +import { console } from "forge-std/console.sol"; +import { stdJson } from "forge-std/StdJson.sol"; +import { Wrapper } from "../Wrapper.s.sol"; +import { TransmuterUtils } from "./TransmuterUtils.s.sol"; import "../../Constants.s.sol"; -import {OldTransmuter} from "../../interfaces/ITransmuter.sol"; +import { OldTransmuter } from "../../interfaces/ITransmuter.sol"; -import {IERC20} from "oz-v5/token/ERC20/IERC20.sol"; +import { IERC20 } from "oz-v5/token/ERC20/IERC20.sol"; import "transmuter/transmuter/Storage.sol" as Storage; -import {DiamondCut} from "transmuter/transmuter/facets/DiamondCut.sol"; -import {DiamondEtherscan} from "transmuter/transmuter/facets/DiamondEtherscan.sol"; -import {DiamondLoupe} from "transmuter/transmuter/facets/DiamondLoupe.sol"; -import {DiamondProxy} from "transmuter/transmuter/DiamondProxy.sol"; -import {Getters} from "transmuter/transmuter/facets/Getters.sol"; -import {Redeemer} from "transmuter/transmuter/facets/Redeemer.sol"; -import {RewardHandler} from "transmuter/transmuter/facets/RewardHandler.sol"; -import {SettersGovernor} from "transmuter/transmuter/facets/SettersGovernor.sol"; -import {SettersGuardian} from "transmuter/transmuter/facets/SettersGuardian.sol"; -import {Swapper} from "transmuter/transmuter/facets/Swapper.sol"; -import {ITransmuter, IDiamondCut, ISettersGovernor} from "transmuter/interfaces/ITransmuter.sol"; +import { DiamondCut } from "transmuter/transmuter/facets/DiamondCut.sol"; +import { DiamondEtherscan } from "transmuter/transmuter/facets/DiamondEtherscan.sol"; +import { DiamondLoupe } from "transmuter/transmuter/facets/DiamondLoupe.sol"; +import { DiamondProxy } from "transmuter/transmuter/DiamondProxy.sol"; +import { Getters } from "transmuter/transmuter/facets/Getters.sol"; +import { Redeemer } from "transmuter/transmuter/facets/Redeemer.sol"; +import { RewardHandler } from "transmuter/transmuter/facets/RewardHandler.sol"; +import { SettersGovernor } from "transmuter/transmuter/facets/SettersGovernor.sol"; +import { SettersGuardian } from "transmuter/transmuter/facets/SettersGuardian.sol"; +import { Swapper } from "transmuter/transmuter/facets/Swapper.sol"; +import { ITransmuter, IDiamondCut, ISettersGovernor } from "transmuter/interfaces/ITransmuter.sol"; contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { using stdJson for string; @@ -95,7 +95,7 @@ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { facetAddress: addFacetAddressList[i], action: Storage.FacetCutAction.Add, functionSelectors: selectors - }); + }); } } @@ -107,10 +107,10 @@ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { bytes memory targetDataEUROC ) = OldTransmuter(address(transmuter)).getOracle(address(EUROC)); - (Storage.OracleReadType oracleTypeBC3M,, bytes memory oracleDataBC3M,) = - OldTransmuter(address(transmuter)).getOracle(address(BC3M)); + (Storage.OracleReadType oracleTypeBC3M, , bytes memory oracleDataBC3M, ) = OldTransmuter(address(transmuter)) + .getOracle(address(BC3M)); - (,,,, uint256 currentBC3MPrice) = transmuter.getOracleValues(address(BC3M)); + (, , , , uint256 currentBC3MPrice) = transmuter.getOracleValues(address(BC3M)); bytes memory callData; // set the right implementations @@ -180,8 +180,12 @@ contract TransmuterUpdateFacets is Wrapper, TransmuterUtils { _updateFacets(chainIds[i]); } - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas, uint256[] memory chainIds2) = - _wrap(subCalls); + ( + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + uint256[] memory chainIds2 + ) = _wrap(subCalls); _serializeJson(targets, values, calldatas, chainIds2, description); } } diff --git a/scripts/proposals/transmuter/TransmuterUtils.s.sol b/scripts/proposals/transmuter/TransmuterUtils.s.sol index cada02a..04534e7 100644 --- a/scripts/proposals/transmuter/TransmuterUtils.s.sol +++ b/scripts/proposals/transmuter/TransmuterUtils.s.sol @@ -2,11 +2,11 @@ pragma solidity ^0.8.19; import "forge-std/Script.sol"; -import {StdAssertions} from "forge-std/Test.sol"; +import { StdAssertions } from "forge-std/Test.sol"; import "stringutils/strings.sol"; -import {CommonUtils} from "utils/src/CommonUtils.sol"; -import {ContractType, BASE_18} from "utils/src/Constants.sol"; +import { CommonUtils } from "utils/src/CommonUtils.sol"; +import { ContractType, BASE_18 } from "utils/src/Constants.sol"; contract TransmuterUtils is Script, CommonUtils { using strings for *; @@ -51,11 +51,14 @@ contract TransmuterUtils is Script, CommonUtils { } } - function _arrayBytes32ToBytes4Exclude(bytes4[] memory _in, bytes4 toExclude) internal pure returns (bytes32[] memory out) { + function _arrayBytes32ToBytes4Exclude( + bytes4[] memory _in, + bytes4 toExclude + ) internal pure returns (bytes32[] memory out) { out = new bytes32[](_in.length); uint256 length = 0; for (uint256 i = 0; i < _in.length; ++i) { - if(_in[i] != toExclude){ + if (_in[i] != toExclude) { out[length] = _bytes4ToBytes32(_in[i]); length++; } diff --git a/test/Constants.t.sol b/test/Constants.t.sol index 67f4040..da47d6b 100644 --- a/test/Constants.t.sol +++ b/test/Constants.t.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.9; -import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; uint48 constant initialVotingDelay = 1800; uint32 constant initialVotingPeriod = 36000; diff --git a/test/Fixture.t.sol b/test/Fixture.t.sol index 5a5c2d9..0268e44 100644 --- a/test/Fixture.t.sol +++ b/test/Fixture.t.sol @@ -2,23 +2,23 @@ pragma solidity ^0.8.19; -import {IveANGLEVotingDelegation} from "contracts/interfaces/IveANGLEVotingDelegation.sol"; -import {deployMockANGLE, deployVeANGLE} from "../scripts/test/DeployANGLE.s.sol"; -import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; +import { IveANGLEVotingDelegation } from "contracts/interfaces/IveANGLEVotingDelegation.sol"; +import { deployMockANGLE, deployVeANGLE } from "../scripts/test/DeployANGLE.s.sol"; +import { ERC20 } from "oz-v5/token/ERC20/ERC20.sol"; import "contracts/interfaces/IveANGLE.sol"; import "./external/VyperDeployer.sol"; -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {VeANGLEVotingDelegation, ECDSA} from "contracts/VeANGLEVotingDelegation.sol"; -import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { VeANGLEVotingDelegation, ECDSA } from "contracts/VeANGLEVotingDelegation.sol"; +import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "./Constants.t.sol"; import "./Utils.t.sol"; -import {Test, stdError} from "forge-std/Test.sol"; -import {console} from "forge-std/console.sol"; +import { Test, stdError } from "forge-std/Test.sol"; +import { console } from "forge-std/console.sol"; contract Fixture is Test { uint256 public constant FORK_BLOCK_NUMBER = 1152; @@ -61,10 +61,10 @@ contract Fixture is Test { // Deploy necessary contracts - for governance to be deployed vyperDeployer = new VyperDeployer(); - (address _mockANGLE,,) = deployMockANGLE(); + (address _mockANGLE, , ) = deployMockANGLE(); ANGLE = ERC20(_mockANGLE); deal(address(ANGLE), mainnetMultisig, GOVERNOR_INIT_BALANCE); - (address _mockVeANGLE,,) = deployVeANGLE(vyperDeployer, _mockANGLE, mainnetMultisig); + (address _mockVeANGLE, , ) = deployVeANGLE(vyperDeployer, _mockANGLE, mainnetMultisig); veANGLE = IveANGLE(_mockVeANGLE); _setupDealAndLockANGLE(alice, 1_000_000 * 1e18, 365 days); _setupDealAndLockANGLE(bob, 333_000 * 1e18, 4 * 365 days); diff --git a/test/external/MockANGLE.sol b/test/external/MockANGLE.sol index 8c04719..05a7e29 100644 --- a/test/external/MockANGLE.sol +++ b/test/external/MockANGLE.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.19; -import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; +import { ERC20 } from "oz-v5/token/ERC20/ERC20.sol"; contract MockANGLE is ERC20 { constructor(string memory _name, string memory _symbol) ERC20(_name, _symbol) {} diff --git a/test/fuzz/GovernorCountingFractional.t.sol b/test/fuzz/GovernorCountingFractional.t.sol index 8befd79..d436500 100644 --- a/test/fuzz/GovernorCountingFractional.t.sol +++ b/test/fuzz/GovernorCountingFractional.t.sol @@ -1,23 +1,23 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity >=0.8.10; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {SafeCast} from "oz-v5/utils/math/SafeCast.sol"; -import {Strings} from "oz-v5/utils/Strings.sol"; -import {MessageHashUtils} from "oz-v5/utils/cryptography/MessageHashUtils.sol"; -import {GovernorCountingSimple} from "oz-v5/governance/extensions/GovernorCountingSimple.sol"; -import {GovernorVotesQuorumFraction} from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; - -import {Test, stdError} from "forge-std/Test.sol"; -import {Vm} from "forge-std/Vm.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { SafeCast } from "oz-v5/utils/math/SafeCast.sol"; +import { Strings } from "oz-v5/utils/Strings.sol"; +import { MessageHashUtils } from "oz-v5/utils/cryptography/MessageHashUtils.sol"; +import { GovernorCountingSimple } from "oz-v5/governance/extensions/GovernorCountingSimple.sol"; +import { GovernorVotesQuorumFraction } from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; + +import { Test, stdError } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; import "forge-std/console.sol"; -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {VeANGLEVotingDelegation} from "contracts/VeANGLEVotingDelegation.sol"; -import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { VeANGLEVotingDelegation } from "contracts/VeANGLEVotingDelegation.sol"; +import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "../external/FixedPointMathLib.t.sol"; @@ -31,7 +31,12 @@ contract GovernorCountingFractionalTest is Test { event MockFunctionCalled(); event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason); event VoteCastWithParams( - address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason, bytes params + address indexed voter, + uint256 proposalId, + uint8 support, + uint256 weight, + string reason, + bytes params ); event ProposalExecuted(uint256 proposalId); event ProposalCreated( @@ -124,7 +129,11 @@ contract GovernorCountingFractionalTest is Test { proposalSender = new ProposalSender(mainnetLzEndpoint); proposalSender.transferOwnership(address(governor)); - vm.mockCall(address(token), abi.encodeWithSelector(token.getPastTotalSupply.selector), abi.encode(TOTAL_SUPPLY)); + vm.mockCall( + address(token), + abi.encodeWithSelector(token.getPastTotalSupply.selector), + abi.encode(TOTAL_SUPPLY) + ); } /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -136,8 +145,9 @@ contract GovernorCountingFractionalTest is Test { } function _getQuorum() internal returns (uint256 _weight) { - _weight = (token.getPastTotalSupply(block.number) * governor.quorumNumerator(block.timestamp)) - / governor.quorumDenominator(); + _weight = + (token.getPastTotalSupply(block.number) * governor.quorumNumerator(block.timestamp)) / + governor.quorumDenominator(); // if the weight is too large (> type(uint128).max) decrease the totalSupply // for it to be enough to be above quorum @@ -145,7 +155,9 @@ contract GovernorCountingFractionalTest is Test { _weight = MAX_VOTE_WEIGHT; uint256 _tmpTotalSupply = _supplyInverseQuorum(_weight); vm.mockCall( - address(token), abi.encodeWithSelector(token.getPastTotalSupply.selector), abi.encode(_tmpTotalSupply) + address(token), + abi.encodeWithSelector(token.getPastTotalSupply.selector), + abi.encode(_tmpTotalSupply) ); } } @@ -155,8 +167,9 @@ contract GovernorCountingFractionalTest is Test { } function _buildDomainSeparator() private view returns (bytes32) { - bytes32 TYPE_HASH = - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + bytes32 TYPE_HASH = keccak256( + "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" + ); bytes32 _hashedName = keccak256(bytes("AngleGovernor")); bytes32 _hashedVersion = keccak256(bytes("1")); return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(governor))); @@ -265,10 +278,10 @@ contract GovernorCountingFractionalTest is Test { } // Sets up up a 4-Voter array with specified weights and voteSplits, and random supportTypes. - function _setupFractionalVoters(uint256[4] memory weights, FractionalVoteSplit[4] memory voteSplits) - internal - returns (Voter[4] memory voters) - { + function _setupFractionalVoters( + uint256[4] memory weights, + FractionalVoteSplit[4] memory voteSplits + ) internal returns (Voter[4] memory voters) { voters = _setupNominalVoters(weights); Voter memory voter; @@ -295,10 +308,9 @@ contract GovernorCountingFractionalTest is Test { ); } - function _mintAndDelegateToVoters(Voter[4] memory voters) - internal - returns (uint256 forVotes, uint256 againstVotes, uint256 abstainVotes) - { + function _mintAndDelegateToVoters( + Voter[4] memory voters + ) internal returns (uint256 forVotes, uint256 againstVotes, uint256 abstainVotes) { Voter memory voter; for (uint8 _i = 0; _i < voters.length; _i++) { @@ -342,7 +354,14 @@ contract GovernorCountingFractionalTest is Test { uint128(_voter.weight.mulWadDown(voteSplit.percentAbstain)) ); vm.expectEmit(true, true, true, true); - emit VoteCastWithParams(_voter.addr, _proposalId, _voter.support, _voter.weight, "Yay", fractionalizedVotes); + emit VoteCastWithParams( + _voter.addr, + _proposalId, + _voter.support, + _voter.weight, + "Yay", + fractionalizedVotes + ); } else { vm.expectEmit(true, true, true, true); emit VoteCast(_voter.addr, _proposalId, _voter.support, _voter.weight, "Yay"); @@ -372,7 +391,9 @@ contract GovernorCountingFractionalTest is Test { vm.warp(governor.proposalDeadline(_proposalId) + 1); vm.roll(governor.$snapshotTimestampToSnapshotBlockNumber(governor.proposalSnapshot(_proposalId)) + 1); - (uint256 againstVotesCast, uint256 forVotesCast, uint256 abstainVotesCast) = governor.proposalVotes(_proposalId); + (uint256 againstVotesCast, uint256 forVotesCast, uint256 abstainVotesCast) = governor.proposalVotes( + _proposalId + ); assertEq(againstVotes, againstVotesCast); assertEq(forVotes, forVotesCast); @@ -380,8 +401,8 @@ contract GovernorCountingFractionalTest is Test { IGovernor.ProposalState status = IGovernor.ProposalState(uint32(governor.state(_proposalId))); if ( - forVotes > againstVotes - && (forVotes + abstainVotes) >= governor.quorum(governor.proposalSnapshot(_proposalId)) + forVotes > againstVotes && + (forVotes + abstainVotes) >= governor.quorum(governor.proposalSnapshot(_proposalId)) ) { assertEq(uint8(status), uint8(IGovernor.ProposalState.Succeeded)); _executeProposal(); @@ -394,8 +415,8 @@ contract GovernorCountingFractionalTest is Test { IGovernor.GovernorUnexpectedProposalState.selector, _rawProposalInfo.id, IGovernor.ProposalState.Defeated, - _encodeStateBitmap(IGovernor.ProposalState.Succeeded) - | _encodeStateBitmap(IGovernor.ProposalState.Queued) + _encodeStateBitmap(IGovernor.ProposalState.Succeeded) | + _encodeStateBitmap(IGovernor.ProposalState.Queued) ) ); governor.execute( @@ -451,8 +472,9 @@ contract GovernorCountingFractionalTest is Test { _mintAndDelegateToVoter(_voter); uint256 _proposalId = _createAndSubmitProposal(); - bytes32 _voteMessage = - keccak256(abi.encode(governor.BALLOT_TYPEHASH(), _proposalId, _voter.support, _voter.addr, 0)); + bytes32 _voteMessage = keccak256( + abi.encode(governor.BALLOT_TYPEHASH(), _proposalId, _voter.support, _voter.addr, 0) + ); bytes memory signature; { @@ -463,8 +485,9 @@ contract GovernorCountingFractionalTest is Test { } governor.castVoteBySig(_proposalId, _voter.support, _voter.addr, signature); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = - governor.proposalVotes(_proposalId); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( + _proposalId + ); if (_voter.support == uint8(GovernorCountingSimple.VoteType.For)) { assertEq(_voter.weight, _actualForVotes); } @@ -476,9 +499,10 @@ contract GovernorCountingFractionalTest is Test { } } - function testFuzz_VotingWithFractionalizedParamsAndSignature(uint256 _weight, FractionalVoteSplit memory _voteSplit) - public - { + function testFuzz_VotingWithFractionalizedParamsAndSignature( + uint256 _weight, + FractionalVoteSplit memory _voteSplit + ) public { Voter memory _voter; uint256 _privateKey; (_voter.addr, _privateKey) = makeAddrAndKey("voter"); @@ -517,11 +541,17 @@ contract GovernorCountingFractionalTest is Test { } governor.castVoteWithReasonAndParamsBySig( - _proposalId, _voter.support, _voter.addr, "I have my reasons", _fractionalizedVotes, signature + _proposalId, + _voter.support, + _voter.addr, + "I have my reasons", + _fractionalizedVotes, + signature ); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = - governor.proposalVotes(_proposalId); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( + _proposalId + ); assertEq(_forVotes, _actualForVotes); assertEq(_againstVotes, _actualAgainstVotes); assertEq(_abstainVotes, _actualAbstainVotes); @@ -583,7 +613,11 @@ contract GovernorCountingFractionalTest is Test { // They must have weight at the time of the proposal snapshot. vm.mockCall(address(token), abi.encodeWithSelector(token.getVotes.selector, _voterAddr), abi.encode(100e18)); - vm.mockCall(address(token), abi.encodeWithSelector(token.getPastVotes.selector, _voterAddr), abi.encode(100e18)); + vm.mockCall( + address(token), + abi.encodeWithSelector(token.getPastVotes.selector, _voterAddr), + abi.encode(100e18) + ); uint256 _proposalId = _createAndSubmitProposal(); @@ -763,11 +797,9 @@ contract GovernorCountingFractionalTest is Test { _quorumTest(_voterAddr, _weight, _voteSplit, _wasQuorumReached); } - function _decodePackedVotes(bytes memory voteData) - internal - pure - returns (uint128 againstVotes, uint128 forVotes, uint128 abstainVotes) - { + function _decodePackedVotes( + bytes memory voteData + ) internal pure returns (uint128 againstVotes, uint128 forVotes, uint128 abstainVotes) { assembly { againstVotes := shr(128, mload(add(voteData, 0x20))) forVotes := and(0xffffffffffffffffffffffffffffffff, mload(add(voteData, 0x20))) @@ -804,9 +836,11 @@ contract GovernorCountingFractionalTest is Test { assertEq(_quorumReached(_proposalId), _isQuorumExpected); } - function testFuzz_CanCastWithPartialWeight(address _voterAddr, uint256 _salt, FractionalVoteSplit memory _voteSplit) - public - { + function testFuzz_CanCastWithPartialWeight( + address _voterAddr, + uint256 _salt, + FractionalVoteSplit memory _voteSplit + ) public { // Build a partial weight vote split. _voteSplit = _randomVoteSplit(_voteSplit); uint256 _percentKeep = bound(_salt, 0.9e18, 0.99e18); // 90% to 99% @@ -838,8 +872,9 @@ contract GovernorCountingFractionalTest is Test { vm.prank(_voter.addr); governor.castVoteWithReasonAndParams(_proposalId, _voter.support, "Lobster", fractionalizedVotes); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = - governor.proposalVotes(_proposalId); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( + _proposalId + ); assertEq(_forVotes, _actualForVotes); assertEq(_againstVotes, _actualAgainstVotes); assertEq(_abstainVotes, _actualAbstainVotes); @@ -848,7 +883,12 @@ contract GovernorCountingFractionalTest is Test { function test_CanCastPartialWeightMultipleTimesAddingToFullWeight() public { testFuzz_CanCastPartialWeightMultipleTimes( - _randomAddress(), 42 ether, 0.45e18, 0.25e18, 0.3e18, FractionalVoteSplit(0.33e18, 0.33e18, 0.34e18) + _randomAddress(), + 42 ether, + 0.45e18, + 0.25e18, + 0.3e18, + FractionalVoteSplit(0.33e18, 0.33e18, 0.34e18) ); } @@ -884,10 +924,12 @@ contract GovernorCountingFractionalTest is Test { // Calculate the vote amounts for the first vote. VoteData memory _firstVote; _firstVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage1)); - _firstVote.againstVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage1)); - _firstVote.abstainVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage1)); + _firstVote.againstVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage1) + ); + _firstVote.abstainVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage1) + ); // Cast votes the first time. vm.prank(_voter.addr); @@ -898,8 +940,9 @@ contract GovernorCountingFractionalTest is Test { abi.encodePacked(_firstVote.againstVotes, _firstVote.forVotes, _firstVote.abstainVotes) ); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = - governor.proposalVotes(_proposalId); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( + _proposalId + ); assertEq(_firstVote.forVotes, _actualForVotes); assertEq(_firstVote.againstVotes, _actualAgainstVotes); assertEq(_firstVote.abstainVotes, _actualAbstainVotes); @@ -914,10 +957,12 @@ contract GovernorCountingFractionalTest is Test { // Now cast votes again. VoteData memory _secondVote; _secondVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage2)); - _secondVote.againstVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage2)); - _secondVote.abstainVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage2)); + _secondVote.againstVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage2) + ); + _secondVote.abstainVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage2) + ); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( @@ -933,8 +978,12 @@ contract GovernorCountingFractionalTest is Test { assertEq(_firstVote.abstainVotes + _secondVote.abstainVotes, _actualAbstainVotes); assertEq( governor.voteWeightCast(_proposalId, _voter.addr), - _firstVote.againstVotes + _firstVote.forVotes + _firstVote.abstainVotes + _secondVote.againstVotes - + _secondVote.forVotes + _secondVote.abstainVotes + _firstVote.againstVotes + + _firstVote.forVotes + + _firstVote.abstainVotes + + _secondVote.againstVotes + + _secondVote.forVotes + + _secondVote.abstainVotes ); // If the entire weight was cast; further votes are not possible. @@ -943,10 +992,12 @@ contract GovernorCountingFractionalTest is Test { // Once more unto the breach! VoteData memory _thirdVote; _thirdVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage3)); - _thirdVote.againstVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage3)); - _thirdVote.abstainVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage3)); + _thirdVote.againstVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage3) + ); + _thirdVote.abstainVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage3) + ); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( @@ -962,9 +1013,15 @@ contract GovernorCountingFractionalTest is Test { assertEq(_firstVote.abstainVotes + _secondVote.abstainVotes + _thirdVote.abstainVotes, _actualAbstainVotes); assertEq( governor.voteWeightCast(_proposalId, _voter.addr), - _firstVote.againstVotes + _firstVote.forVotes + _firstVote.abstainVotes + _secondVote.againstVotes - + _secondVote.forVotes + _secondVote.abstainVotes + _thirdVote.againstVotes + _thirdVote.forVotes - + _thirdVote.abstainVotes + _firstVote.againstVotes + + _firstVote.forVotes + + _firstVote.abstainVotes + + _secondVote.againstVotes + + _secondVote.forVotes + + _secondVote.abstainVotes + + _thirdVote.againstVotes + + _thirdVote.forVotes + + _thirdVote.abstainVotes ); } @@ -996,10 +1053,12 @@ contract GovernorCountingFractionalTest is Test { // Calculate the vote amounts for the first vote. VoteData memory _firstVote; _firstVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage1)); - _firstVote.againstVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage1)); - _firstVote.abstainVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage1)); + _firstVote.againstVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage1) + ); + _firstVote.abstainVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage1) + ); // Cast votes the first time. vm.prank(_voter.addr); @@ -1010,8 +1069,9 @@ contract GovernorCountingFractionalTest is Test { abi.encodePacked(_firstVote.againstVotes, _firstVote.forVotes, _firstVote.abstainVotes) ); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = - governor.proposalVotes(_proposalId); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( + _proposalId + ); assertEq(_actualForVotes, 16 ether); // 100 * 20% * 80% assertEq(_actualAgainstVotes, 3 ether); // 100 * 20% * 15% assertEq(_actualAbstainVotes, 1 ether); // 100 * 20% * 5% @@ -1019,10 +1079,12 @@ contract GovernorCountingFractionalTest is Test { // Now cast votes again. VoteData memory _secondVote; _secondVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage2)); - _secondVote.againstVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage2)); - _secondVote.abstainVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage2)); + _secondVote.againstVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage2) + ); + _secondVote.abstainVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage2) + ); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( @@ -1040,10 +1102,12 @@ contract GovernorCountingFractionalTest is Test { // One more time! VoteData memory _thirdVote; _thirdVote.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage3)); - _thirdVote.againstVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage3)); - _thirdVote.abstainVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage3)); + _thirdVote.againstVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage3) + ); + _thirdVote.abstainVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage3) + ); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( @@ -1088,10 +1152,12 @@ contract GovernorCountingFractionalTest is Test { // Calculate the vote amounts for the first vote. VoteData memory _voteData; _voteData.forVotes = uint128(_voter.weight.mulWadDown(_voteSplit.percentFor).mulWadDown(_votePercentage)); - _voteData.againstVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage)); - _voteData.abstainVotes = - uint128(_voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage)); + _voteData.againstVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAgainst).mulWadDown(_votePercentage) + ); + _voteData.abstainVotes = uint128( + _voter.weight.mulWadDown(_voteSplit.percentAbstain).mulWadDown(_votePercentage) + ); // We're going to do this twice to try to exceed our vote weight. assertLt(_voter.weight, 2 * (uint256(_voteData.forVotes) + _voteData.againstVotes + _voteData.abstainVotes)); @@ -1105,8 +1171,9 @@ contract GovernorCountingFractionalTest is Test { abi.encodePacked(_voteData.againstVotes, _voteData.forVotes, _voteData.abstainVotes) ); - (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = - governor.proposalVotes(_proposalId); + (uint256 _actualAgainstVotes, uint256 _actualForVotes, uint256 _actualAbstainVotes) = governor.proposalVotes( + _proposalId + ); assertEq(_voteData.forVotes, _actualForVotes); assertEq(_voteData.againstVotes, _actualAgainstVotes); assertEq(_voteData.abstainVotes, _actualAbstainVotes); @@ -1182,16 +1249,27 @@ contract GovernorCountingFractionalTest is Test { vm.expectRevert(Errors.GovernorCountingFractionalAllWeightCast.selector); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( - _proposalId, _voter.support, "Fractional vote", _fractionalizedVoteData + _proposalId, + _voter.support, + "Fractional vote", + _fractionalizedVoteData ); } else { vm.expectEmit(true, true, true, true); emit VoteCastWithParams( - _voter.addr, _proposalId, _voter.support, _voter.weight, "Fractional vote", _fractionalizedVoteData + _voter.addr, + _proposalId, + _voter.support, + _voter.weight, + "Fractional vote", + _fractionalizedVoteData ); vm.prank(_voter.addr); governor.castVoteWithReasonAndParams( - _proposalId, _voter.support, "Fractional vote", _fractionalizedVoteData + _proposalId, + _voter.support, + "Fractional vote", + _fractionalizedVoteData ); vm.prank(_voter.addr); @@ -1200,8 +1278,9 @@ contract GovernorCountingFractionalTest is Test { } // The voter should not have been able to increase his/her vote weight by voting twice. - (uint256 _againstVotesCast, uint256 _forVotesCast, uint256 _abstainVotesCast) = - governor.proposalVotes(_proposalId); + (uint256 _againstVotesCast, uint256 _forVotesCast, uint256 _abstainVotesCast) = governor.proposalVotes( + _proposalId + ); assertLe(_againstVotesCast + _forVotesCast + _abstainVotesCast, _voter.weight); } } diff --git a/test/fuzz/VeANGLEVotingDelegation.t.sol b/test/fuzz/VeANGLEVotingDelegation.t.sol index 0cd20dc..2011f26 100644 --- a/test/fuzz/VeANGLEVotingDelegation.t.sol +++ b/test/fuzz/VeANGLEVotingDelegation.t.sol @@ -1,18 +1,18 @@ // SPDX-License-Identifier: ISC pragma solidity ^0.8.19; -import {IveANGLEVotingDelegation} from "contracts/interfaces/IveANGLEVotingDelegation.sol"; -import {Test, stdError} from "forge-std/Test.sol"; -import {deployMockANGLE, deployVeANGLE} from "../../scripts/test/DeployANGLE.s.sol"; -import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; +import { IveANGLEVotingDelegation } from "contracts/interfaces/IveANGLEVotingDelegation.sol"; +import { Test, stdError } from "forge-std/Test.sol"; +import { deployMockANGLE, deployVeANGLE } from "../../scripts/test/DeployANGLE.s.sol"; +import { ERC20 } from "oz-v5/token/ERC20/ERC20.sol"; import "contracts/interfaces/IveANGLE.sol"; import "../external/VyperDeployer.sol"; -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {VeANGLEVotingDelegation, ECDSA} from "contracts/VeANGLEVotingDelegation.sol"; -import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { VeANGLEVotingDelegation, ECDSA } from "contracts/VeANGLEVotingDelegation.sol"; +import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Constants.t.sol"; import "../Utils.t.sol"; @@ -71,11 +71,11 @@ contract VeANGLEVotingDelegationTest is Test, Utils { vyperDeployer = new VyperDeployer(); - (address _mockANGLE,,) = deployMockANGLE(); + (address _mockANGLE, , ) = deployMockANGLE(); ANGLE = ERC20(_mockANGLE); deal(address(ANGLE), mainnetMultisig, 300_000_000e18); - (address _mockVeANGLE,,) = deployVeANGLE(vyperDeployer, _mockANGLE, mainnetMultisig); + (address _mockVeANGLE, , ) = deployVeANGLE(vyperDeployer, _mockANGLE, mainnetMultisig); veANGLE = IveANGLE(_mockVeANGLE); _setupDealAndLockANGLE(); @@ -170,7 +170,9 @@ contract VeANGLEVotingDelegationTest is Test, Utils { // Assert that this account has weight themselves when they haven't delegated function test_RevertWhen_NoDelegationHasWeight() public { assertEq( - token.getVotes(accounts[0]), veANGLE.balanceOf(accounts[0]), "getVotes and veANGLE balance are identical" + token.getVotes(accounts[0]), + veANGLE.balanceOf(accounts[0]), + "getVotes and veANGLE balance are identical" ); } @@ -259,10 +261,11 @@ contract VeANGLEVotingDelegationTest is Test, Utils { function test_DelegateBySig() public { dealCreateLockANGLE(eoaOwners[0], 100e18); - (, string memory name, string memory version, uint256 chainId, address verifyingContract,,) = - token.eip712Domain(); - bytes32 TYPE_HASH = - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + (, string memory name, string memory version, uint256 chainId, address verifyingContract, , ) = token + .eip712Domain(); + bytes32 TYPE_HASH = keccak256( + "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" + ); bytes32 domainSeparator = keccak256( abi.encode(TYPE_HASH, keccak256(bytes(name)), keccak256(bytes(version)), chainId, verifyingContract) ); @@ -386,7 +389,11 @@ contract VeANGLEVotingDelegationTest is Test, Utils { vm.warp(delegationStarts + 1 days - 1); assertGt(token.getVotes(bob, block.timestamp), 0, "Bob still has voting power until next epoch"); - assertEq(0, token.getVotes(charlie, block.timestamp), "Bill should still have no voting power until next epoch"); + assertEq( + 0, + token.getVotes(charlie, block.timestamp), + "Bill should still have no voting power until next epoch" + ); assertEq( 0, token.getVotes(accounts[0], block.timestamp), @@ -538,7 +545,9 @@ contract VeANGLEVotingDelegationTest is Test, Utils { vm.warp(expiration + 1 days); assertEq( - token.getVotes(bob), veANGLE.balanceOf(accounts[0]), "Self delegation is equivalent to veANGLE balance" + token.getVotes(bob), + veANGLE.balanceOf(accounts[0]), + "Self delegation is equivalent to veANGLE balance" ); } @@ -590,7 +599,9 @@ contract VeANGLEVotingDelegationTest is Test, Utils { token.delegate(bob); assertLe( - weight, token.getVotes(accounts[0], block.timestamp - 1), "accounts[0] still has weight before delegation" + weight, + token.getVotes(accounts[0], block.timestamp - 1), + "accounts[0] still has weight before delegation" ); assertEq( weight, @@ -599,7 +610,9 @@ contract VeANGLEVotingDelegationTest is Test, Utils { ); assertLe( - weightA, token.getVotes(accounts[1], block.timestamp - 1), "accounts[1] still has weight before delegation" + weightA, + token.getVotes(accounts[1], block.timestamp - 1), + "accounts[1] still has weight before delegation" ); assertEq( weightA, @@ -626,10 +639,14 @@ contract VeANGLEVotingDelegationTest is Test, Utils { vm.warp(tsRoundedToCheckpoint); assertEq( - 0, token.getVotes(accounts[0], block.timestamp), "accounts[0]'s delegation kicks in so they have no weight" + 0, + token.getVotes(accounts[0], block.timestamp), + "accounts[0]'s delegation kicks in so they have no weight" ); assertEq( - 0, token.getVotes(accounts[1], block.timestamp), "accounts[1]'s delegation kicks in so they have no weight" + 0, + token.getVotes(accounts[1], block.timestamp), + "accounts[1]'s delegation kicks in so they have no weight" ); uint256 bobWeight = token.getVotes(bob, block.timestamp); @@ -703,7 +720,9 @@ contract VeANGLEVotingDelegationTest is Test, Utils { assertEq(weight, 0, "Delegator has no weight"); assertEq(weightA, 0, "Delegator has no weight"); assertEq( - veANGLEBalance + veANGLEBalanceA, delegateWeight, "delegate's weight == veANGLE balance of both delegators" + veANGLEBalance + veANGLEBalanceA, + delegateWeight, + "delegate's weight == veANGLE balance of both delegators" ); } diff --git a/test/invariant/BasicInvariants.t.sol b/test/invariant/BasicInvariants.t.sol index 95f70b2..e0b0e76 100644 --- a/test/invariant/BasicInvariants.t.sol +++ b/test/invariant/BasicInvariants.t.sol @@ -2,15 +2,15 @@ pragma solidity ^0.8.19; -import {IERC20} from "oz-v5/token/ERC20/IERC20.sol"; -import {IERC20Metadata} from "oz-v5/token/ERC20/extensions/IERC20Metadata.sol"; +import { IERC20 } from "oz-v5/token/ERC20/IERC20.sol"; +import { IERC20Metadata } from "oz-v5/token/ERC20/extensions/IERC20Metadata.sol"; import "oz-v5/utils/Strings.sol"; -import {Voter} from "./actors/Voter.t.sol"; -import {Fixture, AngleGovernor} from "../Fixture.t.sol"; -import {ProposalStore} from "./stores/ProposalStore.sol"; +import { Voter } from "./actors/Voter.t.sol"; +import { Fixture, AngleGovernor } from "../Fixture.t.sol"; +import { ProposalStore } from "./stores/ProposalStore.sol"; //solhint-disable -import {console} from "forge-std/console.sol"; +import { console } from "forge-std/console.sol"; contract BasicInvariants is Fixture { uint256 internal constant _NUM_VOTER = 10; diff --git a/test/invariant/DelegationInvariants.t.sol b/test/invariant/DelegationInvariants.t.sol index 4ae661d..ea9c33c 100644 --- a/test/invariant/DelegationInvariants.t.sol +++ b/test/invariant/DelegationInvariants.t.sol @@ -10,7 +10,7 @@ import { Param } from "./actors/Param.t.sol"; import { Fixture, AngleGovernor } from "../Fixture.t.sol"; //solhint-disable -import {console} from "forge-std/console.sol"; +import { console } from "forge-std/console.sol"; contract DelegationInvariants is Fixture { uint256 internal constant _NUM_DELEGATORS = 10; @@ -40,12 +40,12 @@ contract DelegationInvariants is Fixture { selectors[2] = Delegator.withdraw.selector; selectors[3] = Delegator.extendLockTime.selector; selectors[4] = Delegator.extendLockAmount.selector; - targetSelector(FuzzSelector({addr: address(_delegatorHandler), selectors: selectors})); + targetSelector(FuzzSelector({ addr: address(_delegatorHandler), selectors: selectors })); } { bytes4[] memory selectors = new bytes4[](1); selectors[0] = Param.wrap.selector; - targetSelector(FuzzSelector({addr: address(_paramHandler), selectors: selectors})); + targetSelector(FuzzSelector({ addr: address(_paramHandler), selectors: selectors })); } } @@ -54,7 +54,9 @@ contract DelegationInvariants is Fixture { address actor = _delegatorHandler.actors(i); assertEq( - token.delegates(actor), _delegatorHandler.delegations(actor), "delegatee should be the same as actor" + token.delegates(actor), + _delegatorHandler.delegations(actor), + "delegatee should be the same as actor" ); } for (uint256 i; i < _delegatorHandler.delegateesLength(); i++) { diff --git a/test/invariant/MainnetGovernorInvariants.t.sol b/test/invariant/MainnetGovernorInvariants.t.sol index 88c1170..197dd0b 100644 --- a/test/invariant/MainnetGovernorInvariants.t.sol +++ b/test/invariant/MainnetGovernorInvariants.t.sol @@ -2,18 +2,18 @@ pragma solidity ^0.8.19; -import {IERC20} from "oz/token/ERC20/IERC20.sol"; -import {IERC20Metadata} from "oz/token/ERC20/extensions/IERC20Metadata.sol"; +import { IERC20 } from "oz/token/ERC20/IERC20.sol"; +import { IERC20Metadata } from "oz/token/ERC20/extensions/IERC20Metadata.sol"; import "oz/utils/Strings.sol"; -import {Voter} from "./actors/Voter.t.sol"; -import {Proposer} from "./actors/Proposer.t.sol"; -import {BadVoter} from "./actors/BadVoter.t.sol"; -import {Fixture, AngleGovernor} from "../Fixture.t.sol"; -import {ProposalStore, Proposal} from "./stores/ProposalStore.sol"; -import {IGovernor} from "oz/governance/IGovernor.sol"; +import { Voter } from "./actors/Voter.t.sol"; +import { Proposer } from "./actors/Proposer.t.sol"; +import { BadVoter } from "./actors/BadVoter.t.sol"; +import { Fixture, AngleGovernor } from "../Fixture.t.sol"; +import { ProposalStore, Proposal } from "./stores/ProposalStore.sol"; +import { IGovernor } from "oz/governance/IGovernor.sol"; //solhint-disable -import {console} from "forge-std/console.sol"; +import { console } from "forge-std/console.sol"; contract MainnetGovernorInvariants is Fixture { uint256 internal constant _NUM_VOTER = 10; @@ -34,7 +34,7 @@ contract MainnetGovernorInvariants is Fixture { _badVoterHandler = new BadVoter(angleGovernor, ANGLE, _NUM_VOTER, _proposalStore); // Label newly created addresses - vm.label({account: address(_proposalStore), newLabel: "ProposalStore"}); + vm.label({ account: address(_proposalStore), newLabel: "ProposalStore" }); for (uint256 i; i < _NUM_VOTER; i++) { vm.label(_voterHandler.actors(i), string.concat("Voter ", Strings.toString(i))); _setupDealAndLockANGLE(_voterHandler.actors(i), 100000000e18, 4 * 365 days); @@ -58,7 +58,7 @@ contract MainnetGovernorInvariants is Fixture { { bytes4[] memory selectors = new bytes4[](1); selectors[0] = Voter.vote.selector; - targetSelector(FuzzSelector({addr: address(_voterHandler), selectors: selectors})); + targetSelector(FuzzSelector({ addr: address(_voterHandler), selectors: selectors })); } { bytes4[] memory selectors = new bytes4[](4); @@ -66,13 +66,13 @@ contract MainnetGovernorInvariants is Fixture { selectors[1] = Proposer.execute.selector; selectors[2] = Proposer.tryToExecute.selector; selectors[3] = Proposer.skipVotingDelay.selector; - targetSelector(FuzzSelector({addr: address(_proposerHandler), selectors: selectors})); + targetSelector(FuzzSelector({ addr: address(_proposerHandler), selectors: selectors })); } { bytes4[] memory selectors = new bytes4[](2); selectors[0] = BadVoter.voteNonExistantProposal.selector; selectors[1] = BadVoter.executeNonReadyProposals.selector; - targetSelector(FuzzSelector({addr: address(_badVoterHandler), selectors: selectors})); + targetSelector(FuzzSelector({ addr: address(_badVoterHandler), selectors: selectors })); } } @@ -81,8 +81,12 @@ contract MainnetGovernorInvariants is Fixture { Proposal[] memory proposals = _proposalStore.getProposals(); for (uint256 i; i < proposalLength; i++) { Proposal memory proposal = proposals[i]; - uint256 proposalHash = - angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); + uint256 proposalHash = angleGovernor.hashProposal( + proposal.target, + proposal.value, + proposal.data, + proposal.description + ); uint256 totalSupply = veANGLE.totalSupply(); (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) = angleGovernor.proposalVotes(proposalHash); assertLe(againstVotes + forVotes + abstainVotes, totalSupply, "Votes should be under total supply"); @@ -94,8 +98,12 @@ contract MainnetGovernorInvariants is Fixture { Proposal[] memory proposals = _proposalStore.getProposals(); for (uint256 i; i < proposalLength; i++) { Proposal memory proposal = proposals[i]; - uint256 proposalHash = - angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); + uint256 proposalHash = angleGovernor.hashProposal( + proposal.target, + proposal.value, + proposal.data, + proposal.description + ); IGovernor.ProposalState currentState = angleGovernor.state(proposalHash); uint256 snapshot = angleGovernor.proposalSnapshot(proposalHash); uint256 deadline = angleGovernor.proposalDeadline(proposalHash); @@ -125,16 +133,20 @@ contract MainnetGovernorInvariants is Fixture { Proposal[] memory oldProposals = _proposalStore.getOldProposals(); for (uint256 i; i < oldProposals.length; i++) { Proposal memory proposal = oldProposals[i]; - uint256 proposalHash = - angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); + uint256 proposalHash = angleGovernor.hashProposal( + proposal.target, + proposal.value, + proposal.data, + proposal.description + ); IGovernor.ProposalState currentState = angleGovernor.state(proposalHash); vm.expectRevert( abi.encodeWithSelector( IGovernor.GovernorUnexpectedProposalState.selector, proposalHash, currentState, - bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) - | bytes32(1 << uint8(IGovernor.ProposalState.Queued)) + bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) | + bytes32(1 << uint8(IGovernor.ProposalState.Queued)) ) ); angleGovernor.execute(proposal.target, proposal.value, proposal.data, proposal.description); @@ -145,8 +157,12 @@ contract MainnetGovernorInvariants is Fixture { Proposal[] memory oldProposals = _proposalStore.getOldProposals(); for (uint256 i; i < oldProposals.length; i++) { Proposal memory proposal = oldProposals[i]; - uint256 proposalHash = - angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); + uint256 proposalHash = angleGovernor.hashProposal( + proposal.target, + proposal.value, + proposal.data, + proposal.description + ); IGovernor.ProposalState currentState = angleGovernor.state(proposalHash); if (currentState != IGovernor.ProposalState.Active) { vm.expectRevert( diff --git a/test/invariant/actors/BadVoter.t.sol b/test/invariant/actors/BadVoter.t.sol index 3035321..af2add8 100644 --- a/test/invariant/actors/BadVoter.t.sol +++ b/test/invariant/actors/BadVoter.t.sol @@ -1,18 +1,21 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import {BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage} from "./BaseActor.t.sol"; -import {console} from "forge-std/console.sol"; -import {ProposalStore, Proposal} from "../stores/ProposalStore.sol"; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import { BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage } from "./BaseActor.t.sol"; +import { console } from "forge-std/console.sol"; +import { ProposalStore, Proposal } from "../stores/ProposalStore.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; contract BadVoter is BaseActor { AngleGovernor internal _angleGovernor; ProposalStore public proposalStore; - constructor(AngleGovernor angleGovernor, IERC20 angle, uint256 nbrVoter, ProposalStore _proposalStore) - BaseActor(nbrVoter, "BadVoter", angle) - { + constructor( + AngleGovernor angleGovernor, + IERC20 angle, + uint256 nbrVoter, + ProposalStore _proposalStore + ) BaseActor(nbrVoter, "BadVoter", angle) { _angleGovernor = angleGovernor; proposalStore = _proposalStore; } @@ -24,8 +27,12 @@ contract BadVoter is BaseActor { Proposal[] memory proposals = proposalStore.getProposals(); for (uint256 i; i < proposals.length; i++) { Proposal memory proposal = proposals[i]; - uint256 proposalHash = - _angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); + uint256 proposalHash = _angleGovernor.hashProposal( + proposal.target, + proposal.value, + proposal.data, + proposal.description + ); if (proposalHash != proposalId || proposalStore.doesOldProposalExists(proposalHash)) { return; } @@ -41,16 +48,20 @@ contract BadVoter is BaseActor { } Proposal[] memory proposals = proposalStore.getProposals(); Proposal memory proposal = proposalStore.getRandomProposal(proposalId); - uint256 proposalHash = - _angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); + uint256 proposalHash = _angleGovernor.hashProposal( + proposal.target, + proposal.value, + proposal.data, + proposal.description + ); if (_angleGovernor.state(proposalHash) != IGovernor.ProposalState.Succeeded) { vm.expectRevert( abi.encodeWithSelector( IGovernor.GovernorUnexpectedProposalState.selector, proposalHash, _angleGovernor.state(proposalHash), - bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) - | bytes32(1 << uint8(IGovernor.ProposalState.Queued)) + bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) | + bytes32(1 << uint8(IGovernor.ProposalState.Queued)) ) ); _angleGovernor.execute(proposal.target, proposal.value, proposal.data, proposal.description); diff --git a/test/invariant/actors/BaseActor.t.sol b/test/invariant/actors/BaseActor.t.sol index ff8407e..702c2e0 100644 --- a/test/invariant/actors/BaseActor.t.sol +++ b/test/invariant/actors/BaseActor.t.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import {IERC20} from "oz-v5/token/ERC20/IERC20.sol"; -import {IERC20Metadata} from "oz-v5/token/ERC20/extensions/IERC20Metadata.sol"; -import {Test, stdMath, StdStorage, stdStorage} from "forge-std/Test.sol"; -import {IVotes} from "oz-v5/governance/utils/IVotes.sol"; -import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import { IERC20 } from "oz-v5/token/ERC20/IERC20.sol"; +import { IERC20Metadata } from "oz-v5/token/ERC20/extensions/IERC20Metadata.sol"; +import { Test, stdMath, StdStorage, stdStorage } from "forge-std/Test.sol"; +import { IVotes } from "oz-v5/governance/utils/IVotes.sol"; +import { AngleGovernor } from "contracts/AngleGovernor.sol"; import "contracts/utils/Errors.sol"; struct TestStorage { diff --git a/test/invariant/actors/Delegator.t.sol b/test/invariant/actors/Delegator.t.sol index 9a5f857..14b66d3 100644 --- a/test/invariant/actors/Delegator.t.sol +++ b/test/invariant/actors/Delegator.t.sol @@ -2,8 +2,8 @@ pragma solidity ^0.8.19; import "./BaseActor.t.sol"; -import {IERC5805} from "oz-v5/interfaces/IERC5805.sol"; -import {MockANGLE} from "../../external/MockANGLE.sol"; +import { IERC5805 } from "oz-v5/interfaces/IERC5805.sol"; +import { MockANGLE } from "../../external/MockANGLE.sol"; import "contracts/interfaces/IveANGLE.sol"; import "contracts/utils/Errors.sol"; @@ -15,9 +15,12 @@ contract Delegator is BaseActor { mapping(address => address[]) public reverseDelegations; address[] public delegatees; - constructor(uint256 _nbrActor, IERC20 _agToken, address _veToken, address _veDelegation) - BaseActor(_nbrActor, "Delegator", _agToken) - { + constructor( + uint256 _nbrActor, + IERC20 _agToken, + address _veToken, + address _veDelegation + ) BaseActor(_nbrActor, "Delegator", _agToken) { veToken = IveANGLE(_veToken); veDelegation = IERC5805(_veDelegation); } @@ -57,8 +60,9 @@ contract Delegator is BaseActor { reverseDelegations[toDelegate].push(_currentActor); for (uint256 i; i < reverseDelegations[currentDelegatee].length; i++) { if (reverseDelegations[currentDelegatee][i] == _currentActor) { - reverseDelegations[currentDelegatee][i] = - reverseDelegations[currentDelegatee][reverseDelegations[currentDelegatee].length - 1]; + reverseDelegations[currentDelegatee][i] = reverseDelegations[currentDelegatee][ + reverseDelegations[currentDelegatee].length - 1 + ]; reverseDelegations[currentDelegatee].pop(); break; } diff --git a/test/invariant/actors/Param.t.sol b/test/invariant/actors/Param.t.sol index 12e88ac..f937352 100644 --- a/test/invariant/actors/Param.t.sol +++ b/test/invariant/actors/Param.t.sol @@ -2,11 +2,11 @@ pragma solidity ^0.8.19; import "./BaseActor.t.sol"; -import {IERC5805} from "oz-v5/interfaces/IERC5805.sol"; -import {MockANGLE} from "../../external/MockANGLE.sol"; +import { IERC5805 } from "oz-v5/interfaces/IERC5805.sol"; +import { MockANGLE } from "../../external/MockANGLE.sol"; import "contracts/interfaces/IveANGLE.sol"; import "contracts/utils/Errors.sol"; -import {console} from "forge-std/console.sol"; +import { console } from "forge-std/console.sol"; contract Param is BaseActor { IveANGLE public veToken; diff --git a/test/invariant/actors/Proposer.t.sol b/test/invariant/actors/Proposer.t.sol index 3e089e2..9cc9b13 100644 --- a/test/invariant/actors/Proposer.t.sol +++ b/test/invariant/actors/Proposer.t.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import {BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage} from "./BaseActor.t.sol"; -import {console} from "forge-std/console.sol"; -import {IGovernor} from "oz/governance/IGovernor.sol"; -import {ProposalStore, Proposal} from "../stores/ProposalStore.sol"; -import {IERC5805} from "oz/interfaces/IERC5805.sol"; +import { BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage } from "./BaseActor.t.sol"; +import { console } from "forge-std/console.sol"; +import { IGovernor } from "oz/governance/IGovernor.sol"; +import { ProposalStore, Proposal } from "../stores/ProposalStore.sol"; +import { IERC5805 } from "oz/interfaces/IERC5805.sol"; contract Proposer is BaseActor { AngleGovernor internal _angleGovernor; @@ -55,8 +55,12 @@ contract Proposer is BaseActor { return; } Proposal memory proposal = proposalStore.getRandomProposal(proposalId); - uint256 proposalHash = - _angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); + uint256 proposalHash = _angleGovernor.hashProposal( + proposal.target, + proposal.value, + proposal.data, + proposal.description + ); uint256 proposalSnapshot = _angleGovernor.proposalSnapshot(proposalHash); vm.warp(block.timestamp + _angleGovernor.proposalDeadline(proposalHash)); vm.roll(block.number + _angleGovernor.$snapshotTimestampToSnapshotBlockNumber(proposalSnapshot)); @@ -67,8 +71,8 @@ contract Proposer is BaseActor { IGovernor.GovernorUnexpectedProposalState.selector, proposalHash, currentState, - bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) - | bytes32(1 << uint8(IGovernor.ProposalState.Queued)) + bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) | + bytes32(1 << uint8(IGovernor.ProposalState.Queued)) ) ); } @@ -84,8 +88,12 @@ contract Proposer is BaseActor { return; } Proposal memory proposal = proposalStore.getRandomProposal(proposalId); - uint256 proposalHash = - _angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); + uint256 proposalHash = _angleGovernor.hashProposal( + proposal.target, + proposal.value, + proposal.data, + proposal.description + ); uint256 proposalSnapshot = _angleGovernor.proposalSnapshot(proposalHash); IGovernor.ProposalState currentState = _angleGovernor.state(proposalHash); if (currentState != IGovernor.ProposalState.Succeeded) { @@ -94,8 +102,8 @@ contract Proposer is BaseActor { IGovernor.GovernorUnexpectedProposalState.selector, proposalHash, currentState, - bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) - | bytes32(1 << uint8(IGovernor.ProposalState.Queued)) + bytes32(1 << uint8(IGovernor.ProposalState.Succeeded)) | + bytes32(1 << uint8(IGovernor.ProposalState.Queued)) ) ); } diff --git a/test/invariant/actors/Voter.t.sol b/test/invariant/actors/Voter.t.sol index d5506d2..4b25f4a 100644 --- a/test/invariant/actors/Voter.t.sol +++ b/test/invariant/actors/Voter.t.sol @@ -1,18 +1,21 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import {BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage} from "./BaseActor.t.sol"; -import {console} from "forge-std/console.sol"; -import {ProposalStore, Proposal} from "../stores/ProposalStore.sol"; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; +import { BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage } from "./BaseActor.t.sol"; +import { console } from "forge-std/console.sol"; +import { ProposalStore, Proposal } from "../stores/ProposalStore.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; contract Voter is BaseActor { AngleGovernor internal _angleGovernor; ProposalStore public proposalStore; - constructor(AngleGovernor angleGovernor, IERC20 angle, uint256 nbrVoter, ProposalStore _proposalStore) - BaseActor(nbrVoter, "Voter", angle) - { + constructor( + AngleGovernor angleGovernor, + IERC20 angle, + uint256 nbrVoter, + ProposalStore _proposalStore + ) BaseActor(nbrVoter, "Voter", angle) { _angleGovernor = angleGovernor; proposalStore = _proposalStore; } @@ -23,8 +26,12 @@ contract Voter is BaseActor { } voteOutcome = bound(voteOutcome, 0, 2); Proposal memory proposal = proposalStore.getRandomProposal(proposalSeed); - uint256 proposalHash = - _angleGovernor.hashProposal(proposal.target, proposal.value, proposal.data, proposal.description); + uint256 proposalHash = _angleGovernor.hashProposal( + proposal.target, + proposal.value, + proposal.data, + proposal.description + ); IGovernor.ProposalState currentState = _angleGovernor.state(proposalHash); if (currentState != IGovernor.ProposalState.Active) { vm.expectRevert( diff --git a/test/scripts/ScriptHelpers.t.sol b/test/scripts/ScriptHelpers.t.sol index 5e318e5..f2311cf 100644 --- a/test/scripts/ScriptHelpers.t.sol +++ b/test/scripts/ScriptHelpers.t.sol @@ -2,11 +2,11 @@ pragma solidity ^0.8.9; -import {console} from "forge-std/console.sol"; -import {Vm} from "forge-std/Vm.sol"; -import {stdStorage, StdStorage, Test, stdError} from "forge-std/Test.sol"; +import { console } from "forge-std/console.sol"; +import { Vm } from "forge-std/Vm.sol"; +import { stdStorage, StdStorage, Test, stdError } from "forge-std/Test.sol"; -import {AngleGovernor} from "contracts/AngleGovernor.sol"; +import { AngleGovernor } from "contracts/AngleGovernor.sol"; import "../../scripts/Constants.s.sol"; import "../../scripts/Utils.s.sol"; @@ -21,8 +21,9 @@ contract ScriptHelpers is Test, Utils { // TODO remove when on chain tx are passed to connect chains vm.selectFork(forkIdentifier[CHAIN_SOURCE]); - ProposalSender proposalSender = - ProposalSender(payable(_chainToContract(CHAIN_SOURCE, ContractType.ProposalSender))); + ProposalSender proposalSender = ProposalSender( + payable(_chainToContract(CHAIN_SOURCE, ContractType.ProposalSender)) + ); uint256[] memory ALL_CHAINS = new uint256[](10); ALL_CHAINS[0] = CHAIN_LINEA; ALL_CHAINS[1] = CHAIN_POLYGON; @@ -39,7 +40,8 @@ contract ScriptHelpers is Test, Utils { for (uint256 i; i < ALL_CHAINS.length; i++) { uint256 chainId = ALL_CHAINS[i]; proposalSender.setTrustedRemoteAddress( - _getLZChainId(chainId), abi.encodePacked(_chainToContract(chainId, ContractType.ProposalReceiver)) + _getLZChainId(chainId), + abi.encodePacked(_chainToContract(chainId, ContractType.ProposalReceiver)) ); } vm.stopPrank(); @@ -79,31 +81,34 @@ contract ScriptHelpers is Test, Utils { vm.recordLogs(); hoax(whale); - governor.execute{value: valueEther}(targets, values, calldatas, keccak256(bytes(description))); + governor.execute{ value: valueEther }(targets, values, calldatas, keccak256(bytes(description))); } Vm.Log[] memory entries = vm.getRecordedLogs(); for (uint256 chainCount; chainCount < chainIds.length; chainCount++) { uint256 chainId = chainIds[chainCount]; - TimelockControllerWithCounter timelock = - TimelockControllerWithCounter(payable(_chainToContract(chainId, ContractType.Timelock))); + TimelockControllerWithCounter timelock = TimelockControllerWithCounter( + payable(_chainToContract(chainId, ContractType.Timelock)) + ); if (chainId == CHAIN_SOURCE) { vm.warp(block.timestamp + timelock.getMinDelay() + 1); _executeTimelock(chainId, timelock, targets[chainCount], calldatas[chainCount]); } else { { - ProposalSender proposalSender = - ProposalSender(payable(_chainToContract(CHAIN_SOURCE, ContractType.ProposalSender))); - ProposalReceiver proposalReceiver = - ProposalReceiver(payable(_chainToContract(chainId, ContractType.ProposalReceiver))); + ProposalSender proposalSender = ProposalSender( + payable(_chainToContract(CHAIN_SOURCE, ContractType.ProposalSender)) + ); + ProposalReceiver proposalReceiver = ProposalReceiver( + payable(_chainToContract(chainId, ContractType.ProposalReceiver)) + ); bytes memory payload; { for (uint256 i; i < entries.length; i++) { if ( - entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") - && entries[i].topics[1] == bytes32(uint256(_getLZChainId(chainId))) + entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") && + entries[i].topics[1] == bytes32(uint256(_getLZChainId(chainId))) ) { payload = abi.decode(entries[i].data, (bytes)); break; @@ -114,7 +119,10 @@ contract ScriptHelpers is Test, Utils { vm.selectFork(forkIdentifier[chainId]); hoax(address(_lzEndPoint(chainId))); proposalReceiver.lzReceive( - _getLZChainId(CHAIN_SOURCE), abi.encodePacked(proposalSender, proposalReceiver), 0, payload + _getLZChainId(CHAIN_SOURCE), + abi.encodePacked(proposalSender, proposalReceiver), + 0, + payload ); } @@ -123,13 +131,16 @@ contract ScriptHelpers is Test, Utils { bytes[] memory chainCalldatas; { console.logBytes(calldatas[chainCount]); - (, bytes memory senderData,) = abi.decode( + (, bytes memory senderData, ) = abi.decode( // calldatas[chainCount], _slice(calldatas[chainCount], 4, calldatas[chainCount].length - 4), (uint16, bytes, bytes) ); console.logBytes(senderData); - (chainTargets,,, chainCalldatas) = abi.decode(senderData, (address[], uint256[], string[], bytes[])); + (chainTargets, , , chainCalldatas) = abi.decode( + senderData, + (address[], uint256[], string[], bytes[]) + ); } for (uint256 i; i < chainTargets.length; i++) { @@ -150,8 +161,9 @@ contract ScriptHelpers is Test, Utils { if (target == address(timelock)) { vm.prank(_chainToContract(chainId, ContractType.GuardianMultisig)); if (TimelockControllerWithCounter.schedule.selector == bytes4(_slice(rawData, 0, 4))) { - (address target, uint256 value, bytes memory data, bytes32 predecessor, bytes32 salt,) = abi.decode( - _slice(rawData, 4, rawData.length - 4), (address, uint256, bytes, bytes32, bytes32, uint256) + (address target, uint256 value, bytes memory data, bytes32 predecessor, bytes32 salt, ) = abi.decode( + _slice(rawData, 4, rawData.length - 4), + (address, uint256, bytes, bytes32, bytes32, uint256) ); timelock.execute(target, value, data, predecessor, salt); } else { @@ -161,9 +173,11 @@ contract ScriptHelpers is Test, Utils { bytes[] memory tmpCalldatas, bytes32 predecessor, bytes32 salt, + ) = abi.decode( - _slice(rawData, 4, rawData.length - 4), (address[], uint256[], bytes[], bytes32, bytes32, uint256) - ); + _slice(rawData, 4, rawData.length - 4), + (address[], uint256[], bytes[], bytes32, bytes32, uint256) + ); timelock.executeBatch(tmpTargets, tmpValues, tmpCalldatas, predecessor, salt); } } diff --git a/test/scripts/timelock/AddExecutor.t.sol b/test/scripts/timelock/AddExecutor.t.sol index 87127dc..f88a8b9 100644 --- a/test/scripts/timelock/AddExecutor.t.sol +++ b/test/scripts/timelock/AddExecutor.t.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import {stdJson} from "forge-std/StdJson.sol"; -import {console} from "forge-std/console.sol"; -import {ScriptHelpers} from "../ScriptHelpers.t.sol"; -import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; -import {TimelockController} from "oz-v5/governance/TimelockController.sol"; +import { stdJson } from "forge-std/StdJson.sol"; +import { console } from "forge-std/console.sol"; +import { ScriptHelpers } from "../ScriptHelpers.t.sol"; +import { IAccessControl } from "oz-v5/access/IAccessControl.sol"; +import { TimelockController } from "oz-v5/governance/TimelockController.sol"; import "../../../scripts/Constants.s.sol"; -import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; +import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; contract AddExecutorTest is ScriptHelpers { using stdJson for string; @@ -25,8 +25,9 @@ contract AddExecutorTest is ScriptHelpers { // Now test that everything is as expected for (uint256 i; i < chainIds.length; i++) { uint256 chainId = chainIds[i]; - TimelockControllerWithCounter timelock = - TimelockControllerWithCounter(payable(_chainToContract(chainId, ContractType.Timelock))); + TimelockControllerWithCounter timelock = TimelockControllerWithCounter( + payable(_chainToContract(chainId, ContractType.Timelock)) + ); vm.selectFork(forkIdentifier[chainId]); bytes32 EXECUTOR_ROLE = timelock.EXECUTOR_ROLE(); diff --git a/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol index 90d3ed9..c2896f2 100644 --- a/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol +++ b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol @@ -1,14 +1,14 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import {stdJson} from "forge-std/StdJson.sol"; -import {console} from "forge-std/console.sol"; -import {ScriptHelpers} from "../ScriptHelpers.t.sol"; -import {TransmuterUtils} from "../../../scripts/proposals/transmuter/TransmuterUtils.s.sol"; +import { stdJson } from "forge-std/StdJson.sol"; +import { console } from "forge-std/console.sol"; +import { ScriptHelpers } from "../ScriptHelpers.t.sol"; +import { TransmuterUtils } from "../../../scripts/proposals/transmuter/TransmuterUtils.s.sol"; import "../../../scripts/Constants.s.sol"; -import {OldTransmuter} from "../../../scripts/interfaces/ITransmuter.sol"; +import { OldTransmuter } from "../../../scripts/interfaces/ITransmuter.sol"; import "transmuter/transmuter/Storage.sol" as Storage; -import {AggregatorV3Interface} from "transmuter/interfaces/external/chainlink/AggregatorV3Interface.sol"; +import { AggregatorV3Interface } from "transmuter/interfaces/external/chainlink/AggregatorV3Interface.sol"; contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { using stdJson for string; @@ -19,7 +19,8 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { // TODO COMPLETE bytes public oracleConfigDataEUROC = hex"0000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000"; - // + + // function setUp() public override { super.setUp(); @@ -84,23 +85,15 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { bytes memory targetData, bytes memory hyperparams ) = abi.decode( - collatInfoEUROC.oracleConfig, (Storage.OracleReadType, Storage.OracleReadType, bytes, bytes, bytes) - ); + collatInfoEUROC.oracleConfig, + (Storage.OracleReadType, Storage.OracleReadType, bytes, bytes, bytes) + ); assertEq(uint8(oracleType), uint8(8)); assertEq(uint8(targetType), uint8(3)); - assertEq( - oracleData, - hex"" - ); - assertEq( - targetData, - hex"" - ); - assertEq( - hyperparams, - abi.encode(FIREWALL_MINT_BC3M, USER_PROTECTION_BC3M) - ); + assertEq(oracleData, hex""); + assertEq(targetData, hex""); + assertEq(hyperparams, abi.encode(FIREWALL_MINT_BC3M, USER_PROTECTION_BC3M)); } assertEq(collatInfoEUROC.whitelistData.length, 0); assertEq(collatInfoEUROC.managerData.subCollaterals.length, 0); @@ -152,32 +145,32 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { bytes memory targetData, bytes memory hyperparams ) = abi.decode( - collatInfoBC3M.oracleConfig, (Storage.OracleReadType, Storage.OracleReadType, bytes, bytes, bytes) - ); + collatInfoBC3M.oracleConfig, + (Storage.OracleReadType, Storage.OracleReadType, bytes, bytes, bytes) + ); assertEq(uint8(oracleType), uint8(0)); assertEq(uint8(targetType), uint8(9)); - assertEq( - oracleData, - oracleConfigDataEUROC - ); + assertEq(oracleData, oracleConfigDataEUROC); assertEq( hyperparams, abi.encode(FIREWALL_MINT_BC3M, USER_PROTECTION_BC3M) // hex"0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000002386f26fc10000" ); - (uint256 maxValue, uint96 deviationThreshold, uint96 lastUpdateTimestamp, uint32 heartbeat) = - abi.decode(targetData, (uint256, uint96, uint96, uint32)); + (uint256 maxValue, uint96 deviationThreshold, uint96 lastUpdateTimestamp, uint32 heartbeat) = abi + .decode(targetData, (uint256, uint96, uint96, uint32)); - assertApproxEqRel(maxValue, 1195 * BASE_18 / 10, 10 * BPS); + assertApproxEqRel(maxValue, (1195 * BASE_18) / 10, 10 * BPS); assertEq(deviationThreshold, DEVIATION_THRESHOLD_BC3M); assertEq(heartbeat, HEARTBEAT); } { - (Storage.WhitelistType whitelist, bytes memory data) = - abi.decode(collatInfoBC3M.whitelistData, (Storage.WhitelistType, bytes)); + (Storage.WhitelistType whitelist, bytes memory data) = abi.decode( + collatInfoBC3M.whitelistData, + (Storage.WhitelistType, bytes) + ); address keyringGuard = abi.decode(data, (address)); assertEq(uint8(whitelist), uint8(Storage.WhitelistType.BACKED)); assertEq(keyringGuard, 0x9391B14dB2d43687Ea1f6E546390ED4b20766c46); @@ -223,26 +216,36 @@ contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { CHECKS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - function _checkOracleValues(address collateral, uint256 targetValue, uint128 firewallMint, uint128 userProtection) - internal - { - (uint256 mint, uint256 burn, uint256 ratio, uint256 minRatio, uint256 redemption) = - transmuter.getOracleValues(collateral); + function _checkOracleValues( + address collateral, + uint256 targetValue, + uint128 firewallMint, + uint128 userProtection + ) internal { + (uint256 mint, uint256 burn, uint256 ratio, uint256 minRatio, uint256 redemption) = transmuter.getOracleValues( + collateral + ); assertApproxEqRel(targetValue, redemption, 200 * BPS); - if (targetValue * (BASE_18 - userProtection) < redemption * BASE_18 && redemption * BASE_18 < targetValue * (BASE_18 + userProtection) ) assertEq(burn, targetValue); + if ( + targetValue * (BASE_18 - userProtection) < redemption * BASE_18 && + redemption * BASE_18 < targetValue * (BASE_18 + userProtection) + ) assertEq(burn, targetValue); else assertEq(burn, redemption); - - if(targetValue * (BASE_18 - userProtection) < redemption * BASE_18 && redemption * BASE_18 < targetValue * (BASE_18 + userProtection)){ - assertEq(mint,targetValue); - assertEq(ratio,BASE_18); + + if ( + targetValue * (BASE_18 - userProtection) < redemption * BASE_18 && + redemption * BASE_18 < targetValue * (BASE_18 + userProtection) + ) { + assertEq(mint, targetValue); + assertEq(ratio, BASE_18); } else if (redemption * BASE_18 > targetValue * (BASE_18 + firewallMint)) { assertEq(mint, targetValue); assertEq(ratio, BASE_18); - } else if(redemption < targetValue){ + } else if (redemption < targetValue) { assertEq(mint, redemption); assertEq(ratio, (redemption * BASE_18) / targetValue); - } else{ + } else { assertEq(mint, redemption); assertEq(ratio, BASE_18); } diff --git a/test/unit/AngleGovernor.t.sol b/test/unit/AngleGovernor.t.sol index 266c741..2587ab0 100644 --- a/test/unit/AngleGovernor.t.sol +++ b/test/unit/AngleGovernor.t.sol @@ -2,18 +2,18 @@ pragma solidity ^0.8.9; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {Strings} from "oz-v5/utils/Strings.sol"; - -import {Test, stdError} from "forge-std/Test.sol"; -import {Vm} from "forge-std/Vm.sol"; - -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {VeANGLEVotingDelegation} from "contracts/VeANGLEVotingDelegation.sol"; -import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { Strings } from "oz-v5/utils/Strings.sol"; + +import { Test, stdError } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; + +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { VeANGLEVotingDelegation } from "contracts/VeANGLEVotingDelegation.sol"; +import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Utils.t.sol"; @@ -87,8 +87,12 @@ contract AngleGovernorTest is Test, Utils { executors[0] = address(0); // Means everyone can execute vm.startPrank(alice); - TimelockControllerWithCounter mainnetTimelock2 = - new TimelockControllerWithCounter(1 days, proposers, executors, address(this)); + TimelockControllerWithCounter mainnetTimelock2 = new TimelockControllerWithCounter( + 1 days, + proposers, + executors, + address(this) + ); vm.expectRevert(Errors.NotExecutor.selector); angleGovernor.updateTimelock(address(mainnetTimelock2)); vm.expectRevert(Errors.NotExecutor.selector); @@ -113,8 +117,12 @@ contract AngleGovernorTest is Test, Utils { address[] memory proposers = new address[](0); address[] memory executors = new address[](1); executors[0] = address(0); // Means everyone can execute - TimelockControllerWithCounter mainnetTimelock2 = - new TimelockControllerWithCounter(1 days, proposers, executors, address(this)); + TimelockControllerWithCounter mainnetTimelock2 = new TimelockControllerWithCounter( + 1 days, + proposers, + executors, + address(this) + ); vm.expectRevert(Errors.ZeroAddress.selector); hoax(address(mainnetTimelock)); diff --git a/test/unit/GovernorShortCircuit.t.sol b/test/unit/GovernorShortCircuit.t.sol index d2a1971..4e88117 100644 --- a/test/unit/GovernorShortCircuit.t.sol +++ b/test/unit/GovernorShortCircuit.t.sol @@ -2,21 +2,21 @@ pragma solidity ^0.8.9; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {GovernorCountingSimple} from "oz-v5/governance/extensions/GovernorCountingSimple.sol"; -import {Strings} from "oz-v5/utils/Strings.sol"; -import {ERC20} from "oz-v5/token/ERC20/ERC20.sol"; - -import {stdStorage, StdStorage, Test, stdError} from "forge-std/Test.sol"; -import {Vm} from "forge-std/Vm.sol"; - -import {deployMockANGLE, MockANGLE} from "../../scripts/test/DeployANGLE.s.sol"; -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {VeANGLEVotingDelegation} from "contracts/VeANGLEVotingDelegation.sol"; -import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { GovernorCountingSimple } from "oz-v5/governance/extensions/GovernorCountingSimple.sol"; +import { Strings } from "oz-v5/utils/Strings.sol"; +import { ERC20 } from "oz-v5/token/ERC20/ERC20.sol"; + +import { stdStorage, StdStorage, Test, stdError } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; + +import { deployMockANGLE, MockANGLE } from "../../scripts/test/DeployANGLE.s.sol"; +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { VeANGLEVotingDelegation } from "contracts/VeANGLEVotingDelegation.sol"; +import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Utils.t.sol"; @@ -45,7 +45,7 @@ contract GovernorShortCircuitTest is Test, Utils { vm.roll(block.number + 1152); vm.warp(block.timestamp + 10 days); - (address _mockANGLE,,) = deployMockANGLE(); + (address _mockANGLE, , ) = deployMockANGLE(); ANGLE = MockANGLE(_mockANGLE); veANGLEDelegation = new VeANGLEVotingDelegation(address(veANGLE), "veANGLE Delegation", "1"); @@ -92,10 +92,11 @@ contract GovernorShortCircuitTest is Test, Utils { angleGovernor.castVote(proposalId, uint8(GovernorCountingSimple.VoteType.Against)); } - function _proposeTx(address[] memory targets, uint256[] memory values, bytes[] memory calldatas) - public - returns (uint256 pid) - { + function _proposeTx( + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas + ) public returns (uint256 pid) { vm.mockCall( address(veANGLEDelegation), abi.encodeWithSelector(veANGLEDelegation.getPastVotes.selector, address(proposer)), @@ -126,7 +127,9 @@ contract GovernorShortCircuitTest is Test, Utils { mineBlocksBySecond(angleGovernor.votingPeriod()); assertEq( - uint256(IGovernor.ProposalState.Succeeded), uint256(angleGovernor.state(pid)), "Proposal state is succeeded" + uint256(IGovernor.ProposalState.Succeeded), + uint256(angleGovernor.state(pid)), + "Proposal state is succeeded" ); stdstore.target(address(angleGovernor)).sig("timelock()").checked_write(address(angleGovernor)); @@ -187,7 +190,9 @@ contract GovernorShortCircuitTest is Test, Utils { _votePassingQuorum(pid); assertEq( - uint256(IGovernor.ProposalState.Succeeded), uint256(angleGovernor.state(pid)), "Proposal state is succeeded" + uint256(IGovernor.ProposalState.Succeeded), + uint256(angleGovernor.state(pid)), + "Proposal state is succeeded" ); // majorityFor allows skipping delay but still timelock @@ -196,7 +201,9 @@ contract GovernorShortCircuitTest is Test, Utils { assertEq(ANGLE.balanceOf(bob), amount, "Bob received ANGLE"); assertEq(ANGLE.balanceOf(address(angleGovernor)), 0, "angleGovernor has no ANGLE"); assertEq( - uint256(IGovernor.ProposalState.Executed), uint256(angleGovernor.state(pid)), "Proposal state is executed" + uint256(IGovernor.ProposalState.Executed), + uint256(angleGovernor.state(pid)), + "Proposal state is executed" ); } @@ -228,7 +235,9 @@ contract GovernorShortCircuitTest is Test, Utils { _voteDefeatQuorum(pid); assertEq( - uint256(IGovernor.ProposalState.Defeated), uint256(angleGovernor.state(pid)), "Proposal state is defeated" + uint256(IGovernor.ProposalState.Defeated), + uint256(angleGovernor.state(pid)), + "Proposal state is defeated" ); vm.expectRevert( diff --git a/test/unit/GovernorStateAndPropose.t.sol b/test/unit/GovernorStateAndPropose.t.sol index d6033c5..828b7bc 100644 --- a/test/unit/GovernorStateAndPropose.t.sol +++ b/test/unit/GovernorStateAndPropose.t.sol @@ -2,18 +2,18 @@ pragma solidity ^0.8.9; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {Strings} from "oz-v5/utils/Strings.sol"; - -import {Test, stdError} from "forge-std/Test.sol"; -import {Vm} from "forge-std/Vm.sol"; - -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {VeANGLEVotingDelegation} from "contracts/VeANGLEVotingDelegation.sol"; -import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { Strings } from "oz-v5/utils/Strings.sol"; + +import { Test, stdError } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; + +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { VeANGLEVotingDelegation } from "contracts/VeANGLEVotingDelegation.sol"; +import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Utils.t.sol"; @@ -81,7 +81,10 @@ contract GovernorStateAndProposeTest is Test, Utils { vm.expectRevert( abi.encodeWithSelector( - IGovernor.GovernorInsufficientProposerVotes.selector, whale, votes, angleGovernor.proposalThreshold() + IGovernor.GovernorInsufficientProposerVotes.selector, + whale, + votes, + angleGovernor.proposalThreshold() ) ); hoax(whale); @@ -107,7 +110,10 @@ contract GovernorStateAndProposeTest is Test, Utils { vm.expectRevert( abi.encodeWithSelector( - IGovernor.GovernorInvalidProposalLength.selector, targets.length, calldatas.length, values.length + IGovernor.GovernorInvalidProposalLength.selector, + targets.length, + calldatas.length, + values.length ) ); hoax(whale); @@ -124,7 +130,10 @@ contract GovernorStateAndProposeTest is Test, Utils { vm.expectRevert( abi.encodeWithSelector( - IGovernor.GovernorInvalidProposalLength.selector, targets.length, calldatas.length, values.length + IGovernor.GovernorInvalidProposalLength.selector, + targets.length, + calldatas.length, + values.length ) ); hoax(whale); @@ -144,7 +153,10 @@ contract GovernorStateAndProposeTest is Test, Utils { vm.expectRevert( abi.encodeWithSelector( - IGovernor.GovernorInvalidProposalLength.selector, targets.length, calldatas.length, values.length + IGovernor.GovernorInvalidProposalLength.selector, + targets.length, + calldatas.length, + values.length ) ); hoax(whale); diff --git a/test/unit/ProposalLayerZeroRelayer.t.sol b/test/unit/ProposalLayerZeroRelayer.t.sol index fa3deb6..987eeff 100644 --- a/test/unit/ProposalLayerZeroRelayer.t.sol +++ b/test/unit/ProposalLayerZeroRelayer.t.sol @@ -2,23 +2,23 @@ pragma solidity ^0.8.9; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; -import {Strings} from "oz-v5/utils/Strings.sol"; - -import {console} from "forge-std/console.sol"; -import {Test, stdError} from "forge-std/Test.sol"; -import {Vm} from "forge-std/Vm.sol"; - -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender, Ownable} from "contracts/ProposalSender.sol"; -import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; - -import {SubCall} from "./Proposal.sol"; -import {SimulationSetup} from "./SimulationSetup.t.sol"; -import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { IAccessControl } from "oz-v5/access/IAccessControl.sol"; +import { Strings } from "oz-v5/utils/Strings.sol"; + +import { console } from "forge-std/console.sol"; +import { Test, stdError } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; + +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender, Ownable } from "contracts/ProposalSender.sol"; +import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; + +import { SubCall } from "./Proposal.sol"; +import { SimulationSetup } from "./SimulationSetup.t.sol"; +import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Constants.t.sol"; @@ -47,7 +47,7 @@ contract ProposalLayerZeroRelayer is SimulationSetup { timelock(destChain).grantRole.selector, timelock(destChain).PROPOSER_ROLE(), address(newReceiverOptimism) - ) + ) }); p[1] = SubCall({ chainId: destChain, @@ -57,7 +57,7 @@ contract ProposalLayerZeroRelayer is SimulationSetup { timelock(destChain).revokeRole.selector, timelock(destChain).PROPOSER_ROLE(), address(proposalReceiver(destChain)) - ) + ) }); string memory description = "Updating relayer receiver on Optimism"; _crossChainProposal(destChain, p, description, 0.1 ether, hex"", address(0)); @@ -130,7 +130,11 @@ contract ProposalLayerZeroRelayer is SimulationSetup { targets[0] = address(proposalSender()); values[0] = 0; calldatas[0] = abi.encodeWithSelector( - proposalSender().setConfig.selector, version, chainId, configType, abi.encode(blockConfirmation) + proposalSender().setConfig.selector, + version, + chainId, + configType, + abi.encode(blockConfirmation) ); string memory description = "Updating config on Mainnet"; @@ -178,13 +182,15 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") + address(_lzEndPoint(1)), + abi.encodeWithSelector(_lzEndPoint(1).send.selector), + abi.encode("REVERT") ); assertEq(uint256(proposalSender().lastStoredPayloadNonce()), 0); _dummyProposal(1, p, description, 0.1 ether, hex""); assertEq(uint256(proposalSender().lastStoredPayloadNonce()), 1); - bytes memory payload = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); (uint256 nativeFee, uint256 zroFee) = proposalSender().estimateFees(_getLZChainId(137), payload, adapterParams); assertEq(zroFee, 0); @@ -212,7 +218,9 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") + address(_lzEndPoint(1)), + abi.encodeWithSelector(_lzEndPoint(1).send.selector), + abi.encode("REVERT") ); _dummyProposal(1, p, description, 0.1 ether, hex""); vm.expectRevert(abi.encodeWithSelector(Errors.OmnichainProposalSenderInvalidExecParams.selector)); @@ -238,10 +246,10 @@ contract ProposalLayerZeroRelayer is SimulationSetup { abi.encodeWithSelector(_lzEndPoint(srcChain).send.selector), abi.encode("REVERT") ); - bytes memory payload = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); - (uint256 nativeFee,) = proposalSender().estimateFees(_getLZChainId(destChain), payload, adapterParams); + (uint256 nativeFee, ) = proposalSender().estimateFees(_getLZChainId(destChain), payload, adapterParams); assertLe(nativeFee, 0.1 ether); _dummyProposal(srcChain, p, description, 0.1 ether, hex""); vm.clearMockedCalls(); @@ -254,13 +262,18 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(srcChain), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload + _getLZChainId(srcChain), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload ); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + timelock(destChain).getMinDelay() + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p + ); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -280,10 +293,12 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") + address(_lzEndPoint(1)), + abi.encodeWithSelector(_lzEndPoint(1).send.selector), + abi.encode("REVERT") ); - bytes memory payload1 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -293,12 +308,14 @@ contract ProposalLayerZeroRelayer is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) - ) + timelock(destChain).grantRole.selector, + timelock(1).PROPOSER_ROLE(), + address(alice) + ) }); description = "Grant role on Optimism"; - bytes memory payload2 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -315,15 +332,20 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload1 ); uint256 oldDelay = timelock(destChain).getMinDelay(); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p1); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p1 + ); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -331,13 +353,18 @@ contract ProposalLayerZeroRelayer is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload2 ); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p2); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p2 + ); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -358,10 +385,12 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") + address(_lzEndPoint(1)), + abi.encodeWithSelector(_lzEndPoint(1).send.selector), + abi.encode("REVERT") ); - bytes memory payload1 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -371,12 +400,14 @@ contract ProposalLayerZeroRelayer is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) - ) + timelock(destChain).grantRole.selector, + timelock(1).PROPOSER_ROLE(), + address(alice) + ) }); description = "Grant role on Optimism"; - bytes memory payload2 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -393,15 +424,20 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload2 ); uint256 oldDelay = timelock(destChain).getMinDelay(); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p2); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p2 + ); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -409,13 +445,18 @@ contract ProposalLayerZeroRelayer is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload1 ); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p1); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p1 + ); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -436,10 +477,12 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") + address(_lzEndPoint(1)), + abi.encodeWithSelector(_lzEndPoint(1).send.selector), + abi.encode("REVERT") ); - bytes memory payload1 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -449,12 +492,14 @@ contract ProposalLayerZeroRelayer is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) - ) + timelock(destChain).grantRole.selector, + timelock(1).PROPOSER_ROLE(), + address(alice) + ) }); description = "Grant role on Optimism"; - bytes memory payload2 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -471,15 +516,20 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload1 ); uint256 oldDelay = timelock(destChain).getMinDelay(); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p1); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p1 + ); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -487,13 +537,18 @@ contract ProposalLayerZeroRelayer is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload2 ); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p2); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p2 + ); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -514,10 +569,12 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") + address(_lzEndPoint(1)), + abi.encodeWithSelector(_lzEndPoint(1).send.selector), + abi.encode("REVERT") ); - bytes memory payload1 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -527,12 +584,14 @@ contract ProposalLayerZeroRelayer is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) - ) + timelock(destChain).grantRole.selector, + timelock(1).PROPOSER_ROLE(), + address(alice) + ) }); description = "Grant role on Optimism"; - bytes memory payload2 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -549,15 +608,20 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload2 ); uint256 oldDelay = timelock(destChain).getMinDelay(); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p2); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p2 + ); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -565,13 +629,18 @@ contract ProposalLayerZeroRelayer is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload1 ); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p1); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p1 + ); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -593,17 +662,21 @@ contract ProposalLayerZeroRelayer is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) - ) + timelock(destChain).grantRole.selector, + timelock(1).PROPOSER_ROLE(), + address(alice) + ) }); string memory description = "Batch delay and grantRole on Optimism"; vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") + address(_lzEndPoint(1)), + abi.encodeWithSelector(_lzEndPoint(1).send.selector), + abi.encode("REVERT") ); - bytes memory payload = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002c48f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002c48f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p, description, 0.1 ether, hex""); vm.clearMockedCalls(); @@ -616,13 +689,18 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload ); vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + timelock(destChain).getMinDelay() + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p + ); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).executeBatch(targets, values, calldatas, bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -634,8 +712,12 @@ contract ProposalLayerZeroRelayer is SimulationSetup { address[] memory proposers = new address[](0); address[] memory executors = new address[](1); executors[0] = address(0); // Means everyone can execute - TimelockControllerWithCounter timelock2 = - new TimelockControllerWithCounter(1 days, proposers, executors, address(this)); + TimelockControllerWithCounter timelock2 = new TimelockControllerWithCounter( + 1 days, + proposers, + executors, + address(this) + ); AngleGovernor governor2 = new AngleGovernor( veANGLEDelegation, address(timelock2), @@ -667,7 +749,7 @@ contract ProposalLayerZeroRelayer is SimulationSetup { proposalSender(), 0, abi.encodeWithSelector(proposalSender().transferOwnership.selector, address(governor2)) - ) + ) }); (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = wrap(p); @@ -722,23 +804,31 @@ contract ProposalLayerZeroRelayer is SimulationSetup { chainId: 137, target: address(timelock(137)), value: 0, - data: abi.encodeWithSelector(timelock(1).grantRole.selector, timelock(1).PROPOSER_ROLE(), newProposalReceiver) + data: abi.encodeWithSelector( + timelock(1).grantRole.selector, + timelock(1).PROPOSER_ROLE(), + newProposalReceiver + ) }); p[1] = SubCall({ chainId: 137, target: address(timelock(137)), value: 0, data: abi.encodeWithSelector( - timelock(1).revokeRole.selector, timelock(1).PROPOSER_ROLE(), address(proposalReceiver(137)) - ) + timelock(1).revokeRole.selector, + timelock(1).PROPOSER_ROLE(), + address(proposalReceiver(137)) + ) }); p[2] = SubCall({ chainId: 1, target: address(proposalSender()), value: 0, data: abi.encodeWithSelector( - proposalSender().setTrustedRemoteAddress.selector, _getLZChainId(137), abi.encodePacked(proposalReceiver2) - ) + proposalSender().setTrustedRemoteAddress.selector, + _getLZChainId(137), + abi.encodePacked(proposalReceiver2) + ) }); string memory description = "Updating Proposal receiver on Polygon"; @@ -755,14 +845,14 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.warp(block.timestamp + governor().votingPeriod() + 1); vm.recordLogs(); - governor().execute{value: 0.1 ether}(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value + governor().execute{ value: 0.1 ether }(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value Vm.Log[] memory entries = vm.getRecordedLogs(); bytes memory payload; for (uint256 i; i < entries.length; i++) { if ( - entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") - && entries[i].topics[1] == bytes32(uint256(_getLZChainId(137))) + entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") && + entries[i].topics[1] == bytes32(uint256(_getLZChainId(137))) ) { payload = abi.decode(entries[i].data, (bytes)); break; @@ -772,7 +862,10 @@ contract ProposalLayerZeroRelayer is SimulationSetup { vm.selectFork(forkIdentifier[137]); hoax(address(_lzEndPoint(137))); proposalReceiver(137).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(137)), 0, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(137)), + 0, + payload ); // Final test @@ -802,8 +895,8 @@ contract ProposalLayerZeroRelayer is SimulationSetup { assertEq(uint256(proposalSender().lastStoredPayloadNonce()), 0); vm.selectFork(forkIdentifier[destChain]); - bytes memory payload = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); bytes memory execution = abi.encode(_getLZChainId(destChain), payload, adapterParams, 0.1 ether); vm.mockCallRevert( @@ -813,29 +906,42 @@ contract ProposalLayerZeroRelayer is SimulationSetup { ); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload ); assertEq( proposalReceiver(destChain).failedMessages( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0 ), keccak256(payload) ); vm.expectRevert(Errors.OmnichainGovernanceExecutorTxExecReverted.selector); proposalReceiver(destChain).retryMessage( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload ); vm.clearMockedCalls(); assertEq(timelock(destChain).getMinDelay() != 100, true); proposalReceiver(destChain).retryMessage( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload ); vm.warp(block.timestamp + timelock(destChain).getMinDelay() + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p + ); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); } @@ -866,8 +972,8 @@ contract ProposalLayerZeroRelayer is SimulationSetup { assertEq(uint256(proposalSender().lastStoredPayloadNonce()), 0); vm.selectFork(forkIdentifier[destChain]); - bytes memory payload = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); bytes memory execution = abi.encode(_getLZChainId(destChain), payload, adapterParams, 0.1 ether); vm.mockCallRevert( @@ -877,29 +983,42 @@ contract ProposalLayerZeroRelayer is SimulationSetup { ); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 1, + payload ); assertEq( proposalReceiver(destChain).failedMessages( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 1 ), keccak256(payload) ); vm.expectRevert(Errors.OmnichainGovernanceExecutorTxExecReverted.selector); proposalReceiver(destChain).retryMessage( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 1, + payload ); vm.clearMockedCalls(); assertEq(timelock(destChain).getMinDelay() != 100, true); proposalReceiver(destChain).retryMessage( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 1, + payload ); vm.warp(block.timestamp + oldDelay + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p + ); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); } @@ -934,8 +1053,8 @@ contract ProposalLayerZeroRelayer is SimulationSetup { } vm.selectFork(forkIdentifier[destChain]); - bytes memory payload = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; vm.mockCallRevert( address(timelock(destChain)), abi.encodeWithSelector(timelock(destChain).schedule.selector), @@ -943,18 +1062,26 @@ contract ProposalLayerZeroRelayer is SimulationSetup { ); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 1, + payload ); vm.clearMockedCalls(); assertEq(timelock(destChain).getMinDelay() != oldDelay, true); proposalReceiver(destChain).retryMessage( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 1, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 1, + payload ); vm.warp(block.timestamp + newDelay + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p + ); vm.expectRevert( abi.encodeWithSelector( TimelockController.TimelockUnexpectedOperationState.selector, @@ -991,7 +1118,9 @@ contract ProposalLayerZeroRelayer is SimulationSetup { string memory description = "Updating delay on Optimism"; bytes memory error = abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, alice, timelock(1).EXECUTOR_ROLE() + IAccessControl.AccessControlUnauthorizedAccount.selector, + alice, + timelock(1).EXECUTOR_ROLE() ); _crossChainProposal(destChain, p, description, 0.1 ether, error, alice); } diff --git a/test/unit/Scenarios.t.sol b/test/unit/Scenarios.t.sol index 948b257..27fd15b 100644 --- a/test/unit/Scenarios.t.sol +++ b/test/unit/Scenarios.t.sol @@ -2,22 +2,22 @@ pragma solidity ^0.8.9; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {Strings} from "oz-v5/utils/Strings.sol"; - -import {console} from "forge-std/console.sol"; -import {Test, stdError} from "forge-std/Test.sol"; -import {Vm} from "forge-std/Vm.sol"; - -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; - -import {SubCall} from "./Proposal.sol"; -import {SimulationSetup} from "./SimulationSetup.t.sol"; -import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { Strings } from "oz-v5/utils/Strings.sol"; + +import { console } from "forge-std/console.sol"; +import { Test, stdError } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; + +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; + +import { SubCall } from "./Proposal.sol"; +import { SimulationSetup } from "./SimulationSetup.t.sol"; +import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "../Constants.t.sol"; //solhint-disable @@ -125,14 +125,14 @@ contract Scenarios is SimulationSetup { vm.warp(block.timestamp + governor().votingPeriod() + 1); vm.recordLogs(); - governor().execute{value: 0.1 ether}(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value + governor().execute{ value: 0.1 ether }(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value Vm.Log[] memory entries = vm.getRecordedLogs(); bytes memory payload; for (uint256 i; i < entries.length; i++) { if ( - entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") - && entries[i].topics[1] == bytes32(uint256(_getLZChainId(137))) + entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") && + entries[i].topics[1] == bytes32(uint256(_getLZChainId(137))) ) { payload = abi.decode(entries[i].data, (bytes)); break; @@ -142,7 +142,10 @@ contract Scenarios is SimulationSetup { vm.selectFork(forkIdentifier[137]); hoax(address(_lzEndPoint(137))); proposalReceiver(137).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(137)), 0, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(137)), + 0, + payload ); // Final test diff --git a/test/unit/Simulate.t.sol b/test/unit/Simulate.t.sol index 9af05cb..361f63b 100644 --- a/test/unit/Simulate.t.sol +++ b/test/unit/Simulate.t.sol @@ -2,20 +2,20 @@ pragma solidity ^0.8.9; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {Strings} from "oz-v5/utils/Strings.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { Strings } from "oz-v5/utils/Strings.sol"; -import {console} from "forge-std/console.sol"; -import {Vm} from "forge-std/Vm.sol"; +import { console } from "forge-std/console.sol"; +import { Vm } from "forge-std/Vm.sol"; -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; -import {Proposal, SubCall} from "./Proposal.sol"; -import {SimulationSetup} from "./SimulationSetup.t.sol"; -import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import { Proposal, SubCall } from "./Proposal.sol"; +import { SimulationSetup } from "./SimulationSetup.t.sol"; +import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "stringutils/strings.sol"; import "../Constants.t.sol"; @@ -36,11 +36,11 @@ contract ProposalSimulateTest is SimulationSetup { vm.warp(block.timestamp + governor().votingPeriod() + 1); vm.recordLogs(); - governor().execute{value: 1 ether}(targets, values, calldatas, keccak256(bytes(description))); + governor().execute{ value: 1 ether }(targets, values, calldatas, keccak256(bytes(description))); Vm.Log[] memory entries = vm.getRecordedLogs(); // Mainnet execution - (address[] memory batchTargets,,) = filterChainSubCalls(1, p); + (address[] memory batchTargets, , ) = filterChainSubCalls(1, p); if (batchTargets.length > 0) { executeTimelock(1, p); } @@ -52,7 +52,10 @@ contract ProposalSimulateTest is SimulationSetup { vm.selectFork(forkIdentifier[chainId]); hoax(address(_lzEndPoint(chainId))); proposalReceiver(chainId).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(chainId)), 0, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(chainId)), + 0, + payload ); // Final test diff --git a/test/unit/SimulationSetup.t.sol b/test/unit/SimulationSetup.t.sol index 35c6d43..9c0f24c 100644 --- a/test/unit/SimulationSetup.t.sol +++ b/test/unit/SimulationSetup.t.sol @@ -2,22 +2,22 @@ pragma solidity ^0.8.9; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {Strings} from "oz-v5/utils/Strings.sol"; - -import {console} from "forge-std/console.sol"; -import {Test, stdError} from "forge-std/Test.sol"; -import {Vm} from "forge-std/Vm.sol"; - -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender} from "contracts/ProposalSender.sol"; -import {VeANGLEVotingDelegation} from "contracts/VeANGLEVotingDelegation.sol"; -import {TimelockControllerWithCounter} from "contracts/TimelockControllerWithCounter.sol"; - -import {Proposal, SubCall} from "./Proposal.sol"; -import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { Strings } from "oz-v5/utils/Strings.sol"; + +import { console } from "forge-std/console.sol"; +import { Test, stdError } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; + +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender } from "contracts/ProposalSender.sol"; +import { VeANGLEVotingDelegation } from "contracts/VeANGLEVotingDelegation.sol"; +import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; + +import { Proposal, SubCall } from "./Proposal.sol"; +import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "stringutils/strings.sol"; import "utils/src/CommonUtils.sol"; @@ -68,7 +68,12 @@ contract SimulationSetup is Test, CommonUtils { address[] memory executors = new address[](1); executors[0] = address(0); // Means everyone can execute - _timelocks[chainIds[i]] = new TimelockControllerWithCounter(1 days, proposers, executors, address(this)); + _timelocks[chainIds[i]] = new TimelockControllerWithCounter( + 1 days, + proposers, + executors, + address(this) + ); _governor = new AngleGovernor( veANGLEDelegation, address(_timelocks[chainIds[i]]), @@ -90,21 +95,29 @@ contract SimulationSetup is Test, CommonUtils { address[] memory executors = new address[](1); executors[0] = address(0); // Means everyone can execute - _timelocks[chainIds[i]] = new TimelockControllerWithCounter(1 days, proposers, executors, address(this)); + _timelocks[chainIds[i]] = new TimelockControllerWithCounter( + 1 days, + proposers, + executors, + address(this) + ); _proposalReceivers[chainIds[i]] = new ProposalReceiver(address(_lzEndPoint(chainIds[i]))); _timelocks[chainIds[i]].grantRole( - _timelocks[chainIds[i]].PROPOSER_ROLE(), address(_proposalReceivers[chainIds[i]]) + _timelocks[chainIds[i]].PROPOSER_ROLE(), + address(_proposalReceivers[chainIds[i]]) ); _timelocks[chainIds[i]].grantRole(_timelocks[chainIds[i]].CANCELLER_ROLE(), multisig(chainIds[i])); vm.selectFork(forkIdentifier[1]); _proposalSender.setTrustedRemoteAddress( - _getLZChainId(chainIds[i]), abi.encodePacked(_proposalReceivers[chainIds[i]]) + _getLZChainId(chainIds[i]), + abi.encodePacked(_proposalReceivers[chainIds[i]]) ); vm.selectFork(forkIdentifier[chainIds[i]]); _proposalReceivers[chainIds[i]].setTrustedRemoteAddress( - _getLZChainId(1), abi.encodePacked(_proposalSender) + _getLZChainId(1), + abi.encodePacked(_proposalSender) ); _proposalReceivers[chainIds[i]].transferOwnership(address(_timelocks[chainIds[i]])); } @@ -150,10 +163,9 @@ contract SimulationSetup is Test, CommonUtils { // TODO USE IT /// @notice Build the governor proposal based on all the transaction that need to be executed - function wrap(SubCall[] memory prop) - internal - returns (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) - { + function wrap( + SubCall[] memory prop + ) internal returns (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) { targets = new address[](prop.length); values = new uint256[](prop.length); calldatas = new bytes[](prop.length); @@ -177,17 +189,25 @@ contract SimulationSetup is Test, CommonUtils { if (chainId == 1) { vm.selectFork(forkIdentifier[1]); - (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) = - filterChainSubCalls(chainId, prop); - (targets[finalPropLength], values[finalPropLength], calldatas[finalPropLength]) = - wrapTimelock(chainId, prop); + ( + address[] memory batchTargets, + uint256[] memory batchValues, + bytes[] memory batchCalldatas + ) = filterChainSubCalls(chainId, prop); + (targets[finalPropLength], values[finalPropLength], calldatas[finalPropLength]) = wrapTimelock( + chainId, + prop + ); finalPropLength += 1; i += count; } else { vm.selectFork(forkIdentifier[chainId]); - (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) = - filterChainSubCalls(chainId, prop); + ( + address[] memory batchTargets, + uint256[] memory batchValues, + bytes[] memory batchCalldatas + ) = filterChainSubCalls(chainId, prop); (address target, uint256 value, bytes memory data) = wrapTimelock(chainId, prop); batchTargets = new address[](1); @@ -218,7 +238,10 @@ contract SimulationSetup is Test, CommonUtils { vm.selectFork(forkIdentifier[1]); // Set back the fork to mainnet } - function filterChainSubCalls(uint256 chainId, SubCall[] memory prop) + function filterChainSubCalls( + uint256 chainId, + SubCall[] memory prop + ) internal pure returns (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) @@ -243,13 +266,15 @@ contract SimulationSetup is Test, CommonUtils { } } - function wrapTimelock(uint256 chainId, SubCall[] memory p) - public - view - returns (address target, uint256 value, bytes memory data) - { - (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) = - filterChainSubCalls(chainId, p); + function wrapTimelock( + uint256 chainId, + SubCall[] memory p + ) public view returns (address target, uint256 value, bytes memory data) { + ( + address[] memory batchTargets, + uint256[] memory batchValues, + bytes[] memory batchCalldatas + ) = filterChainSubCalls(chainId, p); if (batchTargets.length == 1) { // In case the operation has already been done add a salt uint256 salt = computeSalt(chainId, p); @@ -285,8 +310,11 @@ contract SimulationSetup is Test, CommonUtils { function executeTimelock(uint256 chainId, SubCall[] memory p) internal { vm.selectFork(forkIdentifier[chainId]); vm.warp(block.timestamp + timelock(chainId).getMinDelay() + 1); - (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) = - filterChainSubCalls(chainId, p); + ( + address[] memory batchTargets, + uint256[] memory batchValues, + bytes[] memory batchCalldatas + ) = filterChainSubCalls(chainId, p); uint256 salt = computeSalt(chainId, p); if (batchTargets.length == 1) { timelock(chainId).execute(batchTargets[0], batchValues[0], batchCalldatas[0], bytes32(0), 0); @@ -296,14 +324,21 @@ contract SimulationSetup is Test, CommonUtils { } function computeSalt(uint256 chainId, SubCall[] memory p) internal view returns (uint256 salt) { - (address[] memory batchTargets, uint256[] memory batchValues, bytes[] memory batchCalldatas) = - filterChainSubCalls(chainId, p); + ( + address[] memory batchTargets, + uint256[] memory batchValues, + bytes[] memory batchCalldatas + ) = filterChainSubCalls(chainId, p); if (batchTargets.length == 1) { salt = 0; while ( timelock(chainId).isOperation( timelock(chainId).hashOperation( - batchTargets[0], batchValues[0], batchCalldatas[0], bytes32(0), bytes32(salt) + batchTargets[0], + batchValues[0], + batchCalldatas[0], + bytes32(0), + bytes32(salt) ) ) ) { @@ -314,7 +349,11 @@ contract SimulationSetup is Test, CommonUtils { while ( timelock(chainId).isOperation( timelock(chainId).hashOperationBatch( - batchTargets, batchValues, batchCalldatas, bytes32(0), bytes32(salt) + batchTargets, + batchValues, + batchCalldatas, + bytes32(0), + bytes32(salt) ) ) ) { @@ -350,7 +389,7 @@ contract SimulationSetup is Test, CommonUtils { } vm.recordLogs(); - governor().execute{value: valueEther}(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value + governor().execute{ value: valueEther }(targets, values, calldatas, keccak256(bytes(description))); // TODO Optimize value { bytes memory payload; @@ -358,8 +397,8 @@ contract SimulationSetup is Test, CommonUtils { Vm.Log[] memory entries = vm.getRecordedLogs(); for (uint256 i; i < entries.length; i++) { if ( - entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") - && entries[i].topics[1] == bytes32(uint256(_getLZChainId(chainId))) + entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") && + entries[i].topics[1] == bytes32(uint256(_getLZChainId(chainId))) ) { payload = abi.decode(entries[i].data, (bytes)); break; @@ -370,7 +409,10 @@ contract SimulationSetup is Test, CommonUtils { vm.selectFork(forkIdentifier[chainId]); hoax(address(_lzEndPoint(chainId))); proposalReceiver(chainId).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(chainId)), 0, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(chainId)), + 0, + payload ); } @@ -410,7 +452,7 @@ contract SimulationSetup is Test, CommonUtils { governor().state(proposalId); if (keccak256(error) != keccak256(nullBytes)) vm.expectRevert(error); - governor().execute{value: valueEther}(targets, values, calldatas, keccak256(bytes(description))); + governor().execute{ value: valueEther }(targets, values, calldatas, keccak256(bytes(description))); vm.warp(block.timestamp + timelock(chainId).getMinDelay() + 1); } diff --git a/test/unit/TimelockControllerWithCounter.t.sol b/test/unit/TimelockControllerWithCounter.t.sol index f2e74f6..bf4b7de 100644 --- a/test/unit/TimelockControllerWithCounter.t.sol +++ b/test/unit/TimelockControllerWithCounter.t.sol @@ -2,23 +2,23 @@ pragma solidity ^0.8.9; -import {IGovernor} from "oz-v5/governance/IGovernor.sol"; -import {IVotes} from "oz-v5/governance/extensions/GovernorVotes.sol"; -import {IAccessControl} from "oz-v5/access/IAccessControl.sol"; -import {Strings} from "oz-v5/utils/Strings.sol"; - -import {console} from "forge-std/console.sol"; -import {Test, stdError} from "forge-std/Test.sol"; -import {Vm} from "forge-std/Vm.sol"; - -import {AngleGovernor} from "contracts/AngleGovernor.sol"; -import {ProposalReceiver} from "contracts/ProposalReceiver.sol"; -import {ProposalSender, Ownable} from "contracts/ProposalSender.sol"; -import {TimelockControllerWithCounter, TimelockController} from "contracts/TimelockControllerWithCounter.sol"; - -import {SubCall} from "./Proposal.sol"; -import {SimulationSetup} from "./SimulationSetup.t.sol"; -import {ILayerZeroEndpoint} from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; +import { IVotes } from "oz-v5/governance/extensions/GovernorVotes.sol"; +import { IAccessControl } from "oz-v5/access/IAccessControl.sol"; +import { Strings } from "oz-v5/utils/Strings.sol"; + +import { console } from "forge-std/console.sol"; +import { Test, stdError } from "forge-std/Test.sol"; +import { Vm } from "forge-std/Vm.sol"; + +import { AngleGovernor } from "contracts/AngleGovernor.sol"; +import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; +import { ProposalSender, Ownable } from "contracts/ProposalSender.sol"; +import { TimelockControllerWithCounter, TimelockController } from "contracts/TimelockControllerWithCounter.sol"; + +import { SubCall } from "./Proposal.sol"; +import { SimulationSetup } from "./SimulationSetup.t.sol"; +import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; import "contracts/utils/Errors.sol" as Errors; import "../Constants.t.sol"; @@ -62,7 +62,11 @@ contract TimelockControllerWithCounterTest is SimulationSetup { assertEq(timelock(srcChain).proposalIds(0), 0); governor().execute(targets, values, calldatas, keccak256(bytes(description))); bytes32 txId = timelock(srcChain).hashOperation( - address(governor()), 0, abi.encodeWithSelector(governor().updateQuorumNumerator.selector, 11), bytes32(0), 0 + address(governor()), + 0, + abi.encodeWithSelector(governor().updateQuorumNumerator.selector, 11), + bytes32(0), + 0 ); assertEq(timelock(srcChain).counterProposals(), 1); assertEq(timelock(srcChain).proposalIds(0), txId); @@ -93,7 +97,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { timelock(destChain).grantRole.selector, timelock(destChain).PROPOSER_ROLE(), address(newReceiverOptimism) - ) + ) }); p[1] = SubCall({ chainId: destChain, @@ -103,7 +107,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { timelock(destChain).revokeRole.selector, timelock(destChain).PROPOSER_ROLE(), address(proposalReceiver(destChain)) - ) + ) }); string memory description = "Updating relayer receiver on Optimism"; vm.selectFork(forkIdentifier[srcChain]); @@ -195,10 +199,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { abi.encodeWithSelector(_lzEndPoint(srcChain).send.selector), abi.encode("REVERT") ); - bytes memory payload = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); - (uint256 nativeFee,) = proposalSender().estimateFees(_getLZChainId(destChain), payload, adapterParams); + (uint256 nativeFee, ) = proposalSender().estimateFees(_getLZChainId(destChain), payload, adapterParams); assertLe(nativeFee, 0.1 ether); _dummyProposal(srcChain, p, description, 0.1 ether, hex""); vm.clearMockedCalls(); @@ -216,7 +220,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(srcChain), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload + _getLZChainId(srcChain), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload ); vm.selectFork(forkIdentifier[srcChain]); @@ -227,8 +234,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { assertGe(timelock(destChain).getTimestamp(timelock(destChain).proposalIds(0)), block.timestamp); vm.warp(block.timestamp + timelock(destChain).getMinDelay() + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p + ); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).counterProposals(), 1); @@ -256,10 +265,12 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") + address(_lzEndPoint(1)), + abi.encodeWithSelector(_lzEndPoint(1).send.selector), + abi.encode("REVERT") ); - bytes memory payload1 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -269,12 +280,14 @@ contract TimelockControllerWithCounterTest is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) - ) + timelock(destChain).grantRole.selector, + timelock(1).PROPOSER_ROLE(), + address(alice) + ) }); description = "Grant role on Optimism"; - bytes memory payload2 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -297,7 +310,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload1 ); vm.selectFork(forkIdentifier[1]); @@ -311,8 +327,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p1); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p1 + ); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -326,7 +344,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload2 ); vm.selectFork(forkIdentifier[1]); @@ -339,8 +360,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p2); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p2 + ); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -361,10 +384,12 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") + address(_lzEndPoint(1)), + abi.encodeWithSelector(_lzEndPoint(1).send.selector), + abi.encode("REVERT") ); - bytes memory payload1 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload1 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000012401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams1 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p1, description, 0.1 ether, hex""); @@ -374,12 +399,14 @@ contract TimelockControllerWithCounterTest is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) - ) + timelock(destChain).grantRole.selector, + timelock(1).PROPOSER_ROLE(), + address(alice) + ) }); description = "Grant role on Optimism"; - bytes memory payload2 = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload2 = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000014401d5062a000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams2 = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p2, description, 0.1 ether, hex""); @@ -402,7 +429,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload2 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload2 ); vm.selectFork(forkIdentifier[1]); @@ -416,8 +446,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.selectFork(forkIdentifier[destChain]); vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p2); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p2 + ); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), false); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).hasRole(timelock(destChain).PROPOSER_ROLE(), alice), true); @@ -431,7 +463,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload1 + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload1 ); vm.selectFork(forkIdentifier[1]); assertEq(timelock(1).counterProposals(), 0); @@ -443,8 +478,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { vm.warp(block.timestamp + oldDelay + 1); { - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p1); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p1 + ); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).execute(targets[0], values[0], calldatas[0], bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -466,17 +503,21 @@ contract TimelockControllerWithCounterTest is SimulationSetup { target: address(timelock(destChain)), value: 0, data: abi.encodeWithSelector( - timelock(destChain).grantRole.selector, timelock(1).PROPOSER_ROLE(), address(alice) - ) + timelock(destChain).grantRole.selector, + timelock(1).PROPOSER_ROLE(), + address(alice) + ) }); string memory description = "Batch delay and grantRole on Optimism"; vm.selectFork(forkIdentifier[1]); // Making the call revert to force replay vm.mockCallRevert( - address(_lzEndPoint(1)), abi.encodeWithSelector(_lzEndPoint(1).send.selector), abi.encode("REVERT") + address(_lzEndPoint(1)), + abi.encodeWithSelector(_lzEndPoint(1).send.selector), + abi.encode("REVERT") ); - bytes memory payload = - hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002c48f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + bytes + memory payload = hex"000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002c48f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0cb889707d426a7a386870a03bc70d1b0697598000000000000000000000000a0cb889707d426a7a386870a03bc70d1b06975980000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002464d6235300000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000442f2ff15db09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc10000000000000000000000007e5f4552091a69125d5dfcb7b8c2659029395bdf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; bytes memory adapterParams = abi.encodePacked(uint16(1), uint256(300000)); _dummyProposal(1, p, description, 0.1 ether, hex""); vm.clearMockedCalls(); @@ -494,7 +535,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { hoax(address(_lzEndPoint(destChain))); proposalReceiver(destChain).lzReceive( - _getLZChainId(1), abi.encodePacked(proposalSender(), proposalReceiver(destChain)), 0, payload + _getLZChainId(1), + abi.encodePacked(proposalSender(), proposalReceiver(destChain)), + 0, + payload ); vm.selectFork(forkIdentifier[1]); @@ -505,8 +549,10 @@ contract TimelockControllerWithCounterTest is SimulationSetup { assertEq(timelock(destChain).proposalIds(0), _decodeLzReceivePayload(payload, destChain, true)); vm.warp(block.timestamp + timelock(destChain).getMinDelay() + 1); - (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = - filterChainSubCalls(destChain, p); + (address[] memory targets, uint256[] memory values, bytes[] memory calldatas) = filterChainSubCalls( + destChain, + p + ); assertEq(timelock(destChain).getMinDelay() != 100, true); timelock(destChain).executeBatch(targets, values, calldatas, bytes32(0), 0); assertEq(timelock(destChain).getMinDelay() == 100, true); @@ -519,7 +565,9 @@ contract TimelockControllerWithCounterTest is SimulationSetup { uint256 minDelay = timelock(srcChain).getMinDelay(); vm.expectRevert( abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, alice, timelock(srcChain).PROPOSER_ROLE() + IAccessControl.AccessControlUnauthorizedAccount.selector, + alice, + timelock(srcChain).PROPOSER_ROLE() ) ); vm.prank(alice); @@ -547,7 +595,9 @@ contract TimelockControllerWithCounterTest is SimulationSetup { uint256 minDelay = timelock(srcChain).getMinDelay(); vm.expectRevert( abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, alice, timelock(srcChain).PROPOSER_ROLE() + IAccessControl.AccessControlUnauthorizedAccount.selector, + alice, + timelock(srcChain).PROPOSER_ROLE() ) ); vm.prank(alice); @@ -572,7 +622,9 @@ contract TimelockControllerWithCounterTest is SimulationSetup { string memory description = "Updating delay on Optimism"; bytes memory error = abi.encodeWithSelector( - IAccessControl.AccessControlUnauthorizedAccount.selector, alice, timelock(1).EXECUTOR_ROLE() + IAccessControl.AccessControlUnauthorizedAccount.selector, + alice, + timelock(1).EXECUTOR_ROLE() ); _crossChainProposal(destChain, p, description, 0.1 ether, error, alice); } @@ -601,30 +653,37 @@ contract TimelockControllerWithCounterTest is SimulationSetup { HELPERS //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - function _decodeLzReceivePayload(bytes memory payload, uint256 chainId, bool isBatch) - internal - view - returns (bytes32) - { - (,,, bytes[] memory calldatas) = abi.decode(payload, (address[], uint256[], string[], bytes[])); + function _decodeLzReceivePayload( + bytes memory payload, + uint256 chainId, + bool isBatch + ) internal view returns (bytes32) { + (, , , bytes[] memory calldatas) = abi.decode(payload, (address[], uint256[], string[], bytes[])); bytes memory higherData = calldatas[0]; if (isBatch) return this._decodePayloadTimelockScheduleBatch(higherData, chainId); else return this._decodePayloadTimelockSchedule(higherData, chainId); } function _decodePayloadTimelockSchedule(bytes calldata payload, uint256 chainId) public view returns (bytes32 id) { - (address target, uint256 value, bytes memory data, bytes32 predecessor, bytes32 salt,) = - abi.decode(payload[4:], (address, uint256, bytes, bytes32, bytes32, uint256)); + (address target, uint256 value, bytes memory data, bytes32 predecessor, bytes32 salt, ) = abi.decode( + payload[4:], + (address, uint256, bytes, bytes32, bytes32, uint256) + ); return timelock(chainId).hashOperation(target, value, data, predecessor, salt); } - function _decodePayloadTimelockScheduleBatch(bytes calldata payload, uint256 chainId) - public - view - returns (bytes32 id) - { - (address[] memory targets, uint256[] memory values, bytes[] memory datas, bytes32 predecessor, bytes32 salt,) = - abi.decode(payload[4:], (address[], uint256[], bytes[], bytes32, bytes32, uint256)); + function _decodePayloadTimelockScheduleBatch( + bytes calldata payload, + uint256 chainId + ) public view returns (bytes32 id) { + ( + address[] memory targets, + uint256[] memory values, + bytes[] memory datas, + bytes32 predecessor, + bytes32 salt, + + ) = abi.decode(payload[4:], (address[], uint256[], bytes[], bytes32, bytes32, uint256)); return timelock(chainId).hashOperationBatch(targets, values, datas, predecessor, salt); } } From 16a817c9f1137d972c1be35b24d61f553b83fe45 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Mon, 29 Apr 2024 10:59:16 +0200 Subject: [PATCH 16/26] feat: update transmuter facets --- scripts/proposals/transmuter/TransmuterUtils.s.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/proposals/transmuter/TransmuterUtils.s.sol b/scripts/proposals/transmuter/TransmuterUtils.s.sol index 04534e7..aad48d8 100644 --- a/scripts/proposals/transmuter/TransmuterUtils.s.sol +++ b/scripts/proposals/transmuter/TransmuterUtils.s.sol @@ -29,10 +29,10 @@ contract TransmuterUtils is Script, CommonUtils { uint96 constant DEVIATION_THRESHOLD_BC3M = uint96(100 * BPS); uint32 constant HEARTBEAT = uint32(1 days); - address constant GETTERS = 0xB55639FdcD12503fE85e3B4D4639142C9D7951aa; - address constant REDEEMER = 0xFE2Ff814800Bb1df4E415ac88338f07471C8c87B; - address constant SETTERS_GOVERNOR = 0xb3047F769f8ae481F99a71C488037D31e1dA6707; - address constant SWAPPER = 0xeF0B788D254a7CC0278FC61C52486Db56dd74308; + address constant GETTERS = 0x99fe8557A8F322525262720C52b7d57c56924012; + address constant REDEEMER = 0xa09735EfbcfF6E76e6EfFF82A9Ad996A85cd0725; + address constant SETTERS_GOVERNOR = 0x49c7B39A2E01869d39548F232F9B1586DA8Ef9c2; + address constant SWAPPER = 0xD838bF7fB3b420ac93A7d9f5b40230F78b33536F; /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// HELPERS From 260ab485fa1cb1692f4b5865ab41f7ae07d3c541 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Mon, 29 Apr 2024 11:02:08 +0200 Subject: [PATCH 17/26] remove comment --- helpers/createProposal.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/helpers/createProposal.sh b/helpers/createProposal.sh index 91c7909..130e210 100644 --- a/helpers/createProposal.sh +++ b/helpers/createProposal.sh @@ -97,7 +97,7 @@ function main { echo "Running on chains $chainIds" export CHAIN_IDS=$chainIds - FOUNDRY_PROFILE=dev forge script $script -vvvv + FOUNDRY_PROFILE=dev forge script $script -vvv if [ $? -ne 0 ]; then echo "" @@ -119,9 +119,9 @@ function main { echo "Would you like to create the proposal ? (yes/no)" read execute - # if [[ $execute == "yes" ]]; then - # FOUNDRY_PROFILE=dev forge script scripts/proposals/Propose.s.sol:Propose --fork-url $mainnet_uri --broadcast - # fi + if [[ $execute == "yes" ]]; then + FOUNDRY_PROFILE=dev forge script scripts/proposals/Propose.s.sol:Propose --fork-url $mainnet_uri --broadcast + fi } main $@ From 297b122973888fd587e0ed144d6be9fce674f520 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Mon, 29 Apr 2024 11:09:59 +0200 Subject: [PATCH 18/26] remove temporarily angle-transmuter lib --- .gitmodules | 4 ---- lib/angle-transmuter | 1 - 2 files changed, 5 deletions(-) delete mode 160000 lib/angle-transmuter diff --git a/.gitmodules b/.gitmodules index 99feb2d..1d12a99 100644 --- a/.gitmodules +++ b/.gitmodules @@ -11,10 +11,6 @@ path = lib/solidity-stringutils url = https://github.com/Arachnid/solidity-stringutils ignore = dirty -[submodule "lib/angle-transmuter"] - path = lib/angle-transmuter - url = https://github.com/AngleProtocol/angle-transmuter - branch = feat--oracles-with-firewalls-on-mint-and-burn [submodule "lib/borrow-contracts"] path = lib/borrow-contracts url = https://github.com/AngleProtocol/borrow-contracts diff --git a/lib/angle-transmuter b/lib/angle-transmuter deleted file mode 160000 index feef55a..0000000 --- a/lib/angle-transmuter +++ /dev/null @@ -1 +0,0 @@ -Subproject commit feef55a4a2d583547923fe8a4dc5ce09d1616476 From f2b9e81073d7e8f60efbca285956fea057def349 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Mon, 29 Apr 2024 11:10:18 +0200 Subject: [PATCH 19/26] lint revert --- contracts/AngleGovernor.sol | 4 +--- contracts/external/GovernorCountingFractional.sol | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/contracts/AngleGovernor.sol b/contracts/AngleGovernor.sol index 7fead4d..ee0cc1b 100644 --- a/contracts/AngleGovernor.sol +++ b/contracts/AngleGovernor.sol @@ -99,9 +99,7 @@ contract AngleGovernor is return ProposalState.Succeeded; } else if (isShortCircuitAgainst) { return ProposalState.Defeated; - } else { - return currentState; - } + } else return currentState; } /// @inheritdoc GovernorVotesQuorumFraction diff --git a/contracts/external/GovernorCountingFractional.sol b/contracts/external/GovernorCountingFractional.sol index 66288cf..3439c3e 100644 --- a/contracts/external/GovernorCountingFractional.sol +++ b/contracts/external/GovernorCountingFractional.sol @@ -138,9 +138,8 @@ abstract contract GovernorCountingFractional is Governor { * vote before or after. */ function _countVoteNominal(uint256 proposalId, address account, uint128 totalWeight, uint8 support) internal { - if (_proposalVotersWeightCast[proposalId][account] > 0) { + if (_proposalVotersWeightCast[proposalId][account] > 0) revert GovernorCountingFractionalVoteWouldExceedWeight(); - } _proposalVotersWeightCast[proposalId][account] = totalWeight; From 430f6c7733e10f2a978b383f78245ba70f9147f1 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Mon, 29 Apr 2024 11:11:03 +0200 Subject: [PATCH 20/26] forge install: angle-transmuter --- .gitmodules | 3 +++ lib/angle-transmuter | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/angle-transmuter diff --git a/.gitmodules b/.gitmodules index 1d12a99..0201154 100644 --- a/.gitmodules +++ b/.gitmodules @@ -45,3 +45,6 @@ path = lib/old-oz-upgradeable url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable version = ebf264cc4b812e6557ed7d539e947211acd5670c +[submodule "lib/angle-transmuter"] + path = lib/angle-transmuter + url = https://github.com/AngleProtocol/angle-transmuter diff --git a/lib/angle-transmuter b/lib/angle-transmuter new file mode 160000 index 0000000..6aecf1a --- /dev/null +++ b/lib/angle-transmuter @@ -0,0 +1 @@ +Subproject commit 6aecf1a1014b0b58dbb824370c7a9d424361437c From a1187905bf34bd5282700aacb1077177d7b76f82 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Mon, 29 Apr 2024 12:16:10 +0200 Subject: [PATCH 21/26] fix stack too deep --- test/scripts/ScriptHelpers.t.sol | 70 ++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/test/scripts/ScriptHelpers.t.sol b/test/scripts/ScriptHelpers.t.sol index f2311cf..64f0476 100644 --- a/test/scripts/ScriptHelpers.t.sol +++ b/test/scripts/ScriptHelpers.t.sol @@ -15,6 +15,13 @@ contract ScriptHelpers is Test, Utils { using stdStorage for StdStorage; uint256 constant valueEther = 1 ether; + bytes[] private calldatasHelpers; + string private descriptionHelpers; + address[] private targetsHelpers; + uint256[] private valuesHelpers; + uint256[] private chainIdsHelpers; + Vm.Log[] private entriesHelpers; + bytes private payloadHelpers; function setUp() public virtual override { super.setUp(); @@ -56,13 +63,7 @@ contract ScriptHelpers is Test, Utils { } function _executeProposalInternal(bool isFork) public returns (uint256[] memory) { - ( - bytes[] memory calldatas, - string memory description, - address[] memory targets, - uint256[] memory values, - uint256[] memory chainIds - ) = _deserializeJson(); + (calldatasHelpers, descriptionHelpers, targetsHelpers, valuesHelpers, chainIdsHelpers) = _deserializeJson(); vm.selectFork(forkIdentifier[isFork ? CHAIN_FORK : CHAIN_SOURCE]); { @@ -70,7 +71,12 @@ contract ScriptHelpers is Test, Utils { { hoax(whale); - uint256 proposalId = governor.propose(targets, values, calldatas, description); + uint256 proposalId = governor.propose( + targetsHelpers, + valuesHelpers, + calldatasHelpers, + descriptionHelpers + ); vm.warp(block.timestamp + governor.votingDelay() + 1); vm.roll(block.number + governor.$votingDelayBlocks() + 1); @@ -81,48 +87,52 @@ contract ScriptHelpers is Test, Utils { vm.recordLogs(); hoax(whale); - governor.execute{ value: valueEther }(targets, values, calldatas, keccak256(bytes(description))); + governor.execute{ value: valueEther }( + targetsHelpers, + valuesHelpers, + calldatasHelpers, + keccak256(bytes(descriptionHelpers)) + ); } - Vm.Log[] memory entries = vm.getRecordedLogs(); + entriesHelpers = vm.getRecordedLogs(); - for (uint256 chainCount; chainCount < chainIds.length; chainCount++) { - uint256 chainId = chainIds[chainCount]; + for (uint256 chainCount; chainCount < chainIdsHelpers.length; chainCount++) { + uint256 chainId = chainIdsHelpers[chainCount]; TimelockControllerWithCounter timelock = TimelockControllerWithCounter( payable(_chainToContract(chainId, ContractType.Timelock)) ); if (chainId == CHAIN_SOURCE) { vm.warp(block.timestamp + timelock.getMinDelay() + 1); - _executeTimelock(chainId, timelock, targets[chainCount], calldatas[chainCount]); + _executeTimelock(chainId, timelock, targetsHelpers[chainCount], calldatasHelpers[chainCount]); } else { { - ProposalSender proposalSender = ProposalSender( - payable(_chainToContract(CHAIN_SOURCE, ContractType.ProposalSender)) - ); - ProposalReceiver proposalReceiver = ProposalReceiver( - payable(_chainToContract(chainId, ContractType.ProposalReceiver)) - ); - bytes memory payload; - { - for (uint256 i; i < entries.length; i++) { + for (uint256 i; i < entriesHelpers.length; i++) { if ( - entries[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") && - entries[i].topics[1] == bytes32(uint256(_getLZChainId(chainId))) + entriesHelpers[i].topics[0] == keccak256("ExecuteRemoteProposal(uint16,bytes)") && + entriesHelpers[i].topics[1] == bytes32(uint256(_getLZChainId(chainId))) ) { - payload = abi.decode(entries[i].data, (bytes)); + payloadHelpers = abi.decode(entriesHelpers[i].data, (bytes)); break; } } } + ProposalSender proposalSender = ProposalSender( + payable(_chainToContract(CHAIN_SOURCE, ContractType.ProposalSender)) + ); + ProposalReceiver proposalReceiver = ProposalReceiver( + payable(_chainToContract(chainId, ContractType.ProposalReceiver)) + ); + vm.selectFork(forkIdentifier[chainId]); hoax(address(_lzEndPoint(chainId))); proposalReceiver.lzReceive( _getLZChainId(CHAIN_SOURCE), abi.encodePacked(proposalSender, proposalReceiver), 0, - payload + payloadHelpers ); } @@ -130,10 +140,10 @@ contract ScriptHelpers is Test, Utils { address[] memory chainTargets; bytes[] memory chainCalldatas; { - console.logBytes(calldatas[chainCount]); + console.logBytes(calldatasHelpers[chainCount]); (, bytes memory senderData, ) = abi.decode( - // calldatas[chainCount], - _slice(calldatas[chainCount], 4, calldatas[chainCount].length - 4), + // calldatasHelpers[chainCount], + _slice(calldatasHelpers[chainCount], 4, calldatasHelpers[chainCount].length - 4), (uint16, bytes, bytes) ); console.logBytes(senderData); @@ -148,7 +158,7 @@ contract ScriptHelpers is Test, Utils { } } } - return chainIds; + return chainIdsHelpers; } function _executeTimelock( From c02e4cda27a77a63129f8b44e41d6aac20b51e85 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Mon, 29 Apr 2024 15:20:57 +0200 Subject: [PATCH 22/26] fix lint --- contracts/AngleGovernor.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/AngleGovernor.sol b/contracts/AngleGovernor.sol index ee0cc1b..75062f3 100644 --- a/contracts/AngleGovernor.sol +++ b/contracts/AngleGovernor.sol @@ -6,7 +6,8 @@ import { IVotes } from "oz-v5/governance/utils/IVotes.sol"; import { Governor } from "oz-v5/governance/Governor.sol"; import { GovernorPreventLateQuorum } from "oz-v5/governance/extensions/GovernorPreventLateQuorum.sol"; -import { GovernorVotesQuorumFraction, GovernorVotes } from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; +import { GovernorVotes } from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; +import { GovernorVotesQuorumFraction } from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; import { GovernorSettings } from "oz-v5/governance/extensions/GovernorSettings.sol"; import { IERC5805 } from "oz-v5/interfaces/IERC5805.sol"; From 25515037eac6b347b4e09ae13c9efaee71514434 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Thu, 2 May 2024 18:42:41 +0200 Subject: [PATCH 23/26] feat: proposal to increase quorums --- helpers/createProposal.sh | 6 +++--- scripts/proposals/Propose.s.sol | 5 ++--- scripts/proposals/angleGovernor/IncreaseQuorum.s.sol | 2 +- scripts/proposals/payload.json | 4 ++-- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/helpers/createProposal.sh b/helpers/createProposal.sh index 130e210..2580616 100644 --- a/helpers/createProposal.sh +++ b/helpers/createProposal.sh @@ -97,7 +97,7 @@ function main { echo "Running on chains $chainIds" export CHAIN_IDS=$chainIds - FOUNDRY_PROFILE=dev forge script $script -vvv + forge script $script -vvv if [ $? -ne 0 ]; then echo "" @@ -108,7 +108,7 @@ function main { testContract="${script}Test" echo "" echo "Running test" - FOUNDRY_PROFILE=dev forge test --match-contract $testContract -vvv + forge test --match-contract $testContract -vvv if [ $? -ne 0 ]; then echo "" @@ -120,7 +120,7 @@ function main { read execute if [[ $execute == "yes" ]]; then - FOUNDRY_PROFILE=dev forge script scripts/proposals/Propose.s.sol:Propose --fork-url $mainnet_uri --broadcast + forge script scripts/proposals/Propose.s.sol:Propose --fork-url $mainnet_uri --broadcast fi } diff --git a/scripts/proposals/Propose.s.sol b/scripts/proposals/Propose.s.sol index f82f0ab..2241b6b 100644 --- a/scripts/proposals/Propose.s.sol +++ b/scripts/proposals/Propose.s.sol @@ -27,9 +27,8 @@ contract Propose is Utils { uint256[] memory chainIds ) = _deserializeJson(); - uint256 deployerPrivateKey = vm.deriveKey(vm.envString("MNEMONIC_MAINNET"), 0); - vm.rememberKey(deployerPrivateKey); - + uint256 deployerPrivateKey = vm.envUint("DEPLOYER_PRIVATE_KEY"); + address deployer = vm.addr(deployerPrivateKey); vm.startBroadcast(deployerPrivateKey); AngleGovernor governor = AngleGovernor(payable(_chainToContract(CHAIN_SOURCE, ContractType.Governor))); diff --git a/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol b/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol index 1f9deda..e0792e7 100644 --- a/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol +++ b/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol @@ -40,7 +40,7 @@ contract IncreaseQuorum is Wrapper { function run() external { uint256[] memory chainIds = vm.envUint("CHAIN_IDS", ","); - string memory description = "ipfs://QmXpXXaUYCtUb4w9T2kEtu8t1JwpSv7tqTFwMETKgimcsf"; + string memory description = "ipfs://QmbcRv3pSuvamZ7TtYu55gbnnUmkrxPPNU2GX6NGJecSfQ"; /** * TODO complete diff --git a/scripts/proposals/payload.json b/scripts/proposals/payload.json index c038adf..1781e1b 100644 --- a/scripts/proposals/payload.json +++ b/scripts/proposals/payload.json @@ -1,11 +1,11 @@ { "calldatas": { - "0": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015180000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab00000000000000000000000000253582b2a3fe112feec532221d9708c64cefab000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000ac00000000000000000000000000000000000000000000000000000000000000e6000000000000000000000000000000000000000000000000000000000000008641f931c1c0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008400000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000000000000000000000000000000000000000000680000000000000000000000000b55639fdcd12503fe85e3b4d4639142c9d7951aa000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000016b4a0bdf300000000000000000000000000000000000000000000000000000000ee565a6300000000000000000000000000000000000000000000000000000000847da7be00000000000000000000000000000000000000000000000000000000eb7aac5f000000000000000000000000000000000000000000000000000000003335221000000000000000000000000000000000000000000000000000000000b718136100000000000000000000000000000000000000000000000000000000b85780bc00000000000000000000000000000000000000000000000000000000cd377c5300000000000000000000000000000000000000000000000000000000782513bd0000000000000000000000000000000000000000000000000000000094e35d9e000000000000000000000000000000000000000000000000000000004ea3e3430000000000000000000000000000000000000000000000000000000010d3d22e0000000000000000000000000000000000000000000000000000000038c269eb00000000000000000000000000000000000000000000000000000000adc9d1f7000000000000000000000000000000000000000000000000000000008db9653f000000000000000000000000000000000000000000000000000000000d1266270000000000000000000000000000000000000000000000000000000096d6487900000000000000000000000000000000000000000000000000000000fe7d0c540000000000000000000000000000000000000000000000000000000077dc342900000000000000000000000000000000000000000000000000000000f9839d8900000000000000000000000000000000000000000000000000000000a52aefd40000000000000000000000000000000000000000000000000000000099eeca4900000000000000000000000000000000000000000000000000000000000000000000000000000000fe2ff814800bb1df4e415ac88338f07471c8c87b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000004d703a0cd00000000000000000000000000000000000000000000000000000000815822c1000000000000000000000000000000000000000000000000000000002e7639bc00000000000000000000000000000000000000000000000000000000fd7daaf800000000000000000000000000000000000000000000000000000000000000000000000000000000b3047f769f8ae481f99a71c488037d31e1da670700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000af0d2d5a800000000000000000000000000000000000000000000000000000000c1cdee7e0000000000000000000000000000000000000000000000000000000087c8ab7a000000000000000000000000000000000000000000000000000000005c3eebda000000000000000000000000000000000000000000000000000000001f0ec8ee000000000000000000000000000000000000000000000000000000000e32cb860000000000000000000000000000000000000000000000000000000081ee2deb00000000000000000000000000000000000000000000000000000000b13b0847000000000000000000000000000000000000000000000000000000001b0c7182000000000000000000000000000000000000000000000000000000007c0343a100000000000000000000000000000000000000000000000000000000000000000000000000000000ef0b788d254a7cc0278fc61c52486db56dd743080000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000064583aea6000000000000000000000000000000000000000000000000000000009525f3ab000000000000000000000000000000000000000000000000000000003b6a1fe000000000000000000000000000000000000000000000000000000000d92c6cb200000000000000000000000000000000000000000000000000000000b92567fa00000000000000000000000000000000000000000000000000000000c10a62870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001641f931c1c00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000b3047f769f8ae481f99a71c488037d31e1da67070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000011cb44dfc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000364b13b08470000000000000000000000001abaea1f7c830bd89acc67ec4af516284b1bc33c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000012750000000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf526340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003c4b13b08470000000000000000000000002f123cf3f37ce3328cc9b5b8415f9ec5109b45e7000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006e27a25999b3c665e44d903b2139f5a4be2b6c260000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000003f480000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000067b5df97db1750000000000000000000000000000000000000000000000000000002386f26fc100000000000000000000000000000000000000000000000000000000000065f31a88000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000" + "0": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000748ba9cd5a5ddba5aba70a4ac861b2413dca4436000000000000000000000000748ba9cd5a5ddba5aba70a4ac861b2413dca44360000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002406f3f9e6000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002443ec3e09000000000000000000000000000000000000000000000000000000000000004b00000000000000000000000000000000000000000000000000000000" }, "chainIds": { "0": 1 }, - "description": "ipfs://", + "description": "ipfs://QmbcRv3pSuvamZ7TtYu55gbnnUmkrxPPNU2GX6NGJecSfQ", "targets": { "0": "0x09D81464c7293C774203E46E3C921559c8E9D53f" }, From 30759f9efa90b5e0e9ebeecd2a415cadec36e7e8 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Fri, 12 Jul 2024 09:46:56 +0200 Subject: [PATCH 24/26] rm checkRoles scripts --- scripts/interaction/CheckRoles.s.sol | 906 --------------------------- 1 file changed, 906 deletions(-) delete mode 100644 scripts/interaction/CheckRoles.s.sol diff --git a/scripts/interaction/CheckRoles.s.sol b/scripts/interaction/CheckRoles.s.sol deleted file mode 100644 index 60aa7aa..0000000 --- a/scripts/interaction/CheckRoles.s.sol +++ /dev/null @@ -1,906 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.19; - -import { console } from "forge-std/console.sol"; -import { IVaultManager } from "borrow/interfaces/IVaultManager.sol"; -import { ITreasury } from "borrow/interfaces/ITreasury.sol"; -import { IAgToken } from "borrow/interfaces/IAgToken.sol"; -import { IERC721Metadata } from "oz-v5/token/ERC721/extensions/IERC721Metadata.sol"; -import { IAccessControl } from "oz-v5/access/IAccessControl.sol"; -import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; -import { ProposalSender } from "contracts/ProposalSender.sol"; -import { TimelockControllerWithCounter } from "contracts/TimelockControllerWithCounter.sol"; -import { Utils } from "../Utils.s.sol"; -import "../Constants.s.sol"; -import "stringutils/strings.sol"; - -contract CheckRoles is Utils { - using strings for *; - - address constant oldDeployer = 0xfdA462548Ce04282f4B6D6619823a7C64Fdc0185; - address constant oldKeeper = 0xcC617C6f9725eACC993ac626C7efC6B96476916E; - address constant oldKeeperPolygon = 0x5EB715d601C2F27f83Cb554b6B36e047822fB70a; - address constant oldKeeperPolygon2 = 0xEd42E58A303E20523A695CB31ac31df26C50397B; - address constant merklKeeper = 0x435046800Fb9149eE65159721A92cB7d50a7534b; - address constant tmpCoreBorrowUSD = 0x3fc5a1bd4d0A435c55374208A6A81535A1923039; - string constant angleLZ = "Angle LZ"; - - bytes32 public constant GUARDIAN_ROLE = keccak256("GUARDIAN_ROLE"); - bytes32 public constant GOVERNOR_ROLE = keccak256("GOVERNOR_ROLE"); - bytes32 public constant FLASHLOANER_TREASURY_ROLE = keccak256("FLASHLOANER_TREASURY_ROLE"); - bytes32 public constant TIMELOCK_ADMIN_ROLE = keccak256("TIMELOCK_ADMIN_ROLE"); - bytes32 public constant PROPOSER_ROLE = keccak256("PROPOSER_ROLE"); - bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE"); - bytes32 public constant CANCELLER_ROLE = keccak256("CANCELLER_ROLE"); - bytes32 public constant KEEPER_ROLE = keccak256("KEEPER_ROLE"); - bytes32 public constant DISTRIBUTOR_ROLE = keccak256("DISTRIBUTOR_ROLE"); - bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; - - address[] public allContracts; - - string public constant OUTPUT_PATH = "./scripts/roles.json"; - string private json; - uint256 private jsonIndex; - string private output; - string private outputActor; - string private jsonActor; - uint256 private jsonActorIndex; - - // TODO also check that all proxy contracts have been initialized - function run() external { - vm.label(oldDeployer, "Old Deployer"); - vm.label(oldKeeper, "Old Keeper"); - vm.label(oldKeeperPolygon, "Old Keeper Polygon"); - vm.label(oldKeeperPolygon2, "Old Keeper Polygon 2"); - vm.label(merklKeeper, "Merkl Keeper"); - - string memory jsonGlobal = "chain"; - uint256[] memory chainIds = vm.envUint("CHAIN_IDS", ","); - string memory finalOutput; - for (uint256 i = 0; i < chainIds.length; i++) { - json = vm.toString(chainIds[i]); - jsonIndex = 0; - output = ""; - _checkRoles(chainIds[i]); - finalOutput = vm.serializeString(jsonGlobal, vm.toString(chainIds[i]), output); - } - vm.writeFile(OUTPUT_PATH, finalOutput); - } - - function _checkRoles(uint256 chainId) public { - vm.selectFork(forkIdentifier[chainId]); - - allContracts = _getAllContracts(chainId); - // Address to check roles for - uint256 nbrActors = chainId == CHAIN_ETHEREUM ? 11 : 10; - address[] memory listAddressToCheck = new address[](nbrActors); - - { - address govMultisig = _chainToContract(chainId, ContractType.GovernorMultisig); - address guardianMultisig = _chainToContract(chainId, ContractType.GuardianMultisig); - address timelock = _chainToContract(chainId, ContractType.Timelock); - address coreBorrow = _chainToContract(chainId, ContractType.CoreBorrow); - address proxyAdmin = _chainToContract(chainId, ContractType.ProxyAdmin); - - vm.label(govMultisig, "Governor Multisig"); - vm.label(guardianMultisig, "Guardian Multisig"); - vm.label(timelock, "Timelock"); - vm.label(coreBorrow, "Core Borrow"); - vm.label(proxyAdmin, "Proxy Admin"); - - listAddressToCheck[0] = oldDeployer; - listAddressToCheck[1] = oldKeeper; - listAddressToCheck[2] = oldKeeperPolygon; - listAddressToCheck[3] = oldKeeperPolygon2; - listAddressToCheck[4] = merklKeeper; - listAddressToCheck[5] = govMultisig; - listAddressToCheck[6] = guardianMultisig; - listAddressToCheck[7] = timelock; - listAddressToCheck[8] = coreBorrow; - listAddressToCheck[9] = proxyAdmin; - if (chainId == CHAIN_ETHEREUM) listAddressToCheck[10] = _chainToContract(chainId, ContractType.Governor); - } - - { - // It would be better with a try catch but I don't know how why it doesn't work - if (chainId == CHAIN_ETHEREUM) { - // Contract to check roles on - ITransmuter transmuterEUR = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); - ITransmuter transmuterUSD = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgUSD)); - IAngle angle = IAngle(_chainToContract(chainId, ContractType.Angle)); - ProposalSender proposalSender = ProposalSender( - payable(_chainToContract(chainId, ContractType.ProposalSender)) - ); - IGaugeController gaugeController = IGaugeController( - _chainToContract(chainId, ContractType.GaugeController) - ); - ISmartWalletWhitelist smartWalletWhitelist = ISmartWalletWhitelist( - _chainToContract(chainId, ContractType.SmartWalletWhitelist) - ); - IVeAngle veAngle = IVeAngle(_chainToContract(chainId, ContractType.veANGLE)); - IVeBoostProxy veBoostProxy = IVeBoostProxy(_chainToContract(chainId, ContractType.veBoostProxy)); - IGenericAccessControl merklMiddleman = IGenericAccessControl( - _chainToContract(chainId, ContractType.MerklMiddleman) - ); - - if (!_authorizedCore(chainId, address(transmuterEUR.accessControlManager()))) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat( - "Transmuter EUR - wrong access control manager: ", - vm.toString(address(transmuterEUR.accessControlManager())) - ) - ); - jsonIndex++; - } - if (!_authorizedCore(chainId, address(transmuterUSD.accessControlManager()))) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat( - "Transmuter USD - wrong access control manager: ", - vm.toString(address(transmuterUSD.accessControlManager())) - ) - ); - jsonIndex++; - } - if (!_authorizedMinter(chainId, angle.minter())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("Angle - minter role: ", vm.toString(angle.minter())) - ); - jsonIndex++; - } - if (!_authorizedOwner(chainId, proposalSender.owner())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("Proposal Sender - owner: ", vm.toString(proposalSender.owner())) - ); - jsonIndex++; - } - if (!_authorizedCoreMerkl(chainId, address(merklMiddleman.accessControlManager()))) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat( - "Merkl Middleman - wrong access control manager: ", - vm.toString(address(merklMiddleman.accessControlManager())) - ) - ); - jsonIndex++; - } - if (!_authorizedOwner(chainId, gaugeController.admin())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("Gauge Controller - admin role: ", vm.toString(gaugeController.admin())) - ); - jsonIndex++; - } - if (!_authorizedOwner(chainId, gaugeController.future_admin())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat( - "Gauge Controller - future admin role: ", - vm.toString(gaugeController.future_admin()) - ) - ); - jsonIndex++; - } - if (!_authorizedOwner(chainId, smartWalletWhitelist.admin())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("Smart Wallet Whitelist - admin: ", vm.toString(smartWalletWhitelist.admin())) - ); - jsonIndex++; - } - if (!_authorizedOwner(chainId, smartWalletWhitelist.future_admin())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat( - "Smart Wallet Whitelist - future admin: ", - vm.toString(smartWalletWhitelist.future_admin()) - ) - ); - jsonIndex++; - } - if (!_authorizedOwner(chainId, veAngle.admin())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("veANGLE - admin: ", vm.toString(veAngle.admin())) - ); - jsonIndex++; - } - if (!_authorizedOwner(chainId, veAngle.future_admin())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("veANGLE - future admin: ", vm.toString(veAngle.future_admin())) - ); - jsonIndex++; - } - if (!_authorizedOwner(chainId, veBoostProxy.admin())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("veBoostProxy - admin: ", vm.toString(veBoostProxy.admin())) - ); - jsonIndex++; - } - if (!_authorizedOwner(chainId, veBoostProxy.future_admin())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("veBoostProxy - future admin: ", vm.toString(veBoostProxy.future_admin())) - ); - jsonIndex++; - } - } else { - ProposalReceiver proposalReceiver = ProposalReceiver( - payable(_chainToContract(chainId, ContractType.ProposalReceiver)) - ); - if (!_authorizedOwner(chainId, proposalReceiver.owner())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("Proposal Receiver - owner: ", vm.toString(proposalReceiver.owner())) - ); - jsonIndex++; - } - } - - if (_isCoreChain(chainId)) { - IAccessControlCore angleRouter = IAccessControlCore( - _chainToContract(chainId, ContractType.AngleRouter) - ); - if (!_authorizedCore(chainId, angleRouter.core())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("Angle Router - core: ", vm.toString(angleRouter.core())) - ); - jsonIndex++; - } - } - - if (_isAngleDeployed(chainId) && chainId != CHAIN_POLYGON) { - _checkOnLZToken( - chainId, - ILayerZeroBridge(_chainToContract(chainId, ContractType.AngleLZ)), - angleLZ, - ContractType.Angle, - ContractType.TreasuryAgEUR - ); - } - - if (_isMerklDeployed(chainId)) { - IAccessControlCore distributionCreator = IAccessControlCore( - _chainToContract(chainId, ContractType.DistributionCreator) - ); - IAccessControlCore distributor = IAccessControlCore( - _chainToContract(chainId, ContractType.Distributor) - ); - if (!_authorizedCoreMerkl(chainId, address(distributionCreator.core()))) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("Distribution creator - wrong core: ", vm.toString(distributionCreator.core())) - ); - jsonIndex++; - } - if (!_authorizedCoreMerkl(chainId, address(distributor.core()))) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("Distributor - wrong core: ", vm.toString(distributor.core())) - ); - jsonIndex++; - } - } - - if (_isSavingsDeployed(chainId)) { - ISavings stEUR = ISavings(_chainToContract(chainId, ContractType.StEUR)); - ISavings stUSD = ISavings(_chainToContract(chainId, ContractType.StUSD)); - if (!_authorizedCore(chainId, address(stEUR.accessControlManager()))) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat( - "StEUR - wrong access control manager: ", - vm.toString(stEUR.accessControlManager()) - ) - ); - jsonIndex++; - } - if (!_authorizedCore(chainId, address(stUSD.accessControlManager()))) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat( - "StUSD - wrong access control manager: ", - vm.toString(stUSD.accessControlManager()) - ) - ); - jsonIndex++; - } - } - - ProxyAdmin proxyAdmin = ProxyAdmin(_chainToContract(chainId, ContractType.ProxyAdmin)); - - if (!_authorizedProxyAdminOwner(chainId, proxyAdmin.owner())) { - output = vm.serializeString( - json, - vm.toString(jsonIndex), - string.concat("Proxy Admin - owner: ", vm.toString(proxyAdmin.owner())) - ); - jsonIndex++; - } - _checkOnLZToken( - chainId, - ILayerZeroBridge(_chainToContract(chainId, ContractType.AgEURLZ)), - "AgEUR LZ", - ContractType.AgEUR, - ContractType.TreasuryAgEUR - ); - _checkOnLZToken( - chainId, - ILayerZeroBridge(_chainToContract(chainId, ContractType.AgUSDLZ)), - "AgUSD LZ", - ContractType.AgUSD, - ContractType.TreasuryAgUSD - ); - _checkVaultManagers(chainId, ContractType.TreasuryAgEUR); - _checkVaultManagers(chainId, ContractType.TreasuryAgUSD); - - if (_revertOnWrongFunctioCall(chainId)) { - for (uint256 i = 0; i < allContracts.length; i++) { - _checkGlobalAccessControl(chainId, IGenericAccessControl(allContracts[i])); - } - } - } - - // Contract to check roles on - IAgToken agEUR = IAgToken(_chainToContract(chainId, ContractType.AgEUR)); - IAgToken agUSD = IAgToken(_chainToContract(chainId, ContractType.AgUSD)); - CoreBorrow core = CoreBorrow(_chainToContract(chainId, ContractType.CoreBorrow)); - TimelockControllerWithCounter timelock = TimelockControllerWithCounter( - payable(_chainToContract(chainId, ContractType.Timelock)) - ); - for (uint256 i = 0; i < listAddressToCheck.length; i++) { - outputActor = ""; - jsonActor = vm.toString(listAddressToCheck[i]); - jsonActorIndex = 0; - address actor = listAddressToCheck[i]; - if (agEUR.isMinter(actor) && !_authorizedMinter(chainId, actor)) { - outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "AgEUR - minter role"); - jsonActorIndex++; - } - if (agUSD.isMinter(actor) && !_authorizedMinter(chainId, actor)) { - outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "AgUSD - minter role"); - jsonActorIndex++; - } - if (core.hasRole(GOVERNOR_ROLE, actor) && !_authorizedGovernor(chainId, actor)) { - outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Borrow - governor role"); - jsonActorIndex++; - } - if (core.hasRole(GUARDIAN_ROLE, actor) && !_authorizedGuardian(chainId, actor)) { - outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Core Borrow - guardian role"); - jsonActorIndex++; - } - if (core.hasRole(FLASHLOANER_TREASURY_ROLE, actor) && !_authorizedFlashloaner(chainId, actor)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - "Core Borrow - flashloan role" - ); - jsonActorIndex++; - } - if (timelock.hasRole(PROPOSER_ROLE, actor) && !_authorizedProposer(chainId, actor)) { - outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Timelock - proposer role"); - jsonActorIndex++; - } - if (timelock.hasRole(CANCELLER_ROLE, actor) && !_authorizedCanceller(chainId, actor)) { - outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Timelock - canceller role"); - jsonActorIndex++; - } - if (timelock.hasRole(EXECUTOR_ROLE, actor) && !_authorizedExecutor(chainId, actor)) { - outputActor = vm.serializeString(jsonActor, vm.toString(jsonActorIndex), "Timelock - executor role"); - jsonActorIndex++; - } - if (timelock.hasRole(DEFAULT_ADMIN_ROLE, actor) && !_authorizeDefaultAdmin(chainId, actor)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - "Timelock - default admin role" - ); - jsonActorIndex++; - } - - if (_revertOnWrongFunctioCall(chainId)) { - for (uint256 j = 0; j < allContracts.length; j++) { - _checkAddressAccessControl(chainId, IGenericAccessControl(allContracts[j]), actor); - } - } - - if (_isMerklDeployed(chainId)) { - CoreBorrow coreMerkl = CoreBorrow(_chainToContract(chainId, ContractType.CoreMerkl)); - if (coreMerkl.hasRole(GOVERNOR_ROLE, actor) && !_authorizedGovernor(chainId, actor)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - "Core Merkl - governor role" - ); - jsonActorIndex++; - } - if (coreMerkl.hasRole(GUARDIAN_ROLE, actor) && !_authorizedGuardian(chainId, actor)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - "Core Merkl - guardian role" - ); - jsonActorIndex++; - } - // No one should have this role - if (coreMerkl.hasRole(FLASHLOANER_TREASURY_ROLE, actor)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - "Core Merkl - flashloan role" - ); - jsonActorIndex++; - } - } - - if (chainId == CHAIN_ETHEREUM) { - IAccessControl angleDistributor = IAccessControl( - _chainToContract(chainId, ContractType.AngleDistributor) - ); - if (angleDistributor.hasRole(GOVERNOR_ROLE, actor) && !_authorizedGovernor(chainId, actor)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - "Angle distributor - governor role" - ); - jsonActorIndex++; - } - if (angleDistributor.hasRole(GUARDIAN_ROLE, actor) && !_authorizedGuardian(chainId, actor)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - "Angle distributor - guardian role" - ); - jsonActorIndex++; - } - } - if (outputActor.toSlice().len() != 0) { - output = vm.serializeString(json, vm.toString(listAddressToCheck[i]), outputActor); - } - } - } - - /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - CHECKS - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - - function _checkOnLZToken( - uint256 chainId, - ILayerZeroBridge token, - string memory nameToken, - ContractType contractType, - ContractType contractTypeTreasury - ) internal returns (bool) { - if (token.canonicalToken() != _chainToContract(chainId, contractType)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(nameToken, " - wrong canonical token: ", vm.toString(token.canonicalToken())) - ); - jsonActorIndex++; - } - if (contractType == ContractType.Angle) { - if (!_authorizedCore(chainId, token.coreBorrow())) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(nameToken, " - wrong core borrow: ", vm.toString(token.coreBorrow())) - ); - jsonActorIndex++; - } - } else { - if (token.treasury() != _chainToContract(chainId, contractTypeTreasury)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(nameToken, " - wrong treasury: ", vm.toString(token.treasury())) - ); - jsonActorIndex++; - } - } - if (token.lzEndpoint() != address(_lzEndPoint(chainId))) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(nameToken, " - wrong endpoint: ", vm.toString(token.lzEndpoint())) - ); - jsonActorIndex++; - } - } - - function _checkVaultManagers(uint256 chainId, ContractType treasuryType) internal { - ITreasury treasury = ITreasury(_chainToContract(chainId, treasuryType)); - uint256 i; - while (true) { - try treasury.vaultManagerList(i) returns (address vault) { - if (address(IVaultManager(vault).treasury()) != address(treasury)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat( - IERC721Metadata(vault).name(), - "Vault Manager - wrong treasury: ", - vm.toString(address(treasury)) - ) - ); - jsonActorIndex++; - } - i++; - } catch { - break; - } - } - } - - function _checkGlobalAccessControl(uint256 chainId, IGenericAccessControl contractToCheck) public { - try contractToCheck.owner() returns (address owner) { - if (!_authorizedOwner(chainId, owner)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " owner: ", vm.toString(owner)) - ); - jsonActorIndex++; - } - } catch {} - try contractToCheck.minter() returns (address minter) { - if (!_authorizedOwner(chainId, minter)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " minter: ", vm.toString(minter)) - ); - jsonActorIndex++; - } - } catch {} - try contractToCheck.treasury() returns (address treasury) { - if (!_authorizedTreasury(chainId, treasury)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " treasury: ", vm.toString(treasury)) - ); - jsonActorIndex++; - } - } catch {} - try contractToCheck.coreBorrow() returns (address coreBorrow) { - if (!_authorizedCore(chainId, coreBorrow)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " core borrow: ", vm.toString(coreBorrow)) - ); - jsonActorIndex++; - } - } catch {} - try contractToCheck.core() returns (address coreBorrow) { - if (!_authorizedCore(chainId, coreBorrow)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " core borrow: ", vm.toString(coreBorrow)) - ); - jsonActorIndex++; - } - } catch {} - try contractToCheck.admin() returns (address admin) { - if (!_authorizedOwner(chainId, admin)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " admin: ", vm.toString(admin)) - ); - jsonActorIndex++; - } - } catch {} - try contractToCheck.future_admin() returns (address future_admin) { - if (!_authorizedOwner(chainId, future_admin)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " future admin: ", vm.toString(future_admin)) - ); - jsonActorIndex++; - } - } catch {} - } - - function _checkAddressAccessControl( - uint256 chainId, - IGenericAccessControl contractToCheck, - address addressToCheck - ) public { - try contractToCheck.isMinter(addressToCheck) returns (bool isMinter) { - if (isMinter && !_authorizedMinter(chainId, addressToCheck)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " minter: ") - ); - jsonActorIndex++; - } - } catch {} - try contractToCheck.isTrusted(addressToCheck) returns (bool isTrusted) { - if (isTrusted && !_authorizedTrusted(chainId, addressToCheck)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " trusted: ") - ); - jsonActorIndex++; - } - } catch {} - try contractToCheck.trusted(addressToCheck) returns (uint256 isTrusted) { - if (isTrusted > 0 && !_authorizedTrusted(chainId, addressToCheck)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " trusted: ") - ); - jsonActorIndex++; - } - } catch {} - bytes32[] memory listRoles = _listRoles(); - for (uint256 i = 0; i < listRoles.length; i++) { - try contractToCheck.hasRole(listRoles[i], addressToCheck) returns (bool hasRole) { - if (hasRole && !_mapCheckRoles(i, chainId, addressToCheck)) { - outputActor = vm.serializeString( - jsonActor, - vm.toString(jsonActorIndex), - string.concat(vm.toString(address(contractToCheck)), " have role: ", _nameRoles(i)) - ); - jsonActorIndex++; - } - } catch {} - } - } - - /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - CONSTANTS - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - - function _listRoles() internal pure returns (bytes32[] memory listRoles) { - listRoles = new bytes32[](10); - listRoles[0] = GOVERNOR_ROLE; - listRoles[1] = GUARDIAN_ROLE; - listRoles[2] = FLASHLOANER_TREASURY_ROLE; - listRoles[3] = TIMELOCK_ADMIN_ROLE; - listRoles[4] = PROPOSER_ROLE; - listRoles[5] = EXECUTOR_ROLE; - listRoles[6] = CANCELLER_ROLE; - listRoles[7] = KEEPER_ROLE; - listRoles[8] = DISTRIBUTOR_ROLE; - listRoles[9] = DEFAULT_ADMIN_ROLE; - } - - function _nameRoles(uint256 index) internal pure returns (string memory nameRole) { - if (index == 0) return "GOVERNOR"; - if (index == 1) return "GUARDIAN"; - if (index == 2) return "FLASHLOANER_TREASURY"; - if (index == 3) return "TIMELOCK_ADMIN"; - if (index == 4) return "PROPOSER"; - if (index == 5) return "EXECUTOR"; - if (index == 6) return "CANCELLER"; - if (index == 7) return "KEEPER"; - if (index == 8) return "DISTRIBUTOR"; - if (index == 9) return "DEFAULT_ADMIN"; - } - - function _mapCheckRoles(uint256 index, uint256 chainId, address addressToCheck) internal returns (bool) { - if (index == 0) return _authorizedGovernor(chainId, addressToCheck); - if (index == 1) return _authorizedGuardian(chainId, addressToCheck); - if (index == 2) return _authorizedFlashloaner(chainId, addressToCheck); - if (index == 3) return _authorizedTimelockAdmin(chainId, addressToCheck); - if (index == 4) return _authorizedProposer(chainId, addressToCheck); - if (index == 5) return _authorizedExecutor(chainId, addressToCheck); - if (index == 6) return _authorizedCanceller(chainId, addressToCheck); - if (index == 7) return _authorizedKeeper(chainId, addressToCheck); - if (index == 8) return _authorizedDistributor(chainId, addressToCheck); - if (index == 9) return _authorizeDefaultAdmin(chainId, addressToCheck); - } - - function _isCoreChain(uint256 chainId) internal pure returns (bool) { - return - chainId == CHAIN_ETHEREUM || - chainId == CHAIN_ARBITRUM || - chainId == CHAIN_AVALANCHE || - chainId == CHAIN_OPTIMISM || - chainId == CHAIN_POLYGON || - chainId == CHAIN_GNOSIS; - } - - function _isAngleDeployed(uint256 chainId) internal pure returns (bool) { - return - chainId == CHAIN_ETHEREUM || - chainId == CHAIN_ARBITRUM || - chainId == CHAIN_AURORA || - chainId == CHAIN_AVALANCHE || - chainId == CHAIN_BNB || - chainId == CHAIN_FANTOM || - chainId == CHAIN_OPTIMISM || - chainId == CHAIN_POLYGON; - } - - function _isMerklDeployed(uint256 chainId) internal pure returns (bool) { - return - chainId == CHAIN_ETHEREUM || - chainId == CHAIN_ARBITRUM || - chainId == CHAIN_AVALANCHE || - chainId == CHAIN_BASE || - chainId == CHAIN_BNB || - chainId == CHAIN_GNOSIS || - chainId == CHAIN_LINEA || - chainId == CHAIN_MANTLE || - chainId == CHAIN_OPTIMISM || - chainId == CHAIN_POLYGON || - chainId == CHAIN_POLYGONZKEVM; - } - - function _isSavingsDeployed(uint256 chainId) internal pure returns (bool) { - return - chainId == CHAIN_ETHEREUM || - chainId == CHAIN_ARBITRUM || - chainId == CHAIN_AVALANCHE || - chainId == CHAIN_BASE || - chainId == CHAIN_BNB || - chainId == CHAIN_CELO || - chainId == CHAIN_GNOSIS || - chainId == CHAIN_OPTIMISM || - chainId == CHAIN_POLYGON || - chainId == CHAIN_POLYGONZKEVM; - } - - function _revertOnWrongFunctioCall(uint256 chainId) internal pure returns (bool) { - return chainId != CHAIN_CELO; - } - - /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - HELPERS - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/ - - function _authorizedOwner(uint256 chainId, address owner) internal returns (bool) { - return - owner == address(0) || - owner == _chainToContract(chainId, ContractType.GovernorMultisig) || - // owner == _chainToContract(chainId, ContractType.GuardianMultisig) || - owner == _chainToContract(chainId, ContractType.Timelock) || - owner == _chainToContract(chainId, ContractType.CoreBorrow) || - owner == _chainToContract(chainId, ContractType.ProxyAdmin) || - ((chainId == CHAIN_SOURCE) ? owner == _chainToContract(chainId, ContractType.Governor) : false); - } - - function _authorizedGovernor(uint256 chainId, address governor) internal returns (bool) { - return - governor == address(0) || - governor == _chainToContract(chainId, ContractType.GovernorMultisig) || - governor == _chainToContract(chainId, ContractType.Timelock) || - governor == _chainToContract(chainId, ContractType.CoreBorrow) || - governor == _chainToContract(chainId, ContractType.ProxyAdmin) || - ((chainId == CHAIN_SOURCE) ? governor == _chainToContract(chainId, ContractType.Governor) : false); - } - - function _authorizedGuardian(uint256 chainId, address guardian) internal returns (bool) { - return - guardian == address(0) || - guardian == _chainToContract(chainId, ContractType.GovernorMultisig) || - guardian == _chainToContract(chainId, ContractType.GuardianMultisig) || - guardian == _chainToContract(chainId, ContractType.Timelock) || - guardian == _chainToContract(chainId, ContractType.CoreBorrow) || - guardian == _chainToContract(chainId, ContractType.ProxyAdmin) || - ((chainId == CHAIN_SOURCE) ? guardian == _chainToContract(chainId, ContractType.Governor) : false); - } - - /// @notice Vault Managers are also minter - function _authorizedMinter(uint256 chainId, address minter) internal returns (bool) { - return - minter == address(0) || - minter == _chainToContract(chainId, ContractType.GovernorMultisig) || - minter == _chainToContract(chainId, ContractType.Timelock); - } - - function _authorizedCore(uint256 chainId, address core) internal returns (bool) { - // TODO remove tmp core when USD linked to real one - return core == _chainToContract(chainId, ContractType.CoreBorrow) || core == tmpCoreBorrowUSD; - } - - function _authorizedCoreMerkl(uint256 chainId, address core) internal returns (bool) { - return core == _chainToContract(chainId, ContractType.CoreMerkl); - } - - // TODO need to be fine grained for multiple stablecoins - function _authorizedFlashloaner(uint256 chainId, address loaner) internal returns (bool) { - return - loaner == address(0) || - loaner == _chainToContract(chainId, ContractType.TreasuryAgEUR) || - loaner == _chainToContract(chainId, ContractType.TreasuryAgUSD); - } - - function _authorizedProposer(uint256 chainId, address proposer) internal returns (bool) { - return - (chainId == CHAIN_SOURCE) - ? proposer == _chainToContract(chainId, ContractType.Governor) - : proposer == _chainToContract(chainId, ContractType.ProposalReceiver); - } - - function _authorizedExecutor(uint256 chainId, address executor) internal returns (bool) { - return executor == _chainToContract(chainId, ContractType.GuardianMultisig); - } - - function _authorizedCanceller(uint256 chainId, address canceller) internal returns (bool) { - return canceller == _chainToContract(chainId, ContractType.GuardianMultisig); - } - - function _authorizedTimelockAdmin(uint256 chainId, address admin) internal returns (bool) { - return false; - } - - function _authorizeDefaultAdmin(uint256 chainId, address admin) internal returns (bool) { - return false; - } - - function _authorizedKeeper(uint256 chainId, address keeper) internal returns (bool) { - // return ( - // (chainId == CHAIN_POLYGON) - // ? (keeper == oldKeeperPolygon || keeper == oldKeeperPolygon2) - // : keeper == oldKeeper - // ); - return false; - } - - function _authorizedTrusted(uint256 chainId, address trusted) internal returns (bool) { - return - trusted == _chainToContract(chainId, ContractType.GovernorMultisig) || - trusted == _chainToContract(chainId, ContractType.GuardianMultisig) || - trusted == _chainToContract(chainId, ContractType.Timelock) || - trusted == _chainToContract(chainId, ContractType.CoreBorrow) || - trusted == _chainToContract(chainId, ContractType.ProxyAdmin) || - // trusted == oldDeployer || - // trusted == oldKeeper || - // trusted == oldKeeperPolygon || - // trusted == oldKeeperPolygon2 || - // trusted == merklKeeper || - ((chainId == CHAIN_SOURCE) ? trusted == _chainToContract(chainId, ContractType.Governor) : false); - } - - function _authorizedDistributor(uint256 chainId, address distributor) internal returns (bool) { - return - (chainId == CHAIN_ETHEREUM) - ? distributor == _chainToContract(chainId, ContractType.AngleDistributor) - : false; - } - - function _authorizedProxyAdminOwner(uint256 chainId, address owner) internal returns (bool) { - return owner == _chainToContract(chainId, ContractType.GovernorMultisig); - } - - function _authorizedTreasury(uint256 chainId, address treasury) internal returns (bool) { - return - treasury == _chainToContract(chainId, ContractType.TreasuryAgEUR) || - treasury == _chainToContract(chainId, ContractType.TreasuryAgUSD); - } -} From 7c61b8dd73e9948ac7c61a945414ee738599357d Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Tue, 16 Jul 2024 10:27:06 +0200 Subject: [PATCH 25/26] fix: compilation --- lib/utils | 2 +- test/invariant/DelegationInvariants.t.sol | 5 ++--- test/invariant/MainnetGovernorInvariants.t.sol | 2 +- test/invariant/actors/Proposer.t.sol | 4 ++-- test/unit/SimulationSetup.t.sol | 5 ++++- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/utils b/lib/utils index 68f85f5..e64751f 160000 --- a/lib/utils +++ b/lib/utils @@ -1 +1 @@ -Subproject commit 68f85f572e730690e9ed0bd056eafcc6f85641f0 +Subproject commit e64751fc263a2f3a7f52563da3c010a13195cb6b diff --git a/test/invariant/DelegationInvariants.t.sol b/test/invariant/DelegationInvariants.t.sol index ea9c33c..73b259b 100644 --- a/test/invariant/DelegationInvariants.t.sol +++ b/test/invariant/DelegationInvariants.t.sol @@ -26,7 +26,7 @@ contract DelegationInvariants is Fixture { _paramHandler = new Param(_NUM_PARAMS, ANGLE); // Label newly created addresses - for (uint256 i; i < _NUM_DELEGATORS; i++) { + for (uint256 i; i < _NUM_DELEGATORS; i++) vm.label(_delegatorHandler.actors(i), string.concat("Delegator ", Strings.toString(i))); vm.label({ account: address(_paramHandler), newLabel: "Param" }); @@ -85,9 +85,8 @@ contract DelegationInvariants is Fixture { for (uint256 i; i < _NUM_DELEGATORS; i++) { address actor = _delegatorHandler.actors(i); address delegatee = _delegatorHandler.delegations(actor); - if (delegatee != address(0) && delegatee != actor) { + if (delegatee != address(0) && delegatee != actor) assertEq(token.getVotes(actor), 0, "Delegator should have null vote"); - } } } diff --git a/test/invariant/MainnetGovernorInvariants.t.sol b/test/invariant/MainnetGovernorInvariants.t.sol index 197dd0b..142e716 100644 --- a/test/invariant/MainnetGovernorInvariants.t.sol +++ b/test/invariant/MainnetGovernorInvariants.t.sol @@ -10,7 +10,7 @@ import { Proposer } from "./actors/Proposer.t.sol"; import { BadVoter } from "./actors/BadVoter.t.sol"; import { Fixture, AngleGovernor } from "../Fixture.t.sol"; import { ProposalStore, Proposal } from "./stores/ProposalStore.sol"; -import { IGovernor } from "oz/governance/IGovernor.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; //solhint-disable import { console } from "forge-std/console.sol"; diff --git a/test/invariant/actors/Proposer.t.sol b/test/invariant/actors/Proposer.t.sol index 9cc9b13..80a1bb4 100644 --- a/test/invariant/actors/Proposer.t.sol +++ b/test/invariant/actors/Proposer.t.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.19; import { BaseActor, IERC20, IERC20Metadata, AngleGovernor, TestStorage } from "./BaseActor.t.sol"; import { console } from "forge-std/console.sol"; -import { IGovernor } from "oz/governance/IGovernor.sol"; +import { IGovernor } from "oz-v5/governance/IGovernor.sol"; import { ProposalStore, Proposal } from "../stores/ProposalStore.sol"; -import { IERC5805 } from "oz/interfaces/IERC5805.sol"; +import { IERC5805 } from "oz-v5/interfaces/IERC5805.sol"; contract Proposer is BaseActor { AngleGovernor internal _angleGovernor; diff --git a/test/unit/SimulationSetup.t.sol b/test/unit/SimulationSetup.t.sol index 9c0f24c..6926226 100644 --- a/test/unit/SimulationSetup.t.sol +++ b/test/unit/SimulationSetup.t.sol @@ -51,7 +51,10 @@ contract SimulationSetup is Test, CommonUtils { mapChainIds[10] = "OPTIMISM"; setUpForks(); - // TODO Complete with all deployed chains + if (vm.envExists("ETH_NODE_URI_FORK")) { + chainFork = vm.createFork(vm.envString("ETH_NODE_URI_FORK")); + forkIdentifier[CHAIN_FORK] = chainFork; + } veANGLEDelegation = new VeANGLEVotingDelegation(address(veANGLE), "veANGLE Delegation", "1"); From 221afe14fa6fb6e1a466c5354867c62eaf12805a Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Tue, 16 Jul 2024 11:35:09 +0200 Subject: [PATCH 26/26] fix compilation script --- .../proposals/nameable/UpgradeAgTokenNameable.s.sol | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/proposals/nameable/UpgradeAgTokenNameable.s.sol b/scripts/proposals/nameable/UpgradeAgTokenNameable.s.sol index 53beb94..f153f74 100644 --- a/scripts/proposals/nameable/UpgradeAgTokenNameable.s.sol +++ b/scripts/proposals/nameable/UpgradeAgTokenNameable.s.sol @@ -4,14 +4,20 @@ pragma solidity ^0.8.19; import { console } from "forge-std/console.sol"; import { Wrapper } from "../Wrapper.s.sol"; import "../../Constants.s.sol"; -import { ProxyAdmin } from "oz/proxy/transparent/ProxyAdmin.sol"; contract UpgradeAgTokenNameable is Wrapper { SubCall[] private subCalls; mapping(uint256 => address) private _chainToToken; mapping(uint256 => address) private _chainToImplementation; - function _upgradeAgToken(uint256 chainId, string memory name, string memory symbol, address proxy, address implementation, address proxyAdmin) private { + function _upgradeAgToken( + uint256 chainId, + string memory name, + string memory symbol, + address proxy, + address implementation, + address proxyAdmin + ) private { vm.selectFork(forkIdentifier[chainId]); bytes memory nameAndSymbolData = abi.encodeWithSelector(INameable.setNameAndSymbol.selector, name, symbol);