From f2847d5917fd8d2c5e07de515044f365c0c26a93 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Tue, 8 Oct 2024 08:32:39 +0200 Subject: [PATCH 01/26] feat: add collaterals --- .../TransmuterAddCollateralEURCV.s.sol | 115 ++++++++++++++++++ .../TransmuterAddCollateralXEVT.s..sol | 115 ++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol create mode 100644 scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol new file mode 100644 index 0000000..536a788 --- /dev/null +++ b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +import { console } from "forge-std/console.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper } from "transmuter/interfaces/ITransmuter.sol"; +import { Enum } from "safe/Safe.sol"; +import { MultiSend, Utils } from "../Utils.s.sol"; +import "../Constants.s.sol"; + +contract TransmuterRevokeAddCollateral is Utils { + address public constant COLLATERAL_TO_ADD = 0x5F7827FDeb7c20b443265Fc2F40845B715385Ff2; + address public RECEIVER = 0xA9DdD91249DFdd450E81E1c56Ab60E1A62651701; + uint256 constant BPS = 1e14; + + bytes oracleConfigCollatToAdd; + uint64[] public xFeeMint; + int64[] public yFeeMint; + uint64[] public xFeeBurn; + int64[] public yFeeBurn; + address public agToken; + + function run() external { + uint256 chainId = vm.envUint("CHAIN_ID"); + + ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + agToken = address(transmuter.agToken()); + bytes memory transactions; + uint8 isDelegateCall = 0; + address to = address(transmuter); + uint256 value = 0; + + // Add the new collateral + { + { + bytes memory readData; + bytes memory targetData; + oracleConfigCollatToAdd = abi.encode( + Storage.OracleReadType.NO_ORACLE, + Storage.OracleReadType.STABLE, + readData, + targetData, + // With no oracle the below oracles are useless + abi.encode(uint128(0), uint128(50 * BPS)) + ); + } + { + bytes memory data = abi.encodeWithSelector(ISettersGovernor.addCollateral.selector, COLLATERAL_TO_ADD); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + // Mint fees + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.setFees.selector, + COLLATERAL_TO_ADD, + xFeeMint, + yFeeMint, + true + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + // Burn fees + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.setFees.selector, + COLLATERAL_TO_ADD, + xFeeBurn, + yFeeBurn, + false + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + bytes memory data = abi.encodeWithSelector( + ISettersGovernor.setOracle.selector, + COLLATERAL_TO_ADD, + oracleConfigCollatToAdd + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.togglePause.selector, + COLLATERAL_TO_ADD, + Storage.ActionType.Mint + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.togglePause.selector, + COLLATERAL_TO_ADD, + Storage.ActionType.Burn + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + } + + bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); + address multiSend = address(_chainToMultiSend(chainId)); + _serializeJson(chainId, multiSend, 0, payloadMultiSend, Enum.Operation.DelegateCall, hex""); + } +} diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol new file mode 100644 index 0000000..536a788 --- /dev/null +++ b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +import { console } from "forge-std/console.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper } from "transmuter/interfaces/ITransmuter.sol"; +import { Enum } from "safe/Safe.sol"; +import { MultiSend, Utils } from "../Utils.s.sol"; +import "../Constants.s.sol"; + +contract TransmuterRevokeAddCollateral is Utils { + address public constant COLLATERAL_TO_ADD = 0x5F7827FDeb7c20b443265Fc2F40845B715385Ff2; + address public RECEIVER = 0xA9DdD91249DFdd450E81E1c56Ab60E1A62651701; + uint256 constant BPS = 1e14; + + bytes oracleConfigCollatToAdd; + uint64[] public xFeeMint; + int64[] public yFeeMint; + uint64[] public xFeeBurn; + int64[] public yFeeBurn; + address public agToken; + + function run() external { + uint256 chainId = vm.envUint("CHAIN_ID"); + + ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + agToken = address(transmuter.agToken()); + bytes memory transactions; + uint8 isDelegateCall = 0; + address to = address(transmuter); + uint256 value = 0; + + // Add the new collateral + { + { + bytes memory readData; + bytes memory targetData; + oracleConfigCollatToAdd = abi.encode( + Storage.OracleReadType.NO_ORACLE, + Storage.OracleReadType.STABLE, + readData, + targetData, + // With no oracle the below oracles are useless + abi.encode(uint128(0), uint128(50 * BPS)) + ); + } + { + bytes memory data = abi.encodeWithSelector(ISettersGovernor.addCollateral.selector, COLLATERAL_TO_ADD); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + // Mint fees + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.setFees.selector, + COLLATERAL_TO_ADD, + xFeeMint, + yFeeMint, + true + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + // Burn fees + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.setFees.selector, + COLLATERAL_TO_ADD, + xFeeBurn, + yFeeBurn, + false + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + bytes memory data = abi.encodeWithSelector( + ISettersGovernor.setOracle.selector, + COLLATERAL_TO_ADD, + oracleConfigCollatToAdd + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.togglePause.selector, + COLLATERAL_TO_ADD, + Storage.ActionType.Mint + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.togglePause.selector, + COLLATERAL_TO_ADD, + Storage.ActionType.Burn + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + } + + bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); + address multiSend = address(_chainToMultiSend(chainId)); + _serializeJson(chainId, multiSend, 0, payloadMultiSend, Enum.Operation.DelegateCall, hex""); + } +} From d5b18627490134506c0a02ceee9e7313c2ef61b8 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Tue, 8 Oct 2024 17:42:44 +0200 Subject: [PATCH 02/26] feat: add EURCV collateral --- .../foundry/transmuter/TransmuterAddCollateralEURCV.s.sol | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol index 536a788..c6df1c1 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol @@ -8,9 +8,8 @@ import { Enum } from "safe/Safe.sol"; import { MultiSend, Utils } from "../Utils.s.sol"; import "../Constants.s.sol"; -contract TransmuterRevokeAddCollateral is Utils { +contract TransmuterRevokeAddCollateralEURCV is Utils { address public constant COLLATERAL_TO_ADD = 0x5F7827FDeb7c20b443265Fc2F40845B715385Ff2; - address public RECEIVER = 0xA9DdD91249DFdd450E81E1c56Ab60E1A62651701; uint256 constant BPS = 1e14; bytes oracleConfigCollatToAdd; @@ -30,6 +29,9 @@ contract TransmuterRevokeAddCollateral is Utils { address to = address(transmuter); uint256 value = 0; + (uint64[] memory xFeeMint, int64[] memory yFeeMint) = transmuter.getCollateralMintFees(EUROC); + (uint64[] memory xFeeBurn, int64[] memory yFeeBurn) = transmuter.getCollateralBurnFees(EUROC); + // Add the new collateral { { From c2c20ba0f4471ad95be95be3a5472a1b4781f2f8 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Tue, 8 Oct 2024 17:57:59 +0200 Subject: [PATCH 03/26] tests: add EURCV collateral --- .../TransmuterAddCollateralEURCV.s.sol | 2 +- .../TransmuterAddCollateralEURCV.t.sol | 129 ++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 test/transmuter/TransmuterAddCollateralEURCV.t.sol diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol index c6df1c1..a9895a1 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol @@ -8,7 +8,7 @@ import { Enum } from "safe/Safe.sol"; import { MultiSend, Utils } from "../Utils.s.sol"; import "../Constants.s.sol"; -contract TransmuterRevokeAddCollateralEURCV is Utils { +contract TransmuterAddCollateralEURCV is Utils { address public constant COLLATERAL_TO_ADD = 0x5F7827FDeb7c20b443265Fc2F40845B715385Ff2; uint256 constant BPS = 1e14; diff --git a/test/transmuter/TransmuterAddCollateralEURCV.t.sol b/test/transmuter/TransmuterAddCollateralEURCV.t.sol new file mode 100644 index 0000000..14ab6d0 --- /dev/null +++ b/test/transmuter/TransmuterAddCollateralEURCV.t.sol @@ -0,0 +1,129 @@ +// 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 { MockSafe } from "../mock/MockSafe.sol"; +import { BaseTest } from "../BaseTest.t.sol"; +import "../../scripts/foundry/Constants.s.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import "transmuter/utils/Errors.sol" as Errors; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper, IGetters } from "transmuter/interfaces/ITransmuter.sol"; +import { MAX_MINT_FEE, MAX_BURN_FEE } from "transmuter/utils/Constants.sol"; +import { IERC20 } from "oz/token/ERC20/IERC20.sol"; + +contract TransmuterAddCollateralEURCVTest is BaseTest { + using stdJson for string; + + uint256 constant BPS = 1e14; + + ITransmuter public transmuter; + IAgToken public agToken; + address[] public collateralList; + + function setUp() public override { + super.setUp(); + } + + function testScript() external { + uint256 chainId = json.readUint("$.chainId"); + vm.selectFork(forkIdentifier[chainId]); + + // TODO + StablecoinType fiat = StablecoinType.EUR; + // TODO END + + address gnosisSafe = _chainToContract(chainId, ContractType.GovernorMultisig); + transmuter = ITransmuter(address(_getTransmuter(chainId, fiat))); + agToken = _getAgToken(chainId, fiat); + + address to = json.readAddress("$.to"); + // uint256 value = json.readUint("$.value"); + uint256 operation = json.readUint("$.operation"); + bytes memory payload = json.readBytes("$.data"); + + // Verify that the call will succeed + MockSafe mockSafe = new MockSafe(); + vm.etch(gnosisSafe, address(mockSafe).code); + vm.prank(gnosisSafe); + (bool success, ) = gnosisSafe.call(abi.encode(address(to), payload, operation, 1e7)); + if (!success) revert(); + + collateralList = transmuter.getCollateralList(); + assertEq(agToken.isMinter(address(transmuter)), true); + assertEq(collateralList.length, 4); + assertEq(collateralList[3], address(0x5F7827FDeb7c20b443265Fc2F40845B715385Ff2)); + + // Check parameters are correct for the new collateral + uint256 newCollateralIndex = 3; + address newCollateral = collateralList[newCollateralIndex]; + { + ( + Storage.OracleReadType oracleType, + Storage.OracleReadType targetType, + bytes memory oracleData, + bytes memory targetData, + bytes memory hyperparameters + ) = transmuter.getOracle(newCollateral); + assertEq(uint256(oracleType), uint256(Storage.OracleReadType.NO_ORACLE)); + assertEq(uint256(targetType), uint256(Storage.OracleReadType.STABLE)); + assertEq(oracleData.length, 0); + assertEq(targetData.length, 0); + assertEq(hyperparameters, abi.encode(uint128(0), uint128(50 * BPS))); + } + + { + (uint64[] memory xFeeMintExpected, int64[] memory yFeeMintExpected) = transmuter.getCollateralMintFees(EUROC); + (uint64[] memory xFeeBurnExpected, int64[] memory yFeeBurnExpected) = transmuter.getCollateralBurnFees(EUROC); + + (uint64[] memory xFeeMint, int64[] memory yFeeMint) = transmuter.getCollateralMintFees(newCollateral); + (uint64[] memory xFeeBurn, int64[] memory yFeeBurn) = transmuter.getCollateralBurnFees(newCollateral); + + assertEq(xFeeMint.length, xFeeMintExpected.length); + assertEq(yFeeMint.length, yFeeMintExpected.length); + assertEq(xFeeBurn.length, xFeeBurnExpected.length); + assertEq(yFeeBurn.length, yFeeBurnExpected.length); + + for (uint256 i = 0; i < xFeeMint.length; i++) { + assertEq(xFeeMint[i], xFeeMintExpected[i]); + assertEq(yFeeMint[i], yFeeMintExpected[i]); + } + for (uint256 i = 0; i < xFeeBurn.length; i++) { + assertEq(xFeeBurn[i], xFeeBurnExpected[i]); + assertEq(yFeeBurn[i], yFeeBurnExpected[i]); + } + } + + // Check storage new collat + { + Storage.Collateral memory collatInfo = transmuter.getCollateralInfo(newCollateral); + assertEq(collatInfo.isManaged, 0); + assertEq(collatInfo.isMintLive, 1); + assertEq(collatInfo.isBurnLive, 1); + assertEq(collatInfo.decimals, 18); + assertEq(collatInfo.onlyWhitelisted, 0); + assertEq(collatInfo.normalizedStables, 0); + assertEq(collatInfo.managerData.subCollaterals.length, 0); + assertEq(collatInfo.managerData.config.length, 0); + } + + // Test oracle values returned + { + (uint256 mint, uint256 burn, uint256 ratio, uint256 minRatio, uint256 redemption) = transmuter + .getOracleValues(newCollateral); + assertEq(mint, BASE_18); + assertEq(burn, BASE_18); + assertEq(ratio, BASE_18); + assertEq(redemption, BASE_18); + } + + // Check quotes are working on the added collateral + { + // we ca do some quoteIn and quoteOut + assertEq(BASE_18, transmuter.quoteOut(BASE_18, newCollateral, address(agToken))); + assertEq(BASE_18, transmuter.quoteIn(BASE_18, newCollateral, address(agToken))); + } + + transmuter.quoteRedemptionCurve(BASE_18); + } +} From 551b61f55b680c3bfe83ba9b8a0f02f80b700eef Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Fri, 11 Oct 2024 14:49:51 +0200 Subject: [PATCH 04/26] feat: XEVT oracle config --- lib/angle-transmuter | 2 +- .../TransmuterAddCollateralXEVT.s..sol | 30 +++++++++++++++---- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/angle-transmuter b/lib/angle-transmuter index 41d56b5..1c417c4 160000 --- a/lib/angle-transmuter +++ b/lib/angle-transmuter @@ -1 +1 @@ -Subproject commit 41d56b5fad0fc1582249c22e14a7206a84fa471c +Subproject commit 1c417c47b0cecdfc07fd8175b71c20c3524ac593 diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol index 536a788..350faed 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol @@ -8,9 +8,8 @@ import { Enum } from "safe/Safe.sol"; import { MultiSend, Utils } from "../Utils.s.sol"; import "../Constants.s.sol"; -contract TransmuterRevokeAddCollateral is Utils { - address public constant COLLATERAL_TO_ADD = 0x5F7827FDeb7c20b443265Fc2F40845B715385Ff2; - address public RECEIVER = 0xA9DdD91249DFdd450E81E1c56Ab60E1A62651701; +contract TransmuterAddCollateralEURCV is Utils { + address public constant COLLATERAL_TO_ADD = 0x3Ee320c9F73a84D1717557af00695A34b26d1F1d; uint256 constant BPS = 1e14; bytes oracleConfigCollatToAdd; @@ -30,17 +29,36 @@ contract TransmuterRevokeAddCollateral is Utils { address to = address(transmuter); uint256 value = 0; + uint64[] memory xFeeBurn = new uint64[](3); + uint64[] memory xFeeMint = new uint64[](3); + int64[] memory yFeeMint = new int64[](xFeeMint.length); + int64[] memory yFeeBurn = new int64[](xFeeBurn.length); + xFeeMint[0] = 0; + xFeeMint[1] = 190000000; + xFeeMint[2] = 200000000; + xFeeBurn[0] = 1000000000; + xFeeBurn[1] = 60000000; + xFeeBurn[2] = 50000000; + + yFeeBurn[0] = 5000000; + yFeeBurn[1] = 5000000; + yFeeBurn[2] = 999000000; + yFeeMint[0] = 0; + yFeeMint[1] = 0; + yFeeMint[2] = 999999999999; + // Add the new collateral { { + address oracle; + uint256 normalizationFactor; bytes memory readData; - bytes memory targetData; + bytes memory targetData = abi.encode(oracle, normalizationFactor); oracleConfigCollatToAdd = abi.encode( Storage.OracleReadType.NO_ORACLE, - Storage.OracleReadType.STABLE, + Storage.OracleReadType.MORPHO_ORACLE, readData, targetData, - // With no oracle the below oracles are useless abi.encode(uint128(0), uint128(50 * BPS)) ); } From f7c5736d67fba55a9440b799a52835fd50a4ab45 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Mon, 14 Oct 2024 11:46:18 +0200 Subject: [PATCH 05/26] refactor: fees use base9 --- .../TransmuterAddCollateralXEVT.s..sol | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol index 350faed..506b0c4 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol @@ -34,24 +34,24 @@ contract TransmuterAddCollateralEURCV is Utils { int64[] memory yFeeMint = new int64[](xFeeMint.length); int64[] memory yFeeBurn = new int64[](xFeeBurn.length); xFeeMint[0] = 0; - xFeeMint[1] = 190000000; - xFeeMint[2] = 200000000; - xFeeBurn[0] = 1000000000; - xFeeBurn[1] = 60000000; - xFeeBurn[2] = 50000000; + xFeeMint[1] = 0.19e9; + xFeeMint[2] = 0.20e9; + xFeeBurn[0] = 1e9; + xFeeBurn[1] = 0.06e9; + xFeeBurn[2] = 0.05e9; - yFeeBurn[0] = 5000000; - yFeeBurn[1] = 5000000; - yFeeBurn[2] = 999000000; + yFeeBurn[0] = 0.005e9; + yFeeBurn[1] = 0.005e9; + yFeeBurn[2] = 0.999e9; yFeeMint[0] = 0; yFeeMint[1] = 0; - yFeeMint[2] = 999999999999; + yFeeMint[2] = 100e9 - 1; // Add the new collateral { { - address oracle; - uint256 normalizationFactor; + address oracle; // TODO: Set the oracle address + uint256 normalizationFactor; // TODO: Set the normalization factor bytes memory readData; bytes memory targetData = abi.encode(oracle, normalizationFactor); oracleConfigCollatToAdd = abi.encode( From 26806277ad16b3a4961fafa974f4c965628fc840 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Mon, 14 Oct 2024 12:02:25 +0200 Subject: [PATCH 06/26] feat: update fees on mint and burn for EURCV --- .../transmuter/TransmuterAddCollateralEURCV.s.sol | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol index a9895a1..14bbe1a 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol @@ -29,8 +29,19 @@ contract TransmuterAddCollateralEURCV is Utils { address to = address(transmuter); uint256 value = 0; - (uint64[] memory xFeeMint, int64[] memory yFeeMint) = transmuter.getCollateralMintFees(EUROC); - (uint64[] memory xFeeBurn, int64[] memory yFeeBurn) = transmuter.getCollateralBurnFees(EUROC); + uint64[] memory xFeeBurn = new uint64[](1); + uint64[] memory xFeeMint = new uint64[](3); + int64[] memory yFeeMint = new int64[](xFeeMint.length); + int64[] memory yFeeBurn = new int64[](xFeeBurn.length); + xFeeMint[0] = 0; + xFeeMint[1] = 0.29e9; + xFeeMint[2] = 0.30e9; + xFeeBurn[0] = 1e9; + + yFeeBurn[0] = -0.0001e9; + yFeeMint[0] = 0; + yFeeMint[1] = 0; + yFeeMint[2] = 0; // Add the new collateral { From f23faf894a01b0a5f3fdfac127aa886b98571aee Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Mon, 14 Oct 2024 12:22:04 +0200 Subject: [PATCH 07/26] feat: positive fee when burning and max exposure for EURCV --- .../TransmuterAddCollateralEURCV.s.sol | 4 +-- .../TransmuterAddCollateralEURCV.t.sol | 30 +++++++++---------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol index 14bbe1a..499a12b 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol @@ -38,10 +38,10 @@ contract TransmuterAddCollateralEURCV is Utils { xFeeMint[2] = 0.30e9; xFeeBurn[0] = 1e9; - yFeeBurn[0] = -0.0001e9; + yFeeBurn[0] = 0.9995e9; yFeeMint[0] = 0; yFeeMint[1] = 0; - yFeeMint[2] = 0; + yFeeMint[2] = 100e9 - 1; // Add the new collateral { diff --git a/test/transmuter/TransmuterAddCollateralEURCV.t.sol b/test/transmuter/TransmuterAddCollateralEURCV.t.sol index 14ab6d0..ff0775a 100644 --- a/test/transmuter/TransmuterAddCollateralEURCV.t.sol +++ b/test/transmuter/TransmuterAddCollateralEURCV.t.sol @@ -73,25 +73,23 @@ contract TransmuterAddCollateralEURCVTest is BaseTest { } { - (uint64[] memory xFeeMintExpected, int64[] memory yFeeMintExpected) = transmuter.getCollateralMintFees(EUROC); - (uint64[] memory xFeeBurnExpected, int64[] memory yFeeBurnExpected) = transmuter.getCollateralBurnFees(EUROC); - (uint64[] memory xFeeMint, int64[] memory yFeeMint) = transmuter.getCollateralMintFees(newCollateral); (uint64[] memory xFeeBurn, int64[] memory yFeeBurn) = transmuter.getCollateralBurnFees(newCollateral); - assertEq(xFeeMint.length, xFeeMintExpected.length); - assertEq(yFeeMint.length, yFeeMintExpected.length); - assertEq(xFeeBurn.length, xFeeBurnExpected.length); - assertEq(yFeeBurn.length, yFeeBurnExpected.length); - - for (uint256 i = 0; i < xFeeMint.length; i++) { - assertEq(xFeeMint[i], xFeeMintExpected[i]); - assertEq(yFeeMint[i], yFeeMintExpected[i]); - } - for (uint256 i = 0; i < xFeeBurn.length; i++) { - assertEq(xFeeBurn[i], xFeeBurnExpected[i]); - assertEq(yFeeBurn[i], yFeeBurnExpected[i]); - } + assertEq(xFeeMint.length, 3); + assertEq(yFeeMint.length, 3); + assertEq(xFeeBurn.length, 1); + assertEq(yFeeBurn.length, 1); + + assertEq(xFeeMint[0], 0); + assertEq(xFeeMint[1], 0.29e9); + assertEq(xFeeMint[2], 0.30e9); + assertEq(xFeeBurn[0], 1e9); + + assertEq(yFeeBurn[0], 0.9995e9); + assertEq(yFeeMint[0], 0); + assertEq(yFeeMint[1], 0); + assertEq(yFeeMint[2], 100e9 - 1); } // Check storage new collat From d219505afcab7e920f445479a4739171da45088b Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Mon, 14 Oct 2024 12:30:19 +0200 Subject: [PATCH 08/26] tests: XEVT --- .../TransmuterAddCollateralXEVT.s..sol | 2 +- .../TransmuterAddCollateralXEVT.t.sol | 131 ++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 test/transmuter/TransmuterAddCollateralXEVT.t.sol diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol index 506b0c4..90b495a 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol @@ -8,7 +8,7 @@ import { Enum } from "safe/Safe.sol"; import { MultiSend, Utils } from "../Utils.s.sol"; import "../Constants.s.sol"; -contract TransmuterAddCollateralEURCV is Utils { +contract TransmuterAddCollateralXEVT is Utils { address public constant COLLATERAL_TO_ADD = 0x3Ee320c9F73a84D1717557af00695A34b26d1F1d; uint256 constant BPS = 1e14; diff --git a/test/transmuter/TransmuterAddCollateralXEVT.t.sol b/test/transmuter/TransmuterAddCollateralXEVT.t.sol new file mode 100644 index 0000000..00385e2 --- /dev/null +++ b/test/transmuter/TransmuterAddCollateralXEVT.t.sol @@ -0,0 +1,131 @@ +// 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 { MockSafe } from "../mock/MockSafe.sol"; +import { BaseTest } from "../BaseTest.t.sol"; +import "../../scripts/foundry/Constants.s.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import "transmuter/utils/Errors.sol" as Errors; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper, IGetters } from "transmuter/interfaces/ITransmuter.sol"; +import { MAX_MINT_FEE, MAX_BURN_FEE } from "transmuter/utils/Constants.sol"; +import { IERC20 } from "oz/token/ERC20/IERC20.sol"; + +contract TransmuterAddCollateralXEVTTest is BaseTest { + using stdJson for string; + + uint256 constant BPS = 1e14; + + ITransmuter public transmuter; + IAgToken public agToken; + address[] public collateralList; + + function setUp() public override { + super.setUp(); + } + + function testScript() external { + uint256 chainId = json.readUint("$.chainId"); + vm.selectFork(forkIdentifier[chainId]); + + // TODO + StablecoinType fiat = StablecoinType.EUR; + // TODO END + + address gnosisSafe = _chainToContract(chainId, ContractType.GovernorMultisig); + transmuter = ITransmuter(address(_getTransmuter(chainId, fiat))); + agToken = _getAgToken(chainId, fiat); + + address to = json.readAddress("$.to"); + // uint256 value = json.readUint("$.value"); + uint256 operation = json.readUint("$.operation"); + bytes memory payload = json.readBytes("$.data"); + + // Verify that the call will succeed + MockSafe mockSafe = new MockSafe(); + vm.etch(gnosisSafe, address(mockSafe).code); + vm.prank(gnosisSafe); + (bool success, ) = gnosisSafe.call(abi.encode(address(to), payload, operation, 1e7)); + if (!success) revert(); + + collateralList = transmuter.getCollateralList(); + assertEq(agToken.isMinter(address(transmuter)), true); + assertEq(collateralList.length, 4); + assertEq(collateralList[3], address(0x3Ee320c9F73a84D1717557af00695A34b26d1F1d)); + + // Check parameters are correct for the new collateral + uint256 newCollateralIndex = 3; + address newCollateral = collateralList[newCollateralIndex]; + { + ( + Storage.OracleReadType oracleType, + Storage.OracleReadType targetType, + bytes memory oracleData, + bytes memory targetData, + bytes memory hyperparameters + ) = transmuter.getOracle(newCollateral); + assertEq(uint256(oracleType), uint256(Storage.OracleReadType.NO_ORACLE)); + assertEq(uint256(targetType), uint256(Storage.OracleReadType.STABLE)); + assertEq(oracleData.length, 0); + assertEq(targetData.length, 0); + assertEq(hyperparameters, abi.encode(uint128(0), uint128(50 * BPS))); + } + + { + (uint64[] memory xFeeMint, int64[] memory yFeeMint) = transmuter.getCollateralMintFees(newCollateral); + (uint64[] memory xFeeBurn, int64[] memory yFeeBurn) = transmuter.getCollateralBurnFees(newCollateral); + + assertEq(xFeeMint.length, 3); + assertEq(yFeeMint.length, 3); + assertEq(xFeeBurn.length, 3); + assertEq(yFeeBurn.length, 3); + + assertEq(xFeeMint[0], 0); + assertEq(xFeeMint[1], 0.19e9); + assertEq(xFeeMint[2], 0.20e9); + assertEq(xFeeBurn[0], 1e9); + assertEq(xFeeBurn[1], 0.06e9); + assertEq(xFeeBurn[2], 0.05e9); + + assertEq(yFeeBurn[0], 0.005e9); + assertEq(yFeeBurn[1], 0.005e9); + assertEq(yFeeBurn[2], 0.999e9); + assertEq(yFeeMint[0], 0); + assertEq(yFeeMint[1], 0); + assertEq(yFeeMint[2], 100e9 - 1); + } + + // Check storage new collat + { + Storage.Collateral memory collatInfo = transmuter.getCollateralInfo(newCollateral); + assertEq(collatInfo.isManaged, 0); + assertEq(collatInfo.isMintLive, 1); + assertEq(collatInfo.isBurnLive, 1); + assertEq(collatInfo.decimals, 18); + assertEq(collatInfo.onlyWhitelisted, 0); + assertEq(collatInfo.normalizedStables, 0); + assertEq(collatInfo.managerData.subCollaterals.length, 0); + assertEq(collatInfo.managerData.config.length, 0); + } + + // Test oracle values returned + { + (uint256 mint, uint256 burn, uint256 ratio, uint256 minRatio, uint256 redemption) = transmuter + .getOracleValues(newCollateral); + // assertEq(mint, BASE_18); + // assertEq(burn, BASE_18); + // assertEq(ratio, BASE_18); + // assertEq(redemption, BASE_18); + } + + // Check quotes are working on the added collateral + { + // we ca do some quoteIn and quoteOut + transmuter.quoteOut(BASE_18, newCollateral, address(agToken); + transmuter.quoteIn(BASE_18, newCollateral, address(agToken))); + } + + transmuter.quoteRedemptionCurve(BASE_18); + } +} From d83751341f1258035d5ce3c1d5d09504f17719d5 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Mon, 14 Oct 2024 16:23:28 +0200 Subject: [PATCH 09/26] doc: add explanation for positive burning fee --- scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol index 499a12b..94d4811 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol @@ -38,7 +38,7 @@ contract TransmuterAddCollateralEURCV is Utils { xFeeMint[2] = 0.30e9; xFeeBurn[0] = 1e9; - yFeeBurn[0] = 0.9995e9; + yFeeBurn[0] = 0.9995e9; // 5BPS positive burning fee as we get rev share from it yFeeMint[0] = 0; yFeeMint[1] = 0; yFeeMint[2] = 100e9 - 1; From 115cf43a1e6f2d53bcbe304e591f18a98bc928c3 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Tue, 15 Oct 2024 00:23:13 +0200 Subject: [PATCH 10/26] feat: oracle and normalization for XEVT --- scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol index 90b495a..0bd4519 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol @@ -50,8 +50,8 @@ contract TransmuterAddCollateralXEVT is Utils { // Add the new collateral { { - address oracle; // TODO: Set the oracle address - uint256 normalizationFactor; // TODO: Set the normalization factor + address oracle = 0x6B102047A4bB943DE39233E44487F2d57bDCb33e; + uint256 normalizationFactor = 18; bytes memory readData; bytes memory targetData = abi.encode(oracle, normalizationFactor); oracleConfigCollatToAdd = abi.encode( From 8eac5a45534dfbe77608361d56222cf39558d88e Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Tue, 15 Oct 2024 09:51:22 +0200 Subject: [PATCH 11/26] doc: add explanation for normalizationFactor --- scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol index 0bd4519..0170e95 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol @@ -51,7 +51,7 @@ contract TransmuterAddCollateralXEVT is Utils { { { address oracle = 0x6B102047A4bB943DE39233E44487F2d57bDCb33e; - uint256 normalizationFactor = 18; + uint256 normalizationFactor = 18; // price == 36 decimals bytes memory readData; bytes memory targetData = abi.encode(oracle, normalizationFactor); oracleConfigCollatToAdd = abi.encode( From 2b06a543112fd12f4aa325d23d913b7b3b9b5c8d Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Tue, 15 Oct 2024 12:23:08 +0200 Subject: [PATCH 12/26] tests: finalize XEVT integration --- .../TransmuterAddCollateralXEVT.s..sol | 2 +- .../TransmuterAddCollateralXEVT.t.sol | 20 ++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol index 0170e95..407d788 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol @@ -51,7 +51,7 @@ contract TransmuterAddCollateralXEVT is Utils { { { address oracle = 0x6B102047A4bB943DE39233E44487F2d57bDCb33e; - uint256 normalizationFactor = 18; // price == 36 decimals + uint256 normalizationFactor = 1e18; // price == 36 decimals bytes memory readData; bytes memory targetData = abi.encode(oracle, normalizationFactor); oracleConfigCollatToAdd = abi.encode( diff --git a/test/transmuter/TransmuterAddCollateralXEVT.t.sol b/test/transmuter/TransmuterAddCollateralXEVT.t.sol index 00385e2..47a8a5f 100644 --- a/test/transmuter/TransmuterAddCollateralXEVT.t.sol +++ b/test/transmuter/TransmuterAddCollateralXEVT.t.sol @@ -11,6 +11,7 @@ import "transmuter/utils/Errors.sol" as Errors; import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper, IGetters } from "transmuter/interfaces/ITransmuter.sol"; import { MAX_MINT_FEE, MAX_BURN_FEE } from "transmuter/utils/Constants.sol"; import { IERC20 } from "oz/token/ERC20/IERC20.sol"; +import { IERC4626 } from "oz/token/ERC20/extensions/ERC4626.sol"; contract TransmuterAddCollateralXEVTTest is BaseTest { using stdJson for string; @@ -66,9 +67,9 @@ contract TransmuterAddCollateralXEVTTest is BaseTest { bytes memory hyperparameters ) = transmuter.getOracle(newCollateral); assertEq(uint256(oracleType), uint256(Storage.OracleReadType.NO_ORACLE)); - assertEq(uint256(targetType), uint256(Storage.OracleReadType.STABLE)); + assertEq(uint256(targetType), uint256(Storage.OracleReadType.MORPHO_ORACLE)); assertEq(oracleData.length, 0); - assertEq(targetData.length, 0); + assertNotEq(targetData.length, 0); assertEq(hyperparameters, abi.encode(uint128(0), uint128(50 * BPS))); } @@ -102,7 +103,7 @@ contract TransmuterAddCollateralXEVTTest is BaseTest { assertEq(collatInfo.isManaged, 0); assertEq(collatInfo.isMintLive, 1); assertEq(collatInfo.isBurnLive, 1); - assertEq(collatInfo.decimals, 18); + assertEq(collatInfo.decimals, 6); assertEq(collatInfo.onlyWhitelisted, 0); assertEq(collatInfo.normalizedStables, 0); assertEq(collatInfo.managerData.subCollaterals.length, 0); @@ -110,20 +111,21 @@ contract TransmuterAddCollateralXEVTTest is BaseTest { } // Test oracle values returned + uint256 value = IERC4626(newCollateral).convertToAssets(1e6) * 1e12; { (uint256 mint, uint256 burn, uint256 ratio, uint256 minRatio, uint256 redemption) = transmuter .getOracleValues(newCollateral); - // assertEq(mint, BASE_18); - // assertEq(burn, BASE_18); - // assertEq(ratio, BASE_18); - // assertEq(redemption, BASE_18); + assertEq(mint, value); + assertEq(burn, value); + assertEq(ratio, BASE_18); + assertEq(redemption, value); } // Check quotes are working on the added collateral { // we ca do some quoteIn and quoteOut - transmuter.quoteOut(BASE_18, newCollateral, address(agToken); - transmuter.quoteIn(BASE_18, newCollateral, address(agToken))); + transmuter.quoteOut(value, newCollateral, address(agToken)); + transmuter.quoteIn(value, newCollateral, address(agToken)); } transmuter.quoteRedemptionCurve(BASE_18); From c4a1ece5a24a671e97d11f7e0b19334e3dba3071 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Tue, 15 Oct 2024 17:33:12 +0200 Subject: [PATCH 13/26] feat: correct fees when bruning EURCV --- .../foundry/transmuter/TransmuterAddCollateralEURCV.s.sol | 5 ++--- .../foundry/transmuter/TransmuterAddCollateralXEVT.s..sol | 3 +-- test/transmuter/TransmuterAddCollateralEURCV.t.sol | 6 ++---- test/transmuter/TransmuterAddCollateralXEVT.t.sol | 4 +--- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol index 94d4811..e4639e2 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol @@ -10,7 +10,6 @@ import "../Constants.s.sol"; contract TransmuterAddCollateralEURCV is Utils { address public constant COLLATERAL_TO_ADD = 0x5F7827FDeb7c20b443265Fc2F40845B715385Ff2; - uint256 constant BPS = 1e14; bytes oracleConfigCollatToAdd; uint64[] public xFeeMint; @@ -38,7 +37,7 @@ contract TransmuterAddCollateralEURCV is Utils { xFeeMint[2] = 0.30e9; xFeeBurn[0] = 1e9; - yFeeBurn[0] = 0.9995e9; // 5BPS positive burning fee as we get rev share from it + yFeeBurn[0] = 0.0005e9; yFeeMint[0] = 0; yFeeMint[1] = 0; yFeeMint[2] = 100e9 - 1; @@ -54,7 +53,7 @@ contract TransmuterAddCollateralEURCV is Utils { readData, targetData, // With no oracle the below oracles are useless - abi.encode(uint128(0), uint128(50 * BPS)) + abi.encode(uint128(0), uint128(0)) ); } { diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol index 407d788..23c6fa6 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol @@ -10,7 +10,6 @@ import "../Constants.s.sol"; contract TransmuterAddCollateralXEVT is Utils { address public constant COLLATERAL_TO_ADD = 0x3Ee320c9F73a84D1717557af00695A34b26d1F1d; - uint256 constant BPS = 1e14; bytes oracleConfigCollatToAdd; uint64[] public xFeeMint; @@ -59,7 +58,7 @@ contract TransmuterAddCollateralXEVT is Utils { Storage.OracleReadType.MORPHO_ORACLE, readData, targetData, - abi.encode(uint128(0), uint128(50 * BPS)) + abi.encode(uint128(0), uint128(0)) ); } { diff --git a/test/transmuter/TransmuterAddCollateralEURCV.t.sol b/test/transmuter/TransmuterAddCollateralEURCV.t.sol index ff0775a..d7ea078 100644 --- a/test/transmuter/TransmuterAddCollateralEURCV.t.sol +++ b/test/transmuter/TransmuterAddCollateralEURCV.t.sol @@ -15,8 +15,6 @@ import { IERC20 } from "oz/token/ERC20/IERC20.sol"; contract TransmuterAddCollateralEURCVTest is BaseTest { using stdJson for string; - uint256 constant BPS = 1e14; - ITransmuter public transmuter; IAgToken public agToken; address[] public collateralList; @@ -69,7 +67,7 @@ contract TransmuterAddCollateralEURCVTest is BaseTest { assertEq(uint256(targetType), uint256(Storage.OracleReadType.STABLE)); assertEq(oracleData.length, 0); assertEq(targetData.length, 0); - assertEq(hyperparameters, abi.encode(uint128(0), uint128(50 * BPS))); + assertEq(hyperparameters, abi.encode(uint128(0), uint128(0))); } { @@ -86,7 +84,7 @@ contract TransmuterAddCollateralEURCVTest is BaseTest { assertEq(xFeeMint[2], 0.30e9); assertEq(xFeeBurn[0], 1e9); - assertEq(yFeeBurn[0], 0.9995e9); + assertEq(yFeeBurn[0], 0.0005e9); assertEq(yFeeMint[0], 0); assertEq(yFeeMint[1], 0); assertEq(yFeeMint[2], 100e9 - 1); diff --git a/test/transmuter/TransmuterAddCollateralXEVT.t.sol b/test/transmuter/TransmuterAddCollateralXEVT.t.sol index 47a8a5f..8d16df5 100644 --- a/test/transmuter/TransmuterAddCollateralXEVT.t.sol +++ b/test/transmuter/TransmuterAddCollateralXEVT.t.sol @@ -16,8 +16,6 @@ import { IERC4626 } from "oz/token/ERC20/extensions/ERC4626.sol"; contract TransmuterAddCollateralXEVTTest is BaseTest { using stdJson for string; - uint256 constant BPS = 1e14; - ITransmuter public transmuter; IAgToken public agToken; address[] public collateralList; @@ -70,7 +68,7 @@ contract TransmuterAddCollateralXEVTTest is BaseTest { assertEq(uint256(targetType), uint256(Storage.OracleReadType.MORPHO_ORACLE)); assertEq(oracleData.length, 0); assertNotEq(targetData.length, 0); - assertEq(hyperparameters, abi.encode(uint128(0), uint128(50 * BPS))); + assertEq(hyperparameters, abi.encode(uint128(0), uint128(0))); } { From 0cb4845281844e65a65f6243041b5fd1d7042ed2 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Tue, 22 Oct 2024 18:16:49 +0200 Subject: [PATCH 14/26] feat: add safe to add collaterals scripts --- .../TransmuterAddCollateralEURCV.s.sol | 27 +++++++++---------- .../TransmuterAddCollateralXEVT.s..sol | 10 +++---- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol index e4639e2..2bfc45a 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralEURCV.s.sol @@ -21,29 +21,29 @@ contract TransmuterAddCollateralEURCV is Utils { function run() external { uint256 chainId = vm.envUint("CHAIN_ID"); + address safe = _chainToContract(chainId, ContractType.GovernorMultisig); ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); agToken = address(transmuter.agToken()); bytes memory transactions; - uint8 isDelegateCall = 0; - address to = address(transmuter); - uint256 value = 0; uint64[] memory xFeeBurn = new uint64[](1); uint64[] memory xFeeMint = new uint64[](3); int64[] memory yFeeMint = new int64[](xFeeMint.length); int64[] memory yFeeBurn = new int64[](xFeeBurn.length); + xFeeBurn[0] = 1e9; + yFeeBurn[0] = 0.0005e9; + xFeeMint[0] = 0; xFeeMint[1] = 0.29e9; xFeeMint[2] = 0.30e9; - xFeeBurn[0] = 1e9; - - yFeeBurn[0] = 0.0005e9; yFeeMint[0] = 0; yFeeMint[1] = 0; yFeeMint[2] = 100e9 - 1; // Add the new collateral { + address to = address(transmuter); + uint8 isDelegateCall = 0; { bytes memory readData; bytes memory targetData; @@ -59,7 +59,7 @@ contract TransmuterAddCollateralEURCV is Utils { { bytes memory data = abi.encodeWithSelector(ISettersGovernor.addCollateral.selector, COLLATERAL_TO_ADD); uint256 dataLength = data.length; - bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); transactions = abi.encodePacked(transactions, internalTx); } { @@ -72,7 +72,7 @@ contract TransmuterAddCollateralEURCV is Utils { true ); uint256 dataLength = data.length; - bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); transactions = abi.encodePacked(transactions, internalTx); } { @@ -85,7 +85,7 @@ contract TransmuterAddCollateralEURCV is Utils { false ); uint256 dataLength = data.length; - bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); transactions = abi.encodePacked(transactions, internalTx); } { @@ -95,7 +95,7 @@ contract TransmuterAddCollateralEURCV is Utils { oracleConfigCollatToAdd ); uint256 dataLength = data.length; - bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); transactions = abi.encodePacked(transactions, internalTx); } { @@ -105,7 +105,7 @@ contract TransmuterAddCollateralEURCV is Utils { Storage.ActionType.Mint ); uint256 dataLength = data.length; - bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); transactions = abi.encodePacked(transactions, internalTx); } { @@ -115,13 +115,12 @@ contract TransmuterAddCollateralEURCV is Utils { Storage.ActionType.Burn ); uint256 dataLength = data.length; - bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); transactions = abi.encodePacked(transactions, internalTx); } } bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); - address multiSend = address(_chainToMultiSend(chainId)); - _serializeJson(chainId, multiSend, 0, payloadMultiSend, Enum.Operation.DelegateCall, hex""); + _serializeJson(chainId, address(_chainToMultiSend(chainId)), uint256(0), payloadMultiSend, Enum.Operation.DelegateCall, hex"", safe); } } diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol index 23c6fa6..7ab647f 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol @@ -32,16 +32,16 @@ contract TransmuterAddCollateralXEVT is Utils { uint64[] memory xFeeMint = new uint64[](3); int64[] memory yFeeMint = new int64[](xFeeMint.length); int64[] memory yFeeBurn = new int64[](xFeeBurn.length); - xFeeMint[0] = 0; - xFeeMint[1] = 0.19e9; - xFeeMint[2] = 0.20e9; xFeeBurn[0] = 1e9; xFeeBurn[1] = 0.06e9; xFeeBurn[2] = 0.05e9; - yFeeBurn[0] = 0.005e9; yFeeBurn[1] = 0.005e9; yFeeBurn[2] = 0.999e9; + + xFeeMint[0] = 0; + xFeeMint[1] = 0.19e9; + xFeeMint[2] = 0.20e9; yFeeMint[0] = 0; yFeeMint[1] = 0; yFeeMint[2] = 100e9 - 1; @@ -127,6 +127,6 @@ contract TransmuterAddCollateralXEVT is Utils { bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); address multiSend = address(_chainToMultiSend(chainId)); - _serializeJson(chainId, multiSend, 0, payloadMultiSend, Enum.Operation.DelegateCall, hex""); + _serializeJson(chainId, multiSend, 0, payloadMultiSend, Enum.Operation.DelegateCall, hex"", _chainToContract(chainId, ContractType.GovernorMultisig)); } } From 98708121ead7366ad6d049e2281d96da667b4b63 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Fri, 8 Nov 2024 13:02:09 +0100 Subject: [PATCH 15/26] feat: add MW_EURC collateral --- scripts/foundry/router/UpgradeRouter.s.sol | 4 +- .../TransmuterAddCollateralMW_EURC.s.sol | 132 ++++++++++++++++++ .../TransmuterAddCollateralMW_EURC.t.sol | 131 +++++++++++++++++ 3 files changed, 265 insertions(+), 2 deletions(-) create mode 100644 scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol create mode 100644 test/transmuter/TransmuterAddCollateralMW_EURC.t.sol diff --git a/scripts/foundry/router/UpgradeRouter.s.sol b/scripts/foundry/router/UpgradeRouter.s.sol index 0bcc24f..5858e2e 100644 --- a/scripts/foundry/router/UpgradeRouter.s.sol +++ b/scripts/foundry/router/UpgradeRouter.s.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.19; -import {TransparentUpgradeableProxy} from "oz/proxy/transparent/TransparentUpgradeableProxy.sol"; +import {ITransparentUpgradeableProxy} from "oz/proxy/transparent/TransparentUpgradeableProxy.sol"; import { MultiSend, Utils } from "../Utils.s.sol"; import { Enum } from "safe/Safe.sol"; import "../Constants.s.sol"; @@ -21,7 +21,7 @@ contract UpgradeRouter is Utils { if (chainId == CHAIN_LINEA) { { - bytes memory data = abi.encodeWithSelector(TransparentUpgradeableProxy.upgradeTo.selector, routerImpl); + bytes memory data = abi.encodeWithSelector(ITransparentUpgradeableProxy.upgradeTo.selector, routerImpl); address to = router; bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, data.length, data); transactions = abi.encodePacked(transactions, internalTx); diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol new file mode 100644 index 0000000..67ecc89 --- /dev/null +++ b/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +import { console } from "forge-std/console.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper } from "transmuter/interfaces/ITransmuter.sol"; +import { Enum } from "safe/Safe.sol"; +import { MultiSend, Utils } from "../Utils.s.sol"; +import "../Constants.s.sol"; + +contract TransmuterAddCollateralMW_EURC is Utils { + address public constant COLLATERAL_TO_ADD = 0xf24608E0CCb972b0b0f4A6446a0BBf58c701a026; + + bytes oracleConfigCollatToAdd; + uint64[] public xFeeMint; + int64[] public yFeeMint; + uint64[] public xFeeBurn; + int64[] public yFeeBurn; + address public agToken; + + function run() external { + uint256 chainId = vm.envUint("CHAIN_ID"); + + ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + agToken = address(transmuter.agToken()); + bytes memory transactions; + uint8 isDelegateCall = 0; + address to = address(transmuter); + uint256 value = 0; + + uint64[] memory xFeeBurn = new uint64[](3); + uint64[] memory xFeeMint = new uint64[](3); + int64[] memory yFeeMint = new int64[](xFeeMint.length); + int64[] memory yFeeBurn = new int64[](xFeeBurn.length); + xFeeBurn[0] = 1e9; + xFeeBurn[1] = 0.31e9; + xFeeBurn[2] = 0.30e9; + yFeeBurn[0] = 0.005e9; + yFeeBurn[1] = 0.005e9; + yFeeBurn[2] = 0.999e9; + + xFeeMint[0] = 0; + xFeeMint[1] = 0.79e9; + xFeeMint[2] = 0.80e9; + yFeeMint[0] = 0.0005e9; + yFeeMint[1] = 0.0005e9; + yFeeMint[2] = 100e9 - 1; + + // Add the new collateral + { + { + address oracle = 0x6B102047A4bB943DE39233E44487F2d57bDCb33e; // TODO + uint256 normalizationFactor = 1e18; // TODO + bytes memory readData; + bytes memory targetData = abi.encode(oracle, normalizationFactor); + oracleConfigCollatToAdd = abi.encode( + Storage.OracleReadType.NO_ORACLE, + Storage.OracleReadType.MORPHO_ORACLE, + readData, + targetData, + abi.encode(uint128(0), uint128(0)) + ); + } + { + bytes memory data = abi.encodeWithSelector(ISettersGovernor.addCollateral.selector, COLLATERAL_TO_ADD); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + // Mint fees + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.setFees.selector, + COLLATERAL_TO_ADD, + xFeeMint, + yFeeMint, + true + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + // Burn fees + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.setFees.selector, + COLLATERAL_TO_ADD, + xFeeBurn, + yFeeBurn, + false + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + bytes memory data = abi.encodeWithSelector( + ISettersGovernor.setOracle.selector, + COLLATERAL_TO_ADD, + oracleConfigCollatToAdd + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.togglePause.selector, + COLLATERAL_TO_ADD, + Storage.ActionType.Mint + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.togglePause.selector, + COLLATERAL_TO_ADD, + Storage.ActionType.Burn + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + } + + bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); + address multiSend = address(_chainToMultiSend(chainId)); + _serializeJson(chainId, multiSend, 0, payloadMultiSend, Enum.Operation.DelegateCall, hex"", _chainToContract(chainId, ContractType.GovernorMultisig)); + } +} diff --git a/test/transmuter/TransmuterAddCollateralMW_EURC.t.sol b/test/transmuter/TransmuterAddCollateralMW_EURC.t.sol new file mode 100644 index 0000000..4b51549 --- /dev/null +++ b/test/transmuter/TransmuterAddCollateralMW_EURC.t.sol @@ -0,0 +1,131 @@ +// 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 { MockSafe } from "../mock/MockSafe.sol"; +import { BaseTest } from "../BaseTest.t.sol"; +import "../../scripts/foundry/Constants.s.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import "transmuter/utils/Errors.sol" as Errors; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper, IGetters } from "transmuter/interfaces/ITransmuter.sol"; +import { MAX_MINT_FEE, MAX_BURN_FEE } from "transmuter/utils/Constants.sol"; +import { IERC20 } from "oz/token/ERC20/IERC20.sol"; +import { IERC4626 } from "oz/token/ERC20/extensions/ERC4626.sol"; + +contract TransmuterAddCollateralXEVTTest is BaseTest { + using stdJson for string; + + ITransmuter public transmuter; + IAgToken public agToken; + address[] public collateralList; + + function setUp() public override { + super.setUp(); + } + + function testScript() external { + uint256 chainId = json.readUint("$.chainId"); + vm.selectFork(forkIdentifier[chainId]); + + // TODO + StablecoinType fiat = StablecoinType.EUR; + // TODO END + + address gnosisSafe = _chainToContract(chainId, ContractType.GovernorMultisig); + transmuter = ITransmuter(address(_getTransmuter(chainId, fiat))); + agToken = _getAgToken(chainId, fiat); + + address to = json.readAddress("$.to"); + // uint256 value = json.readUint("$.value"); + uint256 operation = json.readUint("$.operation"); + bytes memory payload = json.readBytes("$.data"); + + // Verify that the call will succeed + MockSafe mockSafe = new MockSafe(); + vm.etch(gnosisSafe, address(mockSafe).code); + vm.prank(gnosisSafe); + (bool success, ) = gnosisSafe.call(abi.encode(address(to), payload, operation, 1e7)); + if (!success) revert(); + + collateralList = transmuter.getCollateralList(); + assertEq(agToken.isMinter(address(transmuter)), true); + assertEq(collateralList.length, 2); + assertEq(collateralList[1], address(0xf24608E0CCb972b0b0f4A6446a0BBf58c701a026)); + + // Check parameters are correct for the new collateral + uint256 newCollateralIndex = 1; + address newCollateral = collateralList[newCollateralIndex]; + { + ( + Storage.OracleReadType oracleType, + Storage.OracleReadType targetType, + bytes memory oracleData, + bytes memory targetData, + bytes memory hyperparameters + ) = transmuter.getOracle(newCollateral); + assertEq(uint256(oracleType), uint256(Storage.OracleReadType.NO_ORACLE)); + assertEq(uint256(targetType), uint256(Storage.OracleReadType.MORPHO_ORACLE)); + assertEq(oracleData.length, 0); + assertNotEq(targetData.length, 0); + assertEq(hyperparameters, abi.encode(uint128(0), uint128(0))); + } + + { + (uint64[] memory xFeeMint, int64[] memory yFeeMint) = transmuter.getCollateralMintFees(newCollateral); + (uint64[] memory xFeeBurn, int64[] memory yFeeBurn) = transmuter.getCollateralBurnFees(newCollateral); + + assertEq(xFeeMint.length, 3); + assertEq(yFeeMint.length, 3); + assertEq(xFeeBurn.length, 3); + assertEq(yFeeBurn.length, 3); + + assertEq(xFeeMint[0], 0); + assertEq(xFeeMint[1], 0.79e9); + assertEq(xFeeMint[2], 0.80e9); + assertEq(xFeeBurn[0], 1e9); + assertEq(xFeeBurn[1], 0.31e9); + assertEq(xFeeBurn[2], 0.30e9); + + assertEq(yFeeBurn[0], 0.005e9); + assertEq(yFeeBurn[1], 0.005e9); + assertEq(yFeeBurn[2], 0.999e9); + assertEq(yFeeMint[0], 0.0005e9); + assertEq(yFeeMint[1], 0.0005e9); + assertEq(yFeeMint[2], 100e9 - 1); + } + + // Check storage new collat + { + Storage.Collateral memory collatInfo = transmuter.getCollateralInfo(newCollateral); + assertEq(collatInfo.isManaged, 0); + assertEq(collatInfo.isMintLive, 1); + assertEq(collatInfo.isBurnLive, 1); + assertEq(collatInfo.decimals, 6); + assertEq(collatInfo.onlyWhitelisted, 0); + assertEq(collatInfo.normalizedStables, 0); + assertEq(collatInfo.managerData.subCollaterals.length, 0); + assertEq(collatInfo.managerData.config.length, 0); + } + + // Test oracle values returned + uint256 value = IERC4626(newCollateral).convertToAssets(1e6) * 1e12; + { + (uint256 mint, uint256 burn, uint256 ratio, uint256 minRatio, uint256 redemption) = transmuter + .getOracleValues(newCollateral); + assertEq(mint, value); + assertEq(burn, value); + assertEq(ratio, BASE_18); + assertEq(redemption, value); + } + + // Check quotes are working on the added collateral + { + // we ca do some quoteIn and quoteOut + transmuter.quoteOut(value, newCollateral, address(agToken)); + transmuter.quoteIn(value, newCollateral, address(agToken)); + } + + transmuter.quoteRedemptionCurve(BASE_18); + } +} From 7702c45f99729f8365b5a77bd5cf6689dcd93fdb Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Fri, 8 Nov 2024 15:44:57 +0100 Subject: [PATCH 16/26] feat: use correct values of oracle amd thresholds --- .../TransmuterAddCollateralMW_EURC.s.sol | 24 +++++++++---------- .../TransmuterAddCollateralXEVT.s..sol | 8 +++---- .../TransmuterAddCollateralMW_EURC.t.sol | 8 +++---- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol index 67ecc89..bf12627 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol @@ -28,20 +28,20 @@ contract TransmuterAddCollateralMW_EURC is Utils { address to = address(transmuter); uint256 value = 0; - uint64[] memory xFeeBurn = new uint64[](3); - uint64[] memory xFeeMint = new uint64[](3); - int64[] memory yFeeMint = new int64[](xFeeMint.length); - int64[] memory yFeeBurn = new int64[](xFeeBurn.length); + xFeeBurn = new uint64[](3); + xFeeMint = new uint64[](3); + yFeeMint = new int64[](xFeeMint.length); + yFeeBurn = new int64[](xFeeBurn.length); xFeeBurn[0] = 1e9; - xFeeBurn[1] = 0.31e9; - xFeeBurn[2] = 0.30e9; + xFeeBurn[1] = 0.21e9; + xFeeBurn[2] = 0.20e9; yFeeBurn[0] = 0.005e9; yFeeBurn[1] = 0.005e9; yFeeBurn[2] = 0.999e9; xFeeMint[0] = 0; - xFeeMint[1] = 0.79e9; - xFeeMint[2] = 0.80e9; + xFeeMint[1] = 0.59e9; + xFeeMint[2] = 0.60e9; yFeeMint[0] = 0.0005e9; yFeeMint[1] = 0.0005e9; yFeeMint[2] = 100e9 - 1; @@ -49,16 +49,16 @@ contract TransmuterAddCollateralMW_EURC is Utils { // Add the new collateral { { - address oracle = 0x6B102047A4bB943DE39233E44487F2d57bDCb33e; // TODO - uint256 normalizationFactor = 1e18; // TODO + address oracle = 0xa7ea0d40C246b876F76713Ba9a9A95f3f18AB794; + uint256 normalizationFactor = 1e18; bytes memory readData; bytes memory targetData = abi.encode(oracle, normalizationFactor); oracleConfigCollatToAdd = abi.encode( - Storage.OracleReadType.NO_ORACLE, + Storage.OracleReadType.MAX, Storage.OracleReadType.MORPHO_ORACLE, readData, targetData, - abi.encode(uint128(0), uint128(0)) + abi.encode(uint128(0), uint128(0.0005e18)) ); } { diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol index 7ab647f..a796ea6 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralXEVT.s..sol @@ -28,10 +28,10 @@ contract TransmuterAddCollateralXEVT is Utils { address to = address(transmuter); uint256 value = 0; - uint64[] memory xFeeBurn = new uint64[](3); - uint64[] memory xFeeMint = new uint64[](3); - int64[] memory yFeeMint = new int64[](xFeeMint.length); - int64[] memory yFeeBurn = new int64[](xFeeBurn.length); + xFeeBurn = new uint64[](3); + xFeeMint = new uint64[](3); + yFeeMint = new int64[](xFeeMint.length); + yFeeBurn = new int64[](xFeeBurn.length); xFeeBurn[0] = 1e9; xFeeBurn[1] = 0.06e9; xFeeBurn[2] = 0.05e9; diff --git a/test/transmuter/TransmuterAddCollateralMW_EURC.t.sol b/test/transmuter/TransmuterAddCollateralMW_EURC.t.sol index 4b51549..68a65b7 100644 --- a/test/transmuter/TransmuterAddCollateralMW_EURC.t.sol +++ b/test/transmuter/TransmuterAddCollateralMW_EURC.t.sol @@ -81,11 +81,11 @@ contract TransmuterAddCollateralXEVTTest is BaseTest { assertEq(yFeeBurn.length, 3); assertEq(xFeeMint[0], 0); - assertEq(xFeeMint[1], 0.79e9); - assertEq(xFeeMint[2], 0.80e9); + assertEq(xFeeMint[1], 0.59e9); + assertEq(xFeeMint[2], 0.60e9); assertEq(xFeeBurn[0], 1e9); - assertEq(xFeeBurn[1], 0.31e9); - assertEq(xFeeBurn[2], 0.30e9); + assertEq(xFeeBurn[1], 0.21e9); + assertEq(xFeeBurn[2], 0.20e9); assertEq(yFeeBurn[0], 0.005e9); assertEq(yFeeBurn[1], 0.005e9); From a82867d2f124a6c493dbfb164728c69fe272d3a6 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Fri, 8 Nov 2024 15:53:28 +0100 Subject: [PATCH 17/26] feat: stablecoin cap --- .../transmuter/TransmuterAddCollateralMW_EURC.s.sol | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol index bf12627..a6f4058 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol @@ -123,6 +123,16 @@ contract TransmuterAddCollateralMW_EURC is Utils { bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); transactions = abi.encodePacked(transactions, internalTx); } + { + bytes memory data = abi.encodeWithSelector( + ISettersGuardian.setStablecoinCap.selector, + COLLATERAL_TO_ADD, + 2_000_000e18 + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } } bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); From ef6d0c1338b7d5e0c9f145482fdea45557f03ca3 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Fri, 8 Nov 2024 16:53:07 +0100 Subject: [PATCH 18/26] feat: setFees script --- .../transmuter/TransmuterSetFees.s.sol | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 scripts/foundry/transmuter/TransmuterSetFees.s.sol diff --git a/scripts/foundry/transmuter/TransmuterSetFees.s.sol b/scripts/foundry/transmuter/TransmuterSetFees.s.sol new file mode 100644 index 0000000..b395ff1 --- /dev/null +++ b/scripts/foundry/transmuter/TransmuterSetFees.s.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +import { console } from "forge-std/console.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper } from "transmuter/interfaces/ITransmuter.sol"; +import { Enum } from "safe/Safe.sol"; +import { MultiSend, Utils } from "../Utils.s.sol"; +import "../Constants.s.sol"; + +contract TransmuterSetFees is Utils { + uint64[] public xFeeBurn; + int64[] public yFeeBurn; + + function run() external { + uint256 chainId = vm.envUint("CHAIN_ID"); + + address safe = _chainToContract(chainId, ContractType.GuardianMultisig); + bytes memory transactions; + + xFeeBurn = new uint64[](1); + yFeeBurn = new int64[](xFeeBurn.length); + xFeeBurn[0] = 1e9; + yFeeBurn[0] = 0; + + { + ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + address to = address(transmuter); + uint8 isDelegateCall = 0; + { + bytes memory data = abi.encodeWithSelector(ISettersGuardian.setFees.selector, 0x3Ee320c9F73a84D1717557af00695A34b26d1F1d, xFeeBurn, yFeeBurn, false); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + } + + bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); + _serializeJson(chainId, address(_chainToMultiSend(chainId)), uint256(0), payloadMultiSend, Enum.Operation.DelegateCall, hex"", safe); + } +} From ad1273f52a0718cd16abb166b9b962a4070e0ccf Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Fri, 8 Nov 2024 16:53:24 +0100 Subject: [PATCH 19/26] feat: whitelist harvesters script --- .../TransmuterWhitelistHarvesters.s.sol | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 scripts/foundry/transmuter/TransmuterWhitelistHarvesters.s.sol diff --git a/scripts/foundry/transmuter/TransmuterWhitelistHarvesters.s.sol b/scripts/foundry/transmuter/TransmuterWhitelistHarvesters.s.sol new file mode 100644 index 0000000..c4268f8 --- /dev/null +++ b/scripts/foundry/transmuter/TransmuterWhitelistHarvesters.s.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +import { console } from "forge-std/console.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import { TrustedType } from "transmuter/transmuter/Storage.sol"; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper} from "transmuter/interfaces/ITransmuter.sol"; +import { Enum } from "safe/Safe.sol"; +import { MultiSend, Utils } from "../Utils.s.sol"; +import "../Constants.s.sol"; + +contract TransmuterWhitelistHarvesters is Utils { + function run() external { + uint256 chainId = vm.envUint("CHAIN_ID"); + + address safe = _chainToContract(chainId, ContractType.GovernorMultisig); + bytes memory transactions; + + { + ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + address to = address(transmuter); + uint8 isDelegateCall = 0; + { + bytes memory data = abi.encodeWithSelector(ISettersGovernor.toggleTrusted.selector, 0x0A10f87F55d89eb2a89c264ebE46C90785a10B77, TrustedType.Updater); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + } + { + ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgUSD)); + address to = address(transmuter); + uint8 isDelegateCall = 0; + { + bytes memory data = abi.encodeWithSelector(ISettersGovernor.toggleTrusted.selector, 0x54b96Fee8208Ea7aCe3d415e5c14798112909794, TrustedType.Updater); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + { + bytes memory data = abi.encodeWithSelector(ISettersGovernor.toggleTrusted.selector, 0x5BEdD878CBfaF4dc53EC272A291A6a4C2259369D, TrustedType.Updater); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + } + + bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); + _serializeJson(chainId, address(_chainToMultiSend(chainId)), uint256(0), payloadMultiSend, Enum.Operation.DelegateCall, hex"", safe); + } +} From 30ce9e023361b454d1f5aea5d5f71989028414d5 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Fri, 8 Nov 2024 18:12:53 +0100 Subject: [PATCH 20/26] feat: set target exposure --- foundry.toml | 2 +- lib/angle-transmuter | 2 +- scripts/foundry/transmuter/TransmuterSetFees.s.sol | 10 +++++++++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/foundry.toml b/foundry.toml index 586198a..1b4270a 100644 --- a/foundry.toml +++ b/foundry.toml @@ -9,7 +9,7 @@ gas_reports = ["*"] via_ir = false sizes = true optimizer_runs=1000 -solc_version = '0.8.22' +solc_version = '0.8.23' fs_permissions = [{ access = "read-write", path = "./scripts/foundry/transaction.json"}, { access = "read-write", path = "./scripts/foundry/transactions.json"}, { access = "read-write", path = "./lib/angle-tokens/scripts"}, { access = "read-write", path = "./scripts/proposals/transmuter/selectors.json"}, { access = "read-write", path = "./scripts/foundry/transmuter/updateFacets/selectors_replace.json"}, { access = "read-write", path = "./scripts/foundry/transmuter/updateFacets/selectors_add.json"}] ffi = true diff --git a/lib/angle-transmuter b/lib/angle-transmuter index 1c417c4..3ea9f59 160000 --- a/lib/angle-transmuter +++ b/lib/angle-transmuter @@ -1 +1 @@ -Subproject commit 1c417c47b0cecdfc07fd8175b71c20c3524ac593 +Subproject commit 3ea9f59d4de1b1812ca50d960ff6afc0e21d0573 diff --git a/scripts/foundry/transmuter/TransmuterSetFees.s.sol b/scripts/foundry/transmuter/TransmuterSetFees.s.sol index b395ff1..cbc1809 100644 --- a/scripts/foundry/transmuter/TransmuterSetFees.s.sol +++ b/scripts/foundry/transmuter/TransmuterSetFees.s.sol @@ -6,6 +6,7 @@ import "transmuter/transmuter/Storage.sol" as Storage; import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper } from "transmuter/interfaces/ITransmuter.sol"; import { Enum } from "safe/Safe.sol"; import { MultiSend, Utils } from "../Utils.s.sol"; +import { BaseHarvester } from "transmuter/helpers/BaseHarvester.sol"; import "../Constants.s.sol"; contract TransmuterSetFees is Utils { @@ -25,14 +26,21 @@ contract TransmuterSetFees is Utils { { ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); - address to = address(transmuter); uint8 isDelegateCall = 0; { + address to = address(transmuter); bytes memory data = abi.encodeWithSelector(ISettersGuardian.setFees.selector, 0x3Ee320c9F73a84D1717557af00695A34b26d1F1d, xFeeBurn, yFeeBurn, false); uint256 dataLength = data.length; bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); transactions = abi.encodePacked(transactions, internalTx); } + { + address to = 0x0A10f87F55d89eb2a89c264ebE46C90785a10B77; + bytes memory data = abi.encodeWithSelector(BaseHarvester.setTargetExposure.selector, 0x3Ee320c9F73a84D1717557af00695A34b26d1F1d, 0); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } } bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); From 43790817db83441be41023b7954e4a6cacacedbf Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:30:05 +0100 Subject: [PATCH 21/26] last test --- lib/borrow-contracts | 2 +- lib/forge-std | 2 +- lib/merkl-contracts | 2 +- lib/safe-contracts | 2 +- scripts/foundry/transaction.json | 5 +- ...ol => TransmuterAddCollateralMWEURC.s.sol} | 54 +++++++++------ ...ol => TransmuterAddCollateralMWEURC.t.sol} | 67 +++++++++++-------- 7 files changed, 82 insertions(+), 52 deletions(-) rename scripts/foundry/transmuter/{TransmuterAddCollateralMW_EURC.s.sol => TransmuterAddCollateralMWEURC.s.sol} (84%) rename test/transmuter/{TransmuterAddCollateralMW_EURC.t.sol => TransmuterAddCollateralMWEURC.t.sol} (69%) diff --git a/lib/borrow-contracts b/lib/borrow-contracts index ffd3a76..f88d770 160000 --- a/lib/borrow-contracts +++ b/lib/borrow-contracts @@ -1 +1 @@ -Subproject commit ffd3a76067d3265b3631bc61bb9406704bb17eb9 +Subproject commit f88d7703846f04b7821192bcdaf1093d6f24735d diff --git a/lib/forge-std b/lib/forge-std index 52715a2..0e70977 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 +Subproject commit 0e7097750918380d84dd3cfdef595bee74dabb70 diff --git a/lib/merkl-contracts b/lib/merkl-contracts index 9890715..a702097 160000 --- a/lib/merkl-contracts +++ b/lib/merkl-contracts @@ -1 +1 @@ -Subproject commit 9890715728874b28008b15fe4fbe98dcf7bb3e5f +Subproject commit a7020975374c95d15c48791e7f77acd1065f3eb6 diff --git a/lib/safe-contracts b/lib/safe-contracts index 8ffae95..129f02c 160000 --- a/lib/safe-contracts +++ b/lib/safe-contracts @@ -1 +1 @@ -Subproject commit 8ffae95faa815acf86ec8b50021ebe9f96abde10 +Subproject commit 129f02cdd72b7af806d90a622959f42d6171bd70 diff --git a/scripts/foundry/transaction.json b/scripts/foundry/transaction.json index 095ec12..b9c5fec 100644 --- a/scripts/foundry/transaction.json +++ b/scripts/foundry/transaction.json @@ -1,8 +1,9 @@ { - "additionalData": "0x89e1e82a0000000000000000000000000000000000000000000000000000000000000000", + "additionalData": "0x", "chainId": 8453, - "data": "0x8d80ff0a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000079003ef3d8ba38ebe18db133cec108f4d14ce00dd9ae0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002489e1e82a000000000000000000000000000000000000000000000000000000000000000000000000000000", + "data": "0x8d80ff0a0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000084f00ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f0d2d5a8000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a02600ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000184629feb62000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a0260000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000232aaf800000000000000000000000000000000000000000000000000000000023c346000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000e8d4a50fff00ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000184629feb62000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a0260000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000000c845880000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000004c4b40000000000000000000000000000000000000000000000000000000003b8b87c000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204b13b0847000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a7ea0d40c246b876f76713ba9a9a95f3f18ab7940000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000dfdf8cff983e38f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf5263400000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9e6a1a4000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000000000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9e6a1a4000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000000100ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044603b4327000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a02600000000000000000000000000000000000000000001a784379d99db420000000000000000000000000000000000000000", "operation": 1, + "safe": "0x7DF37fc774843b678f586D55483819605228a0ae", "to": "0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B", "value": 0 } \ No newline at end of file diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol similarity index 84% rename from scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol rename to scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol index a6f4058..bd77a48 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralMW_EURC.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol @@ -6,9 +6,10 @@ import "transmuter/transmuter/Storage.sol" as Storage; import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper } from "transmuter/interfaces/ITransmuter.sol"; import { Enum } from "safe/Safe.sol"; import { MultiSend, Utils } from "../Utils.s.sol"; +import { MAX_MINT_FEE, MAX_BURN_FEE } from "transmuter/utils/Constants.sol"; import "../Constants.s.sol"; -contract TransmuterAddCollateralMW_EURC is Utils { +contract TransmuterAddCollateralMWEURC is Utils { address public constant COLLATERAL_TO_ADD = 0xf24608E0CCb972b0b0f4A6446a0BBf58c701a026; bytes oracleConfigCollatToAdd; @@ -16,12 +17,14 @@ contract TransmuterAddCollateralMW_EURC is Utils { int64[] public yFeeMint; uint64[] public xFeeBurn; int64[] public yFeeBurn; + uint256 public capStablecoin; address public agToken; function run() external { uint256 chainId = vm.envUint("CHAIN_ID"); - ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + // ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + ITransmuter transmuter = ITransmuter(0xBA0e73218a80C3deC1213d64873aF83B02cE0455); agToken = address(transmuter.agToken()); bytes memory transactions; uint8 isDelegateCall = 0; @@ -37,30 +40,19 @@ contract TransmuterAddCollateralMW_EURC is Utils { xFeeBurn[2] = 0.20e9; yFeeBurn[0] = 0.005e9; yFeeBurn[1] = 0.005e9; - yFeeBurn[2] = 0.999e9; + yFeeBurn[2] = int64(uint64(MAX_BURN_FEE)); xFeeMint[0] = 0; xFeeMint[1] = 0.59e9; xFeeMint[2] = 0.60e9; yFeeMint[0] = 0.0005e9; yFeeMint[1] = 0.0005e9; - yFeeMint[2] = 100e9 - 1; + yFeeMint[2] = int64(uint64(MAX_MINT_FEE)); + + capStablecoin = 2_000_000 ether; // Add the new collateral { - { - address oracle = 0xa7ea0d40C246b876F76713Ba9a9A95f3f18AB794; - uint256 normalizationFactor = 1e18; - bytes memory readData; - bytes memory targetData = abi.encode(oracle, normalizationFactor); - oracleConfigCollatToAdd = abi.encode( - Storage.OracleReadType.MAX, - Storage.OracleReadType.MORPHO_ORACLE, - readData, - targetData, - abi.encode(uint128(0), uint128(0.0005e18)) - ); - } { bytes memory data = abi.encodeWithSelector(ISettersGovernor.addCollateral.selector, COLLATERAL_TO_ADD); uint256 dataLength = data.length; @@ -93,6 +85,21 @@ contract TransmuterAddCollateralMW_EURC is Utils { bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); transactions = abi.encodePacked(transactions, internalTx); } + + { + address oracle = 0xa7ea0d40C246b876F76713Ba9a9A95f3f18AB794; + uint256 normalizationFactor = 1e18; + bytes memory targetData = abi.encode(1008235463728948111); + bytes memory readData = abi.encode(oracle, normalizationFactor); + oracleConfigCollatToAdd = abi.encode( + Storage.OracleReadType.MORPHO_ORACLE, + Storage.OracleReadType.MAX, + readData, + targetData, + abi.encode(uint128(0), uint128(0.0005e18)) + ); + } + { bytes memory data = abi.encodeWithSelector( ISettersGovernor.setOracle.selector, @@ -127,7 +134,7 @@ contract TransmuterAddCollateralMW_EURC is Utils { bytes memory data = abi.encodeWithSelector( ISettersGuardian.setStablecoinCap.selector, COLLATERAL_TO_ADD, - 2_000_000e18 + capStablecoin ); uint256 dataLength = data.length; bytes memory internalTx = abi.encodePacked(isDelegateCall, to, value, dataLength, data); @@ -137,6 +144,15 @@ contract TransmuterAddCollateralMW_EURC is Utils { bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); address multiSend = address(_chainToMultiSend(chainId)); - _serializeJson(chainId, multiSend, 0, payloadMultiSend, Enum.Operation.DelegateCall, hex"", _chainToContract(chainId, ContractType.GovernorMultisig)); + _serializeJson( + chainId, + multiSend, + 0, + payloadMultiSend, + Enum.Operation.DelegateCall, + hex"", + // _chainToContract(chainId, ContractType.GovernorMultisig) + 0x7DF37fc774843b678f586D55483819605228a0ae + ); } } diff --git a/test/transmuter/TransmuterAddCollateralMW_EURC.t.sol b/test/transmuter/TransmuterAddCollateralMWEURC.t.sol similarity index 69% rename from test/transmuter/TransmuterAddCollateralMW_EURC.t.sol rename to test/transmuter/TransmuterAddCollateralMWEURC.t.sol index 68a65b7..d19f57b 100644 --- a/test/transmuter/TransmuterAddCollateralMW_EURC.t.sol +++ b/test/transmuter/TransmuterAddCollateralMWEURC.t.sol @@ -13,7 +13,7 @@ import { MAX_MINT_FEE, MAX_BURN_FEE } from "transmuter/utils/Constants.sol"; import { IERC20 } from "oz/token/ERC20/IERC20.sol"; import { IERC4626 } from "oz/token/ERC20/extensions/ERC4626.sol"; -contract TransmuterAddCollateralXEVTTest is BaseTest { +contract TransmuterAddCollateralMWEURCTest is BaseTest { using stdJson for string; ITransmuter public transmuter; @@ -32,9 +32,13 @@ contract TransmuterAddCollateralXEVTTest is BaseTest { StablecoinType fiat = StablecoinType.EUR; // TODO END - address gnosisSafe = _chainToContract(chainId, ContractType.GovernorMultisig); - transmuter = ITransmuter(address(_getTransmuter(chainId, fiat))); - agToken = _getAgToken(chainId, fiat); + // address gnosisSafe = _chainToContract(chainId, ContractType.GovernorMultisig); + // transmuter = ITransmuter(address(_getTransmuter(chainId, fiat))); + // agToken = _getAgToken(chainId, fiat); + + address gnosisSafe = 0x7DF37fc774843b678f586D55483819605228a0ae; + transmuter = ITransmuter(0xBA0e73218a80C3deC1213d64873aF83B02cE0455); + agToken = IAgToken(address(transmuter.agToken())); address to = json.readAddress("$.to"); // uint256 value = json.readUint("$.value"); @@ -48,13 +52,13 @@ contract TransmuterAddCollateralXEVTTest is BaseTest { (bool success, ) = gnosisSafe.call(abi.encode(address(to), payload, operation, 1e7)); if (!success) revert(); + uint256 newCollateralIndex = 1; collateralList = transmuter.getCollateralList(); assertEq(agToken.isMinter(address(transmuter)), true); assertEq(collateralList.length, 2); - assertEq(collateralList[1], address(0xf24608E0CCb972b0b0f4A6446a0BBf58c701a026)); + assertEq(collateralList[newCollateralIndex], address(0xf24608E0CCb972b0b0f4A6446a0BBf58c701a026)); // Check parameters are correct for the new collateral - uint256 newCollateralIndex = 1; address newCollateral = collateralList[newCollateralIndex]; { ( @@ -64,11 +68,18 @@ contract TransmuterAddCollateralXEVTTest is BaseTest { bytes memory targetData, bytes memory hyperparameters ) = transmuter.getOracle(newCollateral); - assertEq(uint256(oracleType), uint256(Storage.OracleReadType.NO_ORACLE)); - assertEq(uint256(targetType), uint256(Storage.OracleReadType.MORPHO_ORACLE)); - assertEq(oracleData.length, 0); - assertNotEq(targetData.length, 0); - assertEq(hyperparameters, abi.encode(uint128(0), uint128(0))); + + bytes memory readData; + { + address oracle = 0xa7ea0d40C246b876F76713Ba9a9A95f3f18AB794; + uint256 normalizationFactor = 1e18; + readData = abi.encode(oracle, normalizationFactor); + } + assertEq(uint256(oracleType), uint256(Storage.OracleReadType.MORPHO_ORACLE)); + assertEq(uint256(targetType), uint256(Storage.OracleReadType.MAX)); + assertEq(oracleData, readData); + assertEq(targetData, abi.encode(1008235463728948111)); + assertEq(hyperparameters, abi.encode(uint128(0), uint128(0.0005e18))); } { @@ -80,19 +91,19 @@ contract TransmuterAddCollateralXEVTTest is BaseTest { assertEq(xFeeBurn.length, 3); assertEq(yFeeBurn.length, 3); - assertEq(xFeeMint[0], 0); - assertEq(xFeeMint[1], 0.59e9); - assertEq(xFeeMint[2], 0.60e9); assertEq(xFeeBurn[0], 1e9); assertEq(xFeeBurn[1], 0.21e9); assertEq(xFeeBurn[2], 0.20e9); - assertEq(yFeeBurn[0], 0.005e9); assertEq(yFeeBurn[1], 0.005e9); - assertEq(yFeeBurn[2], 0.999e9); + assertEq(yFeeBurn[2], int64(uint64(MAX_BURN_FEE))); + + assertEq(xFeeMint[0], 0); + assertEq(xFeeMint[1], 0.59e9); + assertEq(xFeeMint[2], 0.60e9); assertEq(yFeeMint[0], 0.0005e9); assertEq(yFeeMint[1], 0.0005e9); - assertEq(yFeeMint[2], 100e9 - 1); + assertEq(yFeeMint[2], int64(uint64(MAX_MINT_FEE))); } // Check storage new collat @@ -101,29 +112,31 @@ contract TransmuterAddCollateralXEVTTest is BaseTest { assertEq(collatInfo.isManaged, 0); assertEq(collatInfo.isMintLive, 1); assertEq(collatInfo.isBurnLive, 1); - assertEq(collatInfo.decimals, 6); + assertEq(collatInfo.decimals, 18); assertEq(collatInfo.onlyWhitelisted, 0); assertEq(collatInfo.normalizedStables, 0); assertEq(collatInfo.managerData.subCollaterals.length, 0); assertEq(collatInfo.managerData.config.length, 0); } - // Test oracle values returned - uint256 value = IERC4626(newCollateral).convertToAssets(1e6) * 1e12; { + // Test oracle values returned + uint256 value = IERC4626(newCollateral).convertToAssets(1 ether) * 1e12; (uint256 mint, uint256 burn, uint256 ratio, uint256 minRatio, uint256 redemption) = transmuter .getOracleValues(newCollateral); - assertEq(mint, value); - assertEq(burn, value); - assertEq(ratio, BASE_18); - assertEq(redemption, value); + assertApproxEqAbs(mint, value, 0.01 ether); + assertApproxEqAbs(burn, value, 0.01 ether); + assertApproxEqAbs(ratio, BASE_18, 0.01 ether); + assertApproxEqAbs(redemption, value,0.01 ether); } // Check quotes are working on the added collateral { - // we ca do some quoteIn and quoteOut - transmuter.quoteOut(value, newCollateral, address(agToken)); - transmuter.quoteIn(value, newCollateral, address(agToken)); + // we can do some quoteIn and quoteOut + uint256 mintedAmount = transmuter.quoteIn(1 ether, newCollateral, address(agToken)); + assertApproxEqAbs(mintedAmount, 1 ether, 0.01 ether); + uint256 fromAmount = transmuter.quoteOut(1 ether, newCollateral, address(agToken)); + assertApproxEqAbs(fromAmount, 1 ether, 0.01 ether); } transmuter.quoteRedemptionCurve(BASE_18); From 4f1b3f727ce77326e523c4b40fa17c151966d073 Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:26:54 +0100 Subject: [PATCH 22/26] fix lib utils repo --- .../transmuter/TransmuterAddCollateralMWEURC.s.sol | 6 ++---- test/transmuter/TransmuterAddCollateralMWEURC.t.sol | 12 ++++-------- utils/forwardUtils.js | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol index bd77a48..1ee78a1 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol @@ -23,8 +23,7 @@ contract TransmuterAddCollateralMWEURC is Utils { function run() external { uint256 chainId = vm.envUint("CHAIN_ID"); - // ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); - ITransmuter transmuter = ITransmuter(0xBA0e73218a80C3deC1213d64873aF83B02cE0455); + ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); agToken = address(transmuter.agToken()); bytes memory transactions; uint8 isDelegateCall = 0; @@ -151,8 +150,7 @@ contract TransmuterAddCollateralMWEURC is Utils { payloadMultiSend, Enum.Operation.DelegateCall, hex"", - // _chainToContract(chainId, ContractType.GovernorMultisig) - 0x7DF37fc774843b678f586D55483819605228a0ae + _chainToContract(chainId, ContractType.GovernorMultisig) ); } } diff --git a/test/transmuter/TransmuterAddCollateralMWEURC.t.sol b/test/transmuter/TransmuterAddCollateralMWEURC.t.sol index d19f57b..e389762 100644 --- a/test/transmuter/TransmuterAddCollateralMWEURC.t.sol +++ b/test/transmuter/TransmuterAddCollateralMWEURC.t.sol @@ -32,13 +32,9 @@ contract TransmuterAddCollateralMWEURCTest is BaseTest { StablecoinType fiat = StablecoinType.EUR; // TODO END - // address gnosisSafe = _chainToContract(chainId, ContractType.GovernorMultisig); - // transmuter = ITransmuter(address(_getTransmuter(chainId, fiat))); - // agToken = _getAgToken(chainId, fiat); - - address gnosisSafe = 0x7DF37fc774843b678f586D55483819605228a0ae; - transmuter = ITransmuter(0xBA0e73218a80C3deC1213d64873aF83B02cE0455); - agToken = IAgToken(address(transmuter.agToken())); + address gnosisSafe = _chainToContract(chainId, ContractType.GovernorMultisig); + transmuter = ITransmuter(address(_getTransmuter(chainId, fiat))); + agToken = _getAgToken(chainId, fiat); address to = json.readAddress("$.to"); // uint256 value = json.readUint("$.value"); @@ -127,7 +123,7 @@ contract TransmuterAddCollateralMWEURCTest is BaseTest { assertApproxEqAbs(mint, value, 0.01 ether); assertApproxEqAbs(burn, value, 0.01 ether); assertApproxEqAbs(ratio, BASE_18, 0.01 ether); - assertApproxEqAbs(redemption, value,0.01 ether); + assertApproxEqAbs(redemption, value, 0.01 ether); } // Check quotes are working on the added collateral diff --git a/utils/forwardUtils.js b/utils/forwardUtils.js index 0eaa8cd..d5679d2 100755 --- a/utils/forwardUtils.js +++ b/utils/forwardUtils.js @@ -8,7 +8,7 @@ if (process.argv.length < 3) { const command = process.argv[2]; const extraArgs = process.argv.slice(3).join(' '); -exec(`node lib/utils/utils/${command}.js ${extraArgs}`, (error, stdout, stderr) => { +exec(`bun run lib/utils/utils/${command}.js ${extraArgs}`, (error, stdout, stderr) => { if (error) { console.log(error); process.exit(1); From aff7a11704358c5b7b1959db7cb6c96ba786747e Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Fri, 15 Nov 2024 09:40:03 +0100 Subject: [PATCH 23/26] change target init --- helpers/createTx.sh | 2 +- package.json | 4 +- scripts/foundry/transaction.json | 2 +- .../TransmuterAddCollateralMWEURC.s.sol | 2 +- scripts/submitFoundryTx.ts | 8 +- .../TransmuterAddCollateralMWEURC.t.sol | 2 +- yarn.lock | 88 ++++++++++++++++--- 7 files changed, 87 insertions(+), 21 deletions(-) diff --git a/helpers/createTx.sh b/helpers/createTx.sh index b757933..71cf2e2 100644 --- a/helpers/createTx.sh +++ b/helpers/createTx.sh @@ -120,7 +120,7 @@ function main { read execute if [[ $execute == "yes" ]]; then - yarn submit:foundry + bun submit:foundry fi done } diff --git a/package.json b/package.json index 2734d2b..ad1627f 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "prettier": "prettier --write ." }, "devDependencies": { - "@angleprotocol/sdk": "^v2.28.19", + "@angleprotocol/sdk": "^v2.33.34", "@chainlink/contracts": "0.2.1", "@metamask/detect-provider": "1.2.0", "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers", @@ -59,4 +59,4 @@ "keywords": [], "author": "", "license": "ISC" -} +} \ No newline at end of file diff --git a/scripts/foundry/transaction.json b/scripts/foundry/transaction.json index b9c5fec..f905b3d 100644 --- a/scripts/foundry/transaction.json +++ b/scripts/foundry/transaction.json @@ -1,7 +1,7 @@ { "additionalData": "0x", "chainId": 8453, - "data": "0x8d80ff0a0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000084f00ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f0d2d5a8000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a02600ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000184629feb62000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a0260000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000232aaf800000000000000000000000000000000000000000000000000000000023c346000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000e8d4a50fff00ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000184629feb62000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a0260000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000000c845880000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000004c4b40000000000000000000000000000000000000000000000000000000003b8b87c000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204b13b0847000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a7ea0d40c246b876f76713ba9a9a95f3f18ab7940000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000dfdf8cff983e38f000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf5263400000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9e6a1a4000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000000000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9e6a1a4000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000000100ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044603b4327000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a02600000000000000000000000000000000000000000001a784379d99db420000000000000000000000000000000000000000", + "data": "0x8d80ff0a0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000084f00ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f0d2d5a8000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a02600ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000184629feb62000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a0260000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000232aaf800000000000000000000000000000000000000000000000000000000023c346000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000e8d4a50fff00ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000184629feb62000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a0260000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000000c845880000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000004c4b40000000000000000000000000000000000000000000000000000000003b8b87c000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204b13b0847000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a7ea0d40c246b876f76713ba9a9a95f3f18ab7940000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000de388d72f57a000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf5263400000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9e6a1a4000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000000000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9e6a1a4000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000000100ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044603b4327000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a02600000000000000000000000000000000000000000001a784379d99db420000000000000000000000000000000000000000", "operation": 1, "safe": "0x7DF37fc774843b678f586D55483819605228a0ae", "to": "0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B", diff --git a/scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol b/scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol index 1ee78a1..6cfc3e1 100644 --- a/scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol +++ b/scripts/foundry/transmuter/TransmuterAddCollateralMWEURC.s.sol @@ -88,7 +88,7 @@ contract TransmuterAddCollateralMWEURC is Utils { { address oracle = 0xa7ea0d40C246b876F76713Ba9a9A95f3f18AB794; uint256 normalizationFactor = 1e18; - bytes memory targetData = abi.encode(1008235463728948111); + bytes memory targetData = abi.encode(1000794000000000000); // 1008235463728948111 bytes memory readData = abi.encode(oracle, normalizationFactor); oracleConfigCollatToAdd = abi.encode( Storage.OracleReadType.MORPHO_ORACLE, diff --git a/scripts/submitFoundryTx.ts b/scripts/submitFoundryTx.ts index 8231acd..174543d 100644 --- a/scripts/submitFoundryTx.ts +++ b/scripts/submitFoundryTx.ts @@ -1,14 +1,14 @@ import { submit } from './utils/submitTx'; import transactionJson from '../scripts/foundry/transaction.json'; -import { registry } from '@angleprotocol/sdk'; async function main() { const chainId = transactionJson['chainId']; delete transactionJson['additionalData']; console.log(transactionJson); - // TODO need to change the destination safe - const safeAddress = transactionJson['safe'] ?? registry(chainId).Governor; - await submit(transactionJson, 0, chainId, safeAddress); + const safeAddress = transactionJson['safe']; + if(!safeAddress) throw new Error('Safe address not found'); + + await submit(transactionJson, 52, chainId, safeAddress); } main().catch(error => { diff --git a/test/transmuter/TransmuterAddCollateralMWEURC.t.sol b/test/transmuter/TransmuterAddCollateralMWEURC.t.sol index e389762..8a5f4ba 100644 --- a/test/transmuter/TransmuterAddCollateralMWEURC.t.sol +++ b/test/transmuter/TransmuterAddCollateralMWEURC.t.sol @@ -74,7 +74,7 @@ contract TransmuterAddCollateralMWEURCTest is BaseTest { assertEq(uint256(oracleType), uint256(Storage.OracleReadType.MORPHO_ORACLE)); assertEq(uint256(targetType), uint256(Storage.OracleReadType.MAX)); assertEq(oracleData, readData); - assertEq(targetData, abi.encode(1008235463728948111)); + assertEq(targetData, abi.encode(1000794000000000000)); assertEq(hyperparameters, abi.encode(uint128(0), uint128(0.0005e18))); } diff --git a/yarn.lock b/yarn.lock index a2387e5..8008ff8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,21 +2,24 @@ # yarn lockfile v1 -"@angleprotocol/sdk@^v2.28.19": - version "2.28.19" - resolved "https://npm.pkg.github.com/download/@angleprotocol/sdk/2.28.19/2f7a23045c30ff8a246a7d0a7b17bb4d491a8d5e#2f7a23045c30ff8a246a7d0a7b17bb4d491a8d5e" - integrity sha512-2Db7OVy7iVMyKVvdlJBupsHIJJhLwUVNIyvfY7B1z5SrigXeIAM/SBjVzduqKEDsRPhPvlEWASsRlf6zt5+JRQ== +"@angleprotocol/sdk@^v2.33.34": + version "2.33.34" + resolved "https://npm.pkg.github.com/download/@angleprotocol/sdk/2.33.34/0268b1d3f9ac2b37d3a7eb267aa077f24fa36426#0268b1d3f9ac2b37d3a7eb267aa077f24fa36426" + integrity sha512-GPVN8azvCgqT8F/rGp5d0m4uJ8ZFO7wKwfOFgLEK2bM5V0UziQBWX/2sbLKQNUzEcNVklRqnK/nNufFDrPqxwg== dependencies: "@apollo/client" "^3.7.17" "@typechain/ethers-v5" "^10.0.0" - "@types/lodash" "^4.14.180" + bun-types "^1.1.27" + class-transformer "^0.5.1" + class-validator "^0.14.1" + cross-fetch "^4.0.0" ethers "^5.6.4" graphql "^15.7.1" graphql-request "^3.6.1" jsbi "^4.3.0" keccak256 "^1.0.6" - lodash "^4.17.21" merkletreejs "^0.3.10" + reflect-metadata "^0.2.2" tiny-invariant "^1.1.0" typechain "^8.3.2" @@ -1884,11 +1887,6 @@ "@types/level-errors" "*" "@types/node" "*" -"@types/lodash@^4.14.180": - version "4.17.5" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.5.tgz#e6c29b58e66995d57cd170ce3e2a61926d55ee04" - integrity sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw== - "@types/lru-cache@^5.1.0": version "5.1.1" resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" @@ -1929,6 +1927,13 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw== +"@types/node@~20.12.8": + version "20.12.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.14.tgz#0c5cf7ef26aedfd64b0539bba9380ed1f57dcc77" + integrity sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg== + dependencies: + undici-types "~5.26.4" + "@types/pbkdf2@^3.0.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" @@ -1953,6 +1958,18 @@ dependencies: "@types/node" "*" +"@types/validator@^13.11.8": + version "13.12.2" + resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.12.2.tgz#760329e756e18a4aab82fc502b51ebdfebbe49f5" + integrity sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA== + +"@types/ws@~8.5.10": + version "8.5.13" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.13.tgz#6414c280875e2691d0d1e080b05addbf5cb91e20" + integrity sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "20.2.1" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129" @@ -2963,6 +2980,14 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= +bun-types@^1.1.27: + version "1.1.34" + resolved "https://registry.yarnpkg.com/bun-types/-/bun-types-1.1.34.tgz#cf0e1dc5aa8875573a3acb09bead0f23bab5aca2" + integrity sha512-br5QygTEL/TwB4uQOb96Ky22j4Gq2WxWH/8Oqv20fk5HagwKXo/akB+LiYgSfzexCt6kkcUaVm+bKiPl71xPvw== + dependencies: + "@types/node" "~20.12.8" + "@types/ws" "~8.5.10" + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -3278,6 +3303,11 @@ class-is@^1.1.0: resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== +class-transformer@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" + integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -3288,6 +3318,15 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +class-validator@^0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.14.1.tgz#ff2411ed8134e9d76acfeb14872884448be98110" + integrity sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ== + dependencies: + "@types/validator" "^13.11.8" + libphonenumber-js "^1.10.53" + validator "^13.9.0" + clean-css@4.2.x: version "4.2.4" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" @@ -3651,6 +3690,13 @@ cross-fetch@^3.0.6: dependencies: node-fetch "^2.6.12" +cross-fetch@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-4.0.0.tgz#f037aef1580bb3a1a35164ea2a848ba81b445983" + integrity sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g== + dependencies: + node-fetch "^2.6.12" + cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -6867,6 +6913,11 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +libphonenumber-js@^1.10.53: + version "1.11.14" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.11.14.tgz#d753524fd30e6433834a1464baf7efed4a06b593" + integrity sha512-sexvAfwcW1Lqws4zFp8heAtAEXbEDnvkYCEGzvOoMgZR7JhXo/IkE9MkkGACgBed5fWqh3ShBGnJBdDnU9N8EQ== + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -8577,6 +8628,11 @@ reduce-flatten@^2.0.0: resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== +reflect-metadata@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" + integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== + regenerator-runtime@^0.13.4: version "0.13.9" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" @@ -10120,6 +10176,11 @@ underscore@^1.8.3: resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.2.tgz#276cea1e8b9722a8dbed0100a407dda572125881" integrity sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g== +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -10322,6 +10383,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validator@^13.9.0: + version "13.12.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.12.0.tgz#7d78e76ba85504da3fee4fd1922b385914d4b35f" + integrity sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg== + varint@^5.0.0: version "5.0.2" resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" From da9579a7df087a0b8f55796fee80060d7d5f9f2d Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Tue, 19 Nov 2024 10:39:48 +0100 Subject: [PATCH 24/26] tests: add tests for SetFees, WhitelistHarvesters --- scripts/submitFoundryTx.ts | 2 +- test/transmuter/TransmuterSetFees.t.sol | 70 +++++++++++++++++++ .../TransmuterWhitelistHarvesters.t.sol | 47 +++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 test/transmuter/TransmuterSetFees.t.sol create mode 100644 test/transmuter/TransmuterWhitelistHarvesters.t.sol diff --git a/scripts/submitFoundryTx.ts b/scripts/submitFoundryTx.ts index 174543d..2ba9cef 100644 --- a/scripts/submitFoundryTx.ts +++ b/scripts/submitFoundryTx.ts @@ -8,7 +8,7 @@ async function main() { const safeAddress = transactionJson['safe']; if(!safeAddress) throw new Error('Safe address not found'); - await submit(transactionJson, 52, chainId, safeAddress); + await submit(transactionJson, 0, chainId, safeAddress); } main().catch(error => { diff --git a/test/transmuter/TransmuterSetFees.t.sol b/test/transmuter/TransmuterSetFees.t.sol new file mode 100644 index 0000000..349241b --- /dev/null +++ b/test/transmuter/TransmuterSetFees.t.sol @@ -0,0 +1,70 @@ +// 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 { MockSafe } from "../mock/MockSafe.sol"; +import { BaseTest } from "../BaseTest.t.sol"; +import "../../scripts/foundry/Constants.s.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import "transmuter/utils/Errors.sol" as Errors; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper, IGetters } from "transmuter/interfaces/ITransmuter.sol"; +import { MAX_MINT_FEE, MAX_BURN_FEE } from "transmuter/utils/Constants.sol"; +import { IERC20 } from "oz/token/ERC20/IERC20.sol"; +import { IERC4626 } from "oz/token/ERC20/extensions/ERC4626.sol"; +import { BaseHarvester } from "transmuter/helpers/BaseHarvester.sol"; + +contract TransmuterSetFeesTest is BaseTest { + using stdJson for string; + + ITransmuter public transmuter; + IAgToken public agToken; + + function testScript() external { + uint256 chainId = json.readUint("$.chainId"); + address safe = json.readAddress("$.safe"); + vm.selectFork(forkIdentifier[chainId]); + + + transmuter = transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + agToken = IAgToken(address(transmuter.agToken())); + + address to = json.readAddress("$.to"); + // uint256 value = json.readUint("$.value"); + uint256 operation = json.readUint("$.operation"); + bytes memory payload = json.readBytes("$.data"); + + // Verify that the call will succeed + MockSafe mockSafe = new MockSafe(); + vm.etch(safe, address(mockSafe).code); + vm.prank(safe); + (bool success, ) = safe.call(abi.encode(address(to), payload, operation, 1e7)); + if (!success) revert(); + + address collateral = 0x3Ee320c9F73a84D1717557af00695A34b26d1F1d; + { + (uint64[] memory xFeeBurn, int64[] memory yFeeBurn) = transmuter.getCollateralBurnFees(collateral); + + assertEq(xFeeBurn.length, 1); + assertEq(yFeeBurn.length, 1); + + assertEq(xFeeBurn[0], 1e9); + assertEq(yFeeBurn[0], 0); + } + + // Check quotes are working on the added collateral + { + // we ca do some quoteIn and quoteOut + transmuter.quoteOut(BASE_18, collateral, address(agToken)); + transmuter.quoteIn(BASE_18, collateral, address(agToken)); + } + + transmuter.quoteRedemptionCurve(BASE_18); + + { + BaseHarvester harvester = BaseHarvester(0x0A10f87F55d89eb2a89c264ebE46C90785a10B77); + (, uint64 target,,,) = harvester.yieldBearingData(collateral); + assertEq(target, 0); + } + } +} diff --git a/test/transmuter/TransmuterWhitelistHarvesters.t.sol b/test/transmuter/TransmuterWhitelistHarvesters.t.sol new file mode 100644 index 0000000..11cf4d7 --- /dev/null +++ b/test/transmuter/TransmuterWhitelistHarvesters.t.sol @@ -0,0 +1,47 @@ +// 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 { MockSafe } from "../mock/MockSafe.sol"; +import { BaseTest } from "../BaseTest.t.sol"; +import "../../scripts/foundry/Constants.s.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import "transmuter/utils/Errors.sol" as Errors; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper, IGetters } from "transmuter/interfaces/ITransmuter.sol"; +import { MAX_MINT_FEE, MAX_BURN_FEE } from "transmuter/utils/Constants.sol"; +import { IERC20 } from "oz/token/ERC20/IERC20.sol"; + +contract TransmuterWhitelistHarvestersTest is BaseTest { + using stdJson for string; + + ITransmuter public transmuter; + + function testScript() external { + uint256 chainId = json.readUint("$.chainId"); + address gnosisSafe = json.readAddress("$.safe"); + vm.selectFork(forkIdentifier[chainId]); + + address to = json.readAddress("$.to"); + // uint256 value = json.readUint("$.value"); + uint256 operation = json.readUint("$.operation"); + bytes memory payload = json.readBytes("$.data"); + + // Verify that the call will succeed + MockSafe mockSafe = new MockSafe(); + vm.etch(gnosisSafe, address(mockSafe).code); + vm.prank(gnosisSafe); + (bool success, ) = gnosisSafe.call(abi.encode(address(to), payload, operation, 1e7)); + if (!success) revert(); + + { + transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + assertEq(IGetters(address(transmuter)).isTrusted(address(0x0A10f87F55d89eb2a89c264ebE46C90785a10B77)), true); + } + { + transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgUSD)); + assertEq(IGetters(address(transmuter)).isTrusted(address(0x54b96Fee8208Ea7aCe3d415e5c14798112909794)), true); + assertEq(IGetters(address(transmuter)).isTrusted(address(0x5BEdD878CBfaF4dc53EC272A291A6a4C2259369D)), true); + } + } +} From 73ec13d3282790b10a6658f8ceb633d4c30c9340 Mon Sep 17 00:00:00 2001 From: 0xtekgrinder <0xtekgrinder@protonmail.com> Date: Tue, 19 Nov 2024 11:26:21 +0100 Subject: [PATCH 25/26] feat: correct trusted type for harvesters --- .../foundry/transmuter/TransmuterWhitelistHarvesters.s.sol | 6 +++--- test/transmuter/TransmuterWhitelistHarvesters.t.sol | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/foundry/transmuter/TransmuterWhitelistHarvesters.s.sol b/scripts/foundry/transmuter/TransmuterWhitelistHarvesters.s.sol index c4268f8..3939635 100644 --- a/scripts/foundry/transmuter/TransmuterWhitelistHarvesters.s.sol +++ b/scripts/foundry/transmuter/TransmuterWhitelistHarvesters.s.sol @@ -21,7 +21,7 @@ contract TransmuterWhitelistHarvesters is Utils { address to = address(transmuter); uint8 isDelegateCall = 0; { - bytes memory data = abi.encodeWithSelector(ISettersGovernor.toggleTrusted.selector, 0x0A10f87F55d89eb2a89c264ebE46C90785a10B77, TrustedType.Updater); + bytes memory data = abi.encodeWithSelector(ISettersGovernor.toggleTrusted.selector, 0x0A10f87F55d89eb2a89c264ebE46C90785a10B77, TrustedType.Seller); uint256 dataLength = data.length; bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); transactions = abi.encodePacked(transactions, internalTx); @@ -32,13 +32,13 @@ contract TransmuterWhitelistHarvesters is Utils { address to = address(transmuter); uint8 isDelegateCall = 0; { - bytes memory data = abi.encodeWithSelector(ISettersGovernor.toggleTrusted.selector, 0x54b96Fee8208Ea7aCe3d415e5c14798112909794, TrustedType.Updater); + bytes memory data = abi.encodeWithSelector(ISettersGovernor.toggleTrusted.selector, 0x54b96Fee8208Ea7aCe3d415e5c14798112909794, TrustedType.Seller); uint256 dataLength = data.length; bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); transactions = abi.encodePacked(transactions, internalTx); } { - bytes memory data = abi.encodeWithSelector(ISettersGovernor.toggleTrusted.selector, 0x5BEdD878CBfaF4dc53EC272A291A6a4C2259369D, TrustedType.Updater); + bytes memory data = abi.encodeWithSelector(ISettersGovernor.toggleTrusted.selector, 0x5BEdD878CBfaF4dc53EC272A291A6a4C2259369D, TrustedType.Seller); uint256 dataLength = data.length; bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); transactions = abi.encodePacked(transactions, internalTx); diff --git a/test/transmuter/TransmuterWhitelistHarvesters.t.sol b/test/transmuter/TransmuterWhitelistHarvesters.t.sol index 11cf4d7..9d5100c 100644 --- a/test/transmuter/TransmuterWhitelistHarvesters.t.sol +++ b/test/transmuter/TransmuterWhitelistHarvesters.t.sol @@ -36,12 +36,12 @@ contract TransmuterWhitelistHarvestersTest is BaseTest { { transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); - assertEq(IGetters(address(transmuter)).isTrusted(address(0x0A10f87F55d89eb2a89c264ebE46C90785a10B77)), true); + assertEq(IGetters(address(transmuter)).isTrustedSeller(address(0x0A10f87F55d89eb2a89c264ebE46C90785a10B77)), true); } { transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgUSD)); - assertEq(IGetters(address(transmuter)).isTrusted(address(0x54b96Fee8208Ea7aCe3d415e5c14798112909794)), true); - assertEq(IGetters(address(transmuter)).isTrusted(address(0x5BEdD878CBfaF4dc53EC272A291A6a4C2259369D)), true); + assertEq(IGetters(address(transmuter)).isTrustedSeller(address(0x54b96Fee8208Ea7aCe3d415e5c14798112909794)), true); + assertEq(IGetters(address(transmuter)).isTrustedSeller(address(0x5BEdD878CBfaF4dc53EC272A291A6a4C2259369D)), true); } } } From d92294e5ed0536a5eeeff07e84040fe570c771dd Mon Sep 17 00:00:00 2001 From: gs8nrv <55771972+GuillaumeNervoXS@users.noreply.github.com> Date: Wed, 20 Nov 2024 10:25:41 +0100 Subject: [PATCH 26/26] feat: recover rewards transmuter --- scripts/foundry/transaction.json | 8 +-- .../transmuter/TransmuterRecoverERC20.s.sol | 62 ++++++++++++++++++ test/transmuter/TransmuterERC20Recover.t.sol | 65 +++++++++++++++++++ 3 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 scripts/foundry/transmuter/TransmuterRecoverERC20.s.sol create mode 100644 test/transmuter/TransmuterERC20Recover.t.sol diff --git a/scripts/foundry/transaction.json b/scripts/foundry/transaction.json index f905b3d..9178da0 100644 --- a/scripts/foundry/transaction.json +++ b/scripts/foundry/transaction.json @@ -1,9 +1,9 @@ { "additionalData": "0x", - "chainId": 8453, - "data": "0x8d80ff0a0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000084f00ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024f0d2d5a8000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a02600ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000184629feb62000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a0260000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000232aaf800000000000000000000000000000000000000000000000000000000023c346000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000000007a120000000000000000000000000000000000000000000000000000000e8d4a50fff00ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000184629feb62000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a0260000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000000c845880000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000004c4b4000000000000000000000000000000000000000000000000000000000004c4b40000000000000000000000000000000000000000000000000000000003b8b87c000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000204b13b0847000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000900000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000a7ea0d40c246b876f76713ba9a9a95f3f18ab7940000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000de388d72f57a000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c6bf5263400000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9e6a1a4000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000000000ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9e6a1a4000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a026000000000000000000000000000000000000000000000000000000000000000100ba0e73218a80c3dec1213d64873af83b02ce045500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044603b4327000000000000000000000000f24608e0ccb972b0b0f4a6446a0bbf58c701a02600000000000000000000000000000000000000000001a784379d99db420000000000000000000000000000000000000000", + "chainId": 1, + "data": "0x8d80ff0a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001b200222222fd79264bbe280b4986f6fefbc3524d0137000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000845c3eebda0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca30c93b02514f86d5c86a6e375e3a330b435fb5000000000000000000000000a9ddd91249dfdd450e81e1c56ab60e1a62651701000000000000000000000000000000000000000000000011566924abcbc3d5eb00222222fd79264bbe280b4986f6fefbc3524d0137000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000845c3eebda00000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f39c581f595b53c5cb19bd0b3f8da6c935e2ca0000000000000000000000000a9ddd91249dfdd450e81e1c56ab60e1a6265170100000000000000000000000000000000000000000000000026cc04d97b7c69610000000000000000000000000000", "operation": 1, - "safe": "0x7DF37fc774843b678f586D55483819605228a0ae", - "to": "0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B", + "safe": "0xdC4e6DFe07EFCa50a197DF15D9200883eF4Eb1c8", + "to": "0x40A2aCCbd92BCA938b02010E17A5b8929b49130D", "value": 0 } \ No newline at end of file diff --git a/scripts/foundry/transmuter/TransmuterRecoverERC20.s.sol b/scripts/foundry/transmuter/TransmuterRecoverERC20.s.sol new file mode 100644 index 0000000..9513f37 --- /dev/null +++ b/scripts/foundry/transmuter/TransmuterRecoverERC20.s.sol @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.19; + +import { console } from "forge-std/console.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper } from "transmuter/interfaces/ITransmuter.sol"; +import { Enum } from "safe/Safe.sol"; +import { IERC20 } from "oz/token/ERC20/extensions/IERC20Metadata.sol"; +import { MultiSend, Utils } from "../Utils.s.sol"; +import "../Constants.s.sol"; + +contract TransmuterRecoverERC20 is Utils { + address[] public erc20ToRecover; + uint256[] public amountToRecover; + + function run() external { + uint256 chainId = vm.envUint("CHAIN_ID"); + + address safe = _chainToContract(chainId, ContractType.GovernorMultisig); + bytes memory transactions; + + erc20ToRecover = new address[](3); + erc20ToRecover[0] = 0xCA30c93B02514f86d5C86a6e375E3A330B435Fb5; + erc20ToRecover[1] = 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0; + erc20ToRecover[2] = 0x9994E35Db50125E0DF82e4c2dde62496CE330999; + + amountToRecover = new uint256[](3); + amountToRecover[0] = 319821197533155415531; + amountToRecover[1] = 2795614800816400737; + amountToRecover[2] = 309033239278443116794779; + + { + ITransmuter transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgUSD)); + uint8 isDelegateCall = 0; + for (uint256 i = 0; i < erc20ToRecover.length; i++) { + console.log(erc20ToRecover[i]); + address to = address(transmuter); + bytes memory data = abi.encodeWithSelector( + ISettersGovernor.recoverERC20.selector, + address(0), + erc20ToRecover[i], + 0xA9DdD91249DFdd450E81E1c56Ab60E1A62651701, + amountToRecover[i] + ); + uint256 dataLength = data.length; + bytes memory internalTx = abi.encodePacked(isDelegateCall, to, uint256(0), dataLength, data); + transactions = abi.encodePacked(transactions, internalTx); + } + } + + bytes memory payloadMultiSend = abi.encodeWithSelector(MultiSend.multiSend.selector, transactions); + _serializeJson( + chainId, + address(_chainToMultiSend(chainId)), + uint256(0), + payloadMultiSend, + Enum.Operation.DelegateCall, + hex"", + safe + ); + } +} diff --git a/test/transmuter/TransmuterERC20Recover.t.sol b/test/transmuter/TransmuterERC20Recover.t.sol new file mode 100644 index 0000000..c6990ee --- /dev/null +++ b/test/transmuter/TransmuterERC20Recover.t.sol @@ -0,0 +1,65 @@ +// 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 { MockSafe } from "../mock/MockSafe.sol"; +import { BaseTest } from "../BaseTest.t.sol"; +import "../../scripts/foundry/Constants.s.sol"; +import "transmuter/transmuter/Storage.sol" as Storage; +import "transmuter/utils/Errors.sol" as Errors; +import { ITransmuter, ISettersGovernor, ISettersGuardian, ISwapper, IGetters } from "transmuter/interfaces/ITransmuter.sol"; +import { MAX_MINT_FEE, MAX_BURN_FEE } from "transmuter/utils/Constants.sol"; +import { IERC20 } from "oz/token/ERC20/IERC20.sol"; +import { IERC4626 } from "oz/token/ERC20/extensions/ERC4626.sol"; +import { BaseHarvester } from "transmuter/helpers/BaseHarvester.sol"; + +contract TransmuterRecoverERC20Test is BaseTest { + using stdJson for string; + + ITransmuter public transmuter; + address[] public erc20ToRecover; + uint256[] public amountToRecover; + uint256[] public balancesBefore; + address public receiver = 0xA9DdD91249DFdd450E81E1c56Ab60E1A62651701; + + function testScript() external { + erc20ToRecover = new address[](3); + erc20ToRecover[0] = 0xCA30c93B02514f86d5C86a6e375E3A330B435Fb5; + erc20ToRecover[1] = 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0; + erc20ToRecover[2] = 0x9994E35Db50125E0DF82e4c2dde62496CE330999; + + amountToRecover = new uint256[](3); + amountToRecover[0] = 319821197533155415531; + amountToRecover[1] = 2795614800816400737; + amountToRecover[2] = 309033239278443116794779; + + balancesBefore = new uint256[](erc20ToRecover.length); + + uint256 chainId = json.readUint("$.chainId"); + address safe = json.readAddress("$.safe"); + vm.selectFork(forkIdentifier[chainId]); + transmuter = transmuter = ITransmuter(_chainToContract(chainId, ContractType.TransmuterAgEUR)); + + address to = json.readAddress("$.to"); + // uint256 value = json.readUint("$.value"); + uint256 operation = json.readUint("$.operation"); + bytes memory payload = json.readBytes("$.data"); + + for (uint256 i = 0; i < erc20ToRecover.length; i++) { + balancesBefore[i] = IERC20(erc20ToRecover[i]).balanceOf(receiver); + } + + // Verify that the call will succeed + MockSafe mockSafe = new MockSafe(); + vm.etch(safe, address(mockSafe).code); + vm.prank(safe); + (bool success, ) = safe.call(abi.encode(address(to), payload, operation, 1e7)); + if (!success) revert(); + + for (uint256 i = 0; i < erc20ToRecover.length; i++) { + uint256 balanceAfter = IERC20(erc20ToRecover[i]).balanceOf(receiver); + assertEq(balanceAfter, balancesBefore[i] + amountToRecover[i]); + } + } +}