diff --git a/.gitmodules b/.gitmodules index 94e23a0..0201154 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,12 +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 -[submodule "lib/openzeppelin-contracts-upgradeable"] - path = lib/openzeppelin-contracts-upgradeable - url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable [submodule "lib/solidity-examples"] path = lib/solidity-examples url = https://github.com/LayerZero-Labs/solidity-examples @@ -17,9 +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 [submodule "lib/borrow-contracts"] path = lib/borrow-contracts url = https://github.com/AngleProtocol/borrow-contracts @@ -38,3 +29,22 @@ [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 + version = v4.7.3 +[submodule "lib/openzeppelin-contracts"] + path = lib/openzeppelin-contracts + url = https://github.com/OpenZeppelin/openzeppelin-contracts + version = v4.7.3 +[submodule "lib/old-oz"] + 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 + version = ebf264cc4b812e6557ed7d539e947211acd5670c +[submodule "lib/angle-transmuter"] + path = lib/angle-transmuter + url = https://github.com/AngleProtocol/angle-transmuter diff --git a/.vscode/settings.json b/.vscode/settings.json index e6b354a..261c161 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,10 @@ { "solidity.compileUsingRemoteVersion": "0.8.20", + "[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..75062f3 100644 --- a/contracts/AngleGovernor.sol +++ b/contracts/AngleGovernor.sol @@ -2,13 +2,14 @@ pragma solidity ^0.8.20; -import { IVotes } from "oz/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 { 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 { 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"; import { GovernorCountingFractional } from "./external/GovernorCountingFractional.sol"; import { GovernorShortCircuit } from "./external/GovernorShortCircuit.sol"; diff --git a/contracts/ProposalReceiver.sol b/contracts/ProposalReceiver.sol index e9c5218..d6a53f7 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"; @@ -51,7 +51,7 @@ contract ProposalReceiver is NonblockingLzApp, ReentrancyGuard { /// @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[])); + .decode(_payload, (address[], uint256[], string[], bytes[])); for (uint256 i = 0; i < targets.length; i++) { _executeTransaction(targets[i], values[i], signatures[i], calldatas[i]); diff --git a/contracts/ProposalSender.sol b/contracts/ProposalSender.sol index 3e60aec..12f59c0 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 ); @@ -70,7 +70,7 @@ contract ProposalSender is Ownable, ReentrancyGuard { uint16 remoteChainId, bytes calldata payload, bytes calldata adapterParams - ) external view returns (uint nativeFee, uint zroFee) { + ) external view returns (uint256 nativeFee, uint256 zroFee) { return lzEndpoint.estimateFees(remoteChainId, address(this), payload, false, adapterParams); } @@ -122,7 +122,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(); @@ -156,7 +156,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 +170,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..97d0010 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 diff --git a/contracts/VeANGLEVotingDelegation.sol b/contracts/VeANGLEVotingDelegation.sol index 8d3efc4..1c723de 100644 --- a/contracts/VeANGLEVotingDelegation.sol +++ b/contracts/VeANGLEVotingDelegation.sol @@ -1,11 +1,11 @@ // 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 { 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"; diff --git a/contracts/external/GovernorCountingFractional.sol b/contracts/external/GovernorCountingFractional.sol index c03fbbc..3439c3e 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"; diff --git a/contracts/external/GovernorShortCircuit.sol b/contracts/external/GovernorShortCircuit.sol index 021e1fa..d592bb5 100644 --- a/contracts/external/GovernorShortCircuit.sol +++ b/contracts/external/GovernorShortCircuit.sol @@ -2,10 +2,10 @@ 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 { 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"; diff --git a/foundry.toml b/foundry.toml index ab5cec6..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"}] +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/helpers/createProposal.sh b/helpers/createProposal.sh index 1cfc17b..2580616 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" @@ -53,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" @@ -95,7 +97,7 @@ function main { echo "Running on chains $chainIds" export CHAIN_IDS=$chainIds - FOUNDRY_PROFILE=dev forge script $script + forge script $script -vvv if [ $? -ne 0 ]; then echo "" @@ -106,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 "" @@ -118,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/lib/angle-transmuter b/lib/angle-transmuter index 7fd03d3..6aecf1a 160000 --- a/lib/angle-transmuter +++ b/lib/angle-transmuter @@ -1 +1 @@ -Subproject commit 7fd03d3135c8d2ee8bcfe174b5b80c309823560f +Subproject commit 6aecf1a1014b0b58dbb824370c7a9d424361437c 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 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 diff --git a/lib/openzeppelin-contracts b/lib/openzeppelin-contracts index cffb2f1..ecd2ca2 160000 --- a/lib/openzeppelin-contracts +++ b/lib/openzeppelin-contracts @@ -1 +1 @@ -Subproject commit cffb2f1ddcd87efd68effc92cfd336c5145acabd +Subproject commit ecd2ca2cd7cac116f7a37d0e474bbb3d7d5e1c4d diff --git a/lib/openzeppelin-contracts-upgradeable b/lib/openzeppelin-contracts-upgradeable index ebf264c..0a2cb9a 160000 --- a/lib/openzeppelin-contracts-upgradeable +++ b/lib/openzeppelin-contracts-upgradeable @@ -1 +1 @@ -Subproject commit ebf264cc4b812e6557ed7d539e947211acd5670c +Subproject commit 0a2cb9a445c365870ed7a8ab461b12acf3e27d63 diff --git a/lib/utils b/lib/utils index 3b7a747..e64751f 160000 --- a/lib/utils +++ b/lib/utils @@ -1 +1 @@ -Subproject commit 3b7a747213be6a1210b1c92d92c7688798a74edf +Subproject commit e64751fc263a2f3a7f52563da3c010a13195cb6b diff --git a/remappings.txt b/remappings.txt index 962e7d4..6798424 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 @@ -9,7 +9,9 @@ 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 utils/=lib/utils \ No newline at end of file diff --git a/scripts/Constants.s.sol b/scripts/Constants.s.sol index fa5415d..a58a671 100644 --- a/scripts/Constants.s.sol +++ b/scripts/Constants.s.sol @@ -3,14 +3,14 @@ pragma solidity ^0.8.9; import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.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/proxy/transparent/ProxyAdmin.sol"; -import { Ownable } from "oz/access/Ownable.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/governance/TimelockController.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..a03e311 100644 --- a/scripts/Interfaces.s.sol +++ b/scripts/Interfaces.s.sol @@ -1,6 +1,6 @@ pragma solidity ^0.8.19; -import { IAccessControl } from "oz/access/IAccessControl.sol"; +import { IAccessControl } from "oz-v5/access/IAccessControl.sol"; import { IAccessControlManager } from "interfaces/IAccessControlManager.sol"; interface IAccessControlCore { diff --git a/scripts/deployment/DeployOnChainGovernance.s.sol b/scripts/deployment/DeployOnChainGovernance.s.sol index 73065ab..fc142ba 100644 --- a/scripts/deployment/DeployOnChainGovernance.s.sol +++ b/scripts/deployment/DeployOnChainGovernance.s.sol @@ -5,11 +5,11 @@ 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 { ERC20 } from "oz-v5/token/ERC20/ERC20.sol"; import "contracts/interfaces/IveANGLE.sol"; import "../../test/external/VyperDeployer.sol"; diff --git a/scripts/deployment/DeploySideChainGovernance.s.sol b/scripts/deployment/DeploySideChainGovernance.s.sol index e50f187..1cce3c9 100644 --- a/scripts/deployment/DeploySideChainGovernance.s.sol +++ b/scripts/deployment/DeploySideChainGovernance.s.sol @@ -5,10 +5,10 @@ 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 { ERC20 } from "oz-v5/token/ERC20/ERC20.sol"; import { ProposalReceiver } from "contracts/ProposalReceiver.sol"; import { ProposalSender } from "contracts/ProposalSender.sol"; diff --git a/scripts/interfaces/ITransmuter.sol b/scripts/interfaces/ITransmuter.sol new file mode 100644 index 0000000..aa2f888 --- /dev/null +++ b/scripts/interfaces/ITransmuter.sol @@ -0,0 +1,11 @@ +// 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/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 39d9f04..e0792e7 100644 --- a/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol +++ b/scripts/proposals/angleGovernor/IncreaseQuorum.s.sol @@ -3,7 +3,7 @@ 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 { GovernorVotesQuorumFraction } from "oz-v5/governance/extensions/GovernorVotesQuorumFraction.sol"; import { GovernorShortCircuit } from "contracts/external/GovernorShortCircuit.sol"; import "../../Constants.s.sol"; @@ -40,13 +40,16 @@ 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 */ + /** + * 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); 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); diff --git a/scripts/proposals/payload.json b/scripts/proposals/payload.json index 6c2f61c..1781e1b 100644 --- a/scripts/proposals/payload.json +++ b/scripts/proposals/payload.json @@ -1,11 +1,11 @@ { "calldatas": { - "0": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001517f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000748ba9cd5a5ddba5aba70a4ac861b2413dca4436000000000000000000000000748ba9cd5a5ddba5aba70a4ac861b2413dca44360000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002406f3f9e6000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002443ec3e09000000000000000000000000000000000000000000000000000000000000004b00000000000000000000000000000000000000000000000000000000" + "0": "0x8f2a0bb000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000151800000000000000000000000000000000000000000000000000000000000000002000000000000000000000000748ba9cd5a5ddba5aba70a4ac861b2413dca4436000000000000000000000000748ba9cd5a5ddba5aba70a4ac861b2413dca44360000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002406f3f9e6000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002443ec3e09000000000000000000000000000000000000000000000000000000000000004b00000000000000000000000000000000000000000000000000000000" }, "chainIds": { "0": 1 }, - "description": "ipfs://QmRSdyuXeemVEn97RPRSiit6UEUonvwVr9we7bEe2w8v2E", + "description": "ipfs://QmbcRv3pSuvamZ7TtYu55gbnnUmkrxPPNU2GX6NGJecSfQ", "targets": { "0": "0x09D81464c7293C774203E46E3C921559c8E9D53f" }, diff --git a/scripts/proposals/timelock/AddExecutor.s.sol b/scripts/proposals/timelock/AddExecutor.s.sol index 0449521..4f66bfd 100644 --- a/scripts/proposals/timelock/AddExecutor.s.sol +++ b/scripts/proposals/timelock/AddExecutor.s.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.20; import { console } from "forge-std/console.sol"; -import { IAccessControl } from "oz/access/IAccessControl.sol"; +import { IAccessControl } from "oz-v5/access/IAccessControl.sol"; import { Wrapper } from "../Wrapper.s.sol"; import "../../Constants.s.sol"; @@ -28,10 +28,13 @@ 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); } diff --git a/scripts/proposals/transmuter/README.md b/scripts/proposals/transmuter/README.md new file mode 100644 index 0000000..c603807 --- /dev/null +++ b/scripts/proposals/transmuter/README.md @@ -0,0 +1,62 @@ +# Guide to test facets update + +## Angle-Transmuter repo + +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 +``` + +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 + +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 +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..905ff38 --- /dev/null +++ b/scripts/proposals/transmuter/TransmuterUpdateFacets.s.sol @@ -0,0 +1,191 @@ +// 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 { 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; + + string[] replaceFacetNames; + string[] addFacetNames; + address[] replaceFacetAddressList; + address[] addFacetAddressList; + + ITransmuter transmuter; + IERC20 agEUR; + address governor; + + SubCall[] private subCalls; + + 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"); + replaceFacetAddressList.push(GETTERS); + + replaceFacetNames.push("Redeemer"); + replaceFacetAddressList.push(REDEEMER); + + replaceFacetNames.push("SettersGovernor"); + replaceFacetAddressList.push(SETTERS_GOVERNOR); + + replaceFacetNames.push("Swapper"); + replaceFacetAddressList.push(SWAPPER); + + addFacetNames.push("SettersGovernor"); + addFacetAddressList.push(SETTERS_GOVERNOR); + + { + 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( + jsonReplace.readBytes32Array(string.concat("$.", replaceFacetNames[i])) + ); + + replaceCut[i] = Storage.FacetCut({ + facetAddress: replaceFacetAddressList[i], + action: Storage.FacetCutAction.Replace, + functionSelectors: selectors + }); + } + } + + { + string memory jsonAdd = vm.readFile(JSON_SELECTOR_PATH_ADD); + // Build appropriate payload + uint256 n = addFacetNames.length; + addCut = new Storage.FacetCut[](n); + for (uint256 i = 0; i < n; ++i) { + // Get Selectors from json + bytes4[] memory selectors = _arrayBytes32ToBytes4( + jsonAdd.readBytes32Array(string.concat("$.", addFacetNames[i])) + ); + addCut[i] = Storage.FacetCut({ + facetAddress: addFacetAddressList[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, USER_PROTECTION_EUROC) + ) + ) + ) + ); + + subCalls.push( + SubCall( + chainId, + address(transmuter), + 0, + abi.encodeWithSelector( + ISettersGovernor.setOracle.selector, + BC3M, + abi.encode( + 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, USER_PROTECTION_BC3M) + ) + ) + ) + ); + } + + function run() external { + uint256[] memory chainIds = vm.envUint("CHAIN_IDS", ","); + string memory description = "ipfs://"; + + 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..aad48d8 --- /dev/null +++ b/scripts/proposals/transmuter/TransmuterUtils.s.sol @@ -0,0 +1,83 @@ +// 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 = "./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; + address constant EUROE = 0x820802Fa8a99901F52e39acD21177b0BE6EE2974; + address constant EURE = 0x3231Cb76718CDeF2155FC47b5286d82e6eDA273f; + address constant BC3M = 0x2F123cF3F37CE3328CC9B5b8415f9EC5109b45e7; + address constant USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + + uint128 constant FIREWALL_MINT_EUROC = 0; + uint128 constant USER_PROTECTION_EUROC = uint128(5 * BPS); + uint128 constant FIREWALL_MINT_BC3M = uint128(BASE_18); + 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 = 0x99fe8557A8F322525262720C52b7d57c56924012; + address constant REDEEMER = 0xa09735EfbcfF6E76e6EfFF82A9Ad996A85cd0725; + address constant SETTERS_GOVERNOR = 0x49c7B39A2E01869d39548F232F9B1586DA8Ef9c2; + address constant SWAPPER = 0xD838bF7fB3b420ac93A7d9f5b40230F78b33536F; + + /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + 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 _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) { + 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/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/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 diff --git a/test/Constants.t.sol b/test/Constants.t.sol index 4d6deb4..da47d6b 100644 --- a/test/Constants.t.sol +++ b/test/Constants.t.sol @@ -3,7 +3,7 @@ pragma solidity ^0.8.9; import { ILayerZeroEndpoint } from "lz/lzApp/interfaces/ILayerZeroEndpoint.sol"; -import { IVotes } from "oz/governance/extensions/GovernorVotes.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..0268e44 100644 --- a/test/Fixture.t.sol +++ b/test/Fixture.t.sol @@ -4,7 +4,7 @@ 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 { ERC20 } from "oz-v5/token/ERC20/ERC20.sol"; import "contracts/interfaces/IveANGLE.sol"; import "./external/VyperDeployer.sol"; diff --git a/test/external/MockANGLE.sol b/test/external/MockANGLE.sol index 313c482..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/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..d436500 100644 --- a/test/fuzz/GovernorCountingFractional.t.sol +++ b/test/fuzz/GovernorCountingFractional.t.sol @@ -1,13 +1,13 @@ // 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 { 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"; diff --git a/test/fuzz/VeANGLEVotingDelegation.t.sol b/test/fuzz/VeANGLEVotingDelegation.t.sol index 566e115..2011f26 100644 --- a/test/fuzz/VeANGLEVotingDelegation.t.sol +++ b/test/fuzz/VeANGLEVotingDelegation.t.sol @@ -4,7 +4,7 @@ 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 { ERC20 } from "oz-v5/token/ERC20/ERC20.sol"; import "contracts/interfaces/IveANGLE.sol"; import "../external/VyperDeployer.sol"; diff --git a/test/invariant/BasicInvariants.t.sol b/test/invariant/BasicInvariants.t.sol index 86f97a3..e0b0e76 100644 --- a/test/invariant/BasicInvariants.t.sol +++ b/test/invariant/BasicInvariants.t.sol @@ -2,9 +2,9 @@ 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 { 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"; 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/BadVoter.t.sol b/test/invariant/actors/BadVoter.t.sol index d34607d..af2add8 100644 --- a/test/invariant/actors/BadVoter.t.sol +++ b/test/invariant/actors/BadVoter.t.sol @@ -4,7 +4,7 @@ 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 { IGovernor } from "oz-v5/governance/IGovernor.sol"; contract BadVoter is BaseActor { AngleGovernor internal _angleGovernor; diff --git a/test/invariant/actors/BaseActor.t.sol b/test/invariant/actors/BaseActor.t.sol index a3237c9..702c2e0 100644 --- a/test/invariant/actors/BaseActor.t.sol +++ b/test/invariant/actors/BaseActor.t.sol @@ -1,10 +1,10 @@ // 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 { 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/governance/utils/IVotes.sol"; +import { IVotes } from "oz-v5/governance/utils/IVotes.sol"; import { AngleGovernor } from "contracts/AngleGovernor.sol"; import "contracts/utils/Errors.sol"; diff --git a/test/invariant/actors/Delegator.t.sol b/test/invariant/actors/Delegator.t.sol index 1b7a7c8..14b66d3 100644 --- a/test/invariant/actors/Delegator.t.sol +++ b/test/invariant/actors/Delegator.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.19; import "./BaseActor.t.sol"; -import { IERC5805 } from "oz/interfaces/IERC5805.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"; diff --git a/test/invariant/actors/Param.t.sol b/test/invariant/actors/Param.t.sol index 11fe038..f937352 100644 --- a/test/invariant/actors/Param.t.sol +++ b/test/invariant/actors/Param.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.19; import "./BaseActor.t.sol"; -import { IERC5805 } from "oz/interfaces/IERC5805.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"; 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/invariant/actors/Voter.t.sol b/test/invariant/actors/Voter.t.sol index 44a431c..4b25f4a 100644 --- a/test/invariant/actors/Voter.t.sol +++ b/test/invariant/actors/Voter.t.sol @@ -4,7 +4,7 @@ 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 { IGovernor } from "oz-v5/governance/IGovernor.sol"; contract Voter is BaseActor { AngleGovernor internal _angleGovernor; diff --git a/test/scripts/ScriptHelpers.t.sol b/test/scripts/ScriptHelpers.t.sol index bf09152..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(); @@ -47,22 +54,29 @@ contract ScriptHelpers is Test, Utils { vm.stopPrank(); } + function _executeProposalWithFork() public returns (uint256[] memory) { + return _executeProposalInternal(true); + } + function _executeProposal() public returns (uint256[] memory) { - ( - bytes[] memory calldatas, - string memory description, - address[] memory targets, - uint256[] memory values, - uint256[] memory chainIds - ) = _deserializeJson(); + return _executeProposalInternal(false); + } - vm.selectFork(forkIdentifier[CHAIN_SOURCE]); + function _executeProposalInternal(bool isFork) public returns (uint256[] memory) { + (calldatasHelpers, descriptionHelpers, targetsHelpers, valuesHelpers, chainIdsHelpers) = _deserializeJson(); + + vm.selectFork(forkIdentifier[isFork ? CHAIN_FORK : CHAIN_SOURCE]); { AngleGovernor governor = AngleGovernor(payable(_chainToContract(CHAIN_SOURCE, ContractType.Governor))); { 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); @@ -73,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 ); } @@ -122,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); @@ -140,7 +158,7 @@ contract ScriptHelpers is Test, Utils { } } } - return chainIds; + return chainIdsHelpers; } function _executeTimelock( diff --git a/test/scripts/timelock/AddExecutor.t.sol b/test/scripts/timelock/AddExecutor.t.sol index 9d0827f..f88a8b9 100644 --- a/test/scripts/timelock/AddExecutor.t.sol +++ b/test/scripts/timelock/AddExecutor.t.sol @@ -4,8 +4,8 @@ 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 { 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"; diff --git a/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol new file mode 100644 index 0000000..c2896f2 --- /dev/null +++ b/test/scripts/transmuter/TransmuterUpdateFacetsTest.t.sol @@ -0,0 +1,253 @@ +// 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; +import { AggregatorV3Interface } from "transmuter/interfaces/external/chainlink/AggregatorV3Interface.sol"; + +contract TransmuterUpdateFacetsTest is ScriptHelpers, TransmuterUtils { + using stdJson for string; + + ITransmuter transmuter; + uint256[] chainIds; + + // TODO COMPLETE + bytes public oracleConfigDataEUROC = + hex"0000000000000000000000004305fb66699c3b2702d4d05cf36551390a4c69c600000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000276fa85158bf14ede77087fe3ae472f66213f6ea2f5b411cb2de472794990fa5ca995d00bb36a63cef7fd2c287dc105fc8f3d93779f062f09551b0af3e81ec30b000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000001275000000000000000000000000000000000000000000000000000000000000127500000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000"; + + // + + 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(1710857504), uint256(1710857504), uint80(0)) + ); + + chainIds = _executeProposalWithFork(); + } + + 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))); + + _testAccessControlManager(); + _testAgToken(); + _testGetCollateralList(); + _testGetCollateralInfo(); + _testGetOracleValues(); + } + } + + 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 _testGetCollateralInfo() internal { + { + 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, 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); + + { + 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); + { + ( + 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, 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)); + + 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) + ); + 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 _testGetOracleValues() internal { + _checkOracleValues(address(EUROC), BASE_18, FIREWALL_MINT_EUROC, USER_PROTECTION_EUROC); + _checkOracleValues(address(BC3M), (11957 * BASE_18) / 100, FIREWALL_MINT_BC3M, USER_PROTECTION_BC3M); + } + + /*////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + 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 + ); + assertApproxEqRel(targetValue, redemption, 200 * BPS); + + 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 { + assertEq(mint, redemption); + assertEq(ratio, BASE_18); + } + } +} diff --git a/test/unit/AngleGovernor.t.sol b/test/unit/AngleGovernor.t.sol index 8be2108..2587ab0 100644 --- a/test/unit/AngleGovernor.t.sol +++ b/test/unit/AngleGovernor.t.sol @@ -2,9 +2,9 @@ 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 { Test, stdError } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; diff --git a/test/unit/GovernorShortCircuit.t.sol b/test/unit/GovernorShortCircuit.t.sol index 26e3247..4e88117 100644 --- a/test/unit/GovernorShortCircuit.t.sol +++ b/test/unit/GovernorShortCircuit.t.sol @@ -2,11 +2,11 @@ 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 { 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"; diff --git a/test/unit/GovernorStateAndPropose.t.sol b/test/unit/GovernorStateAndPropose.t.sol index 9bfbe7f..828b7bc 100644 --- a/test/unit/GovernorStateAndPropose.t.sol +++ b/test/unit/GovernorStateAndPropose.t.sol @@ -2,9 +2,9 @@ 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 { Test, stdError } from "forge-std/Test.sol"; import { Vm } from "forge-std/Vm.sol"; diff --git a/test/unit/ProposalLayerZeroRelayer.t.sol b/test/unit/ProposalLayerZeroRelayer.t.sol index 53607a1..987eeff 100644 --- a/test/unit/ProposalLayerZeroRelayer.t.sol +++ b/test/unit/ProposalLayerZeroRelayer.t.sol @@ -2,10 +2,10 @@ 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 { 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"; @@ -114,13 +114,16 @@ 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); @@ -146,10 +149,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); @@ -186,7 +192,7 @@ contract ProposalLayerZeroRelayer is SimulationSetup { 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); diff --git a/test/unit/Scenarios.t.sol b/test/unit/Scenarios.t.sol index 5247327..27fd15b 100644 --- a/test/unit/Scenarios.t.sol +++ b/test/unit/Scenarios.t.sol @@ -2,9 +2,9 @@ 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 { Test, stdError } from "forge-std/Test.sol"; diff --git a/test/unit/Simulate.t.sol b/test/unit/Simulate.t.sol index 659dfd1..361f63b 100644 --- a/test/unit/Simulate.t.sol +++ b/test/unit/Simulate.t.sol @@ -2,9 +2,9 @@ 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"; diff --git a/test/unit/SimulationSetup.t.sol b/test/unit/SimulationSetup.t.sol index ef88db5..6926226 100644 --- a/test/unit/SimulationSetup.t.sol +++ b/test/unit/SimulationSetup.t.sol @@ -2,9 +2,9 @@ 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 { Test, stdError } from "forge-std/Test.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"); diff --git a/test/unit/TimelockControllerWithCounter.t.sol b/test/unit/TimelockControllerWithCounter.t.sol index 9bdc1fc..bf4b7de 100644 --- a/test/unit/TimelockControllerWithCounter.t.sol +++ b/test/unit/TimelockControllerWithCounter.t.sol @@ -2,10 +2,10 @@ 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 { 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"; @@ -658,7 +658,7 @@ contract TimelockControllerWithCounterTest is SimulationSetup { uint256 chainId, bool isBatch ) internal view returns (bytes32) { - (, , , bytes[] memory calldatas) = abi.decode(payload, (address[], uint[], string[], bytes[])); + (, , , 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);