diff --git a/diffs/AaveV3Ethereum_GSMMigration_20251113_before_AaveV3Ethereum_GSMMigration_20251113_after.md b/diffs/AaveV3Ethereum_GSMMigration_20251113_before_AaveV3Ethereum_GSMMigration_20251113_after.md new file mode 100644 index 000000000..03e795173 --- /dev/null +++ b/diffs/AaveV3Ethereum_GSMMigration_20251113_before_AaveV3Ethereum_GSMMigration_20251113_after.md @@ -0,0 +1,754 @@ +## Reserve changes + +### Reserves altered + +#### LINK ([0x514910771AF9Ca656af840dff83E8264EcF986CA](https://etherscan.io/address/0x514910771AF9Ca656af840dff83E8264EcF986CA)) + +| description | value before | value after | +| --- | --- | --- | +| aTokenUnderlyingBalance | 13,339,268.2878 LINK [13339268287858692233587361] | 13,339,108.2878 LINK [13339108287858692233587361] | +| virtualBalance | 13,339,267.2866 LINK [13339267286666280700624373] | 13,339,107.2866 LINK [13339107286666280700624373] | + + +## Raw diff + +```json +{ + "reserves": { + "0x514910771AF9Ca656af840dff83E8264EcF986CA": { + "aTokenUnderlyingBalance": { + "from": "13339268287858692233587361", + "to": "13339108287858692233587361" + }, + "virtualBalance": { + "from": "13339267286666280700624373", + "to": "13339107286666280700624373" + } + } + }, + "raw": { + "0x0b0c0d8346f69ee94d29405f5630fc883a1052ab": { + "label": null, + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000036": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002" + }, + "0x172d209324876149067df2431a48061d6e873c73eae84f3c6c0d9f6ce8961c27": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "0x2974bc752e3ee88955eca3b54fbeb8b99f22148d2fe0c02a03af5ee36a60a42d": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000004d3c375ed08ade001000000000000018d0bf423c03d8de000000" + }, + "0x4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b8": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000003a3868898305f04bec7fea77becff04c13444112" + }, + "0x4a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b9": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x000000000000000000000000882285e62656b9623af136ce3078c6bdcc33f5e3" + }, + "0x4cee56f28790491168c42f93c586ca70822de0cc0a14ff73db6b036b014dd4ca": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002" + }, + "0x64691f9c88e2e6b4867d44adbd591939e35af0e00a67553c81587d5f02897686": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000243bd78f174bc7ba9b900000000000002d7eb3f96e070d97000000" + } + } + }, + "0x167527db01325408696326e3580cd8e55d99dc1a": { + "label": "GhoEthereum.GSM_REGISTRY", + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000001": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002" + }, + "0x0f62667621af3a659837622a8b7f5abedb34f5d9f45f1038157cb9d3cae6a7a3": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002" + }, + "0x521f025d7969ed440c86f631cf342e8d12982d2e90271160bb39c7bcfe746a68": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x8e7953a60bc64b776c3fba21ac81fb1165bb1b9c205022d1f189eb1e8a9c46db": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6": { + "previousValue": "0x000000000000000000000000535b2f7c20b9c83d70e519cf9991578ef9816b7b", + "newValue": "0x0000000000000000000000003a3868898305f04bec7fea77becff04c13444112" + }, + "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7": { + "previousValue": "0x000000000000000000000000feeb6fe430b7523fef2a38327241ee7153779535", + "newValue": "0x000000000000000000000000882285e62656b9623af136ce3078c6bdcc33f5e3" + }, + "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf8": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf9": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xb15be38f1142bf0d9483bbd6492e98c42b5e278b1431bba9518001825911133c": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + } + }, + "0x1cdf8879ec8be012ba959eb515b11008e0cb6323": { + "label": "MiscEthereum.AAVE_CL_ROBOT_OPERATOR", + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000002": { + "previousValue": "0x000000000000000000000000000000000000000000000000000000000000000d", + "newValue": "0x000000000000000000000000000000000000000000000000000000000000000d" + }, + "0x2b513b5ab089b470b4d0a77b1252a9d56e768c174a9e4a9e54099e8a2546f25d": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000005", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x2d0d87e5f6758d48bdf23bcc25877d2af0e9346c58afbbf98295e5fe1a5c6279": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + "0x33ce4bfc6c10154c4d24f0c40836e0e313f7e086c8ac220eb261d0ba9726ccd3": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000004", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad1": { + "previousValue": "0xfa1682db000000000000000000000000a526e27103da59d6b9083cfaadd2aa97", + "newValue": "0x960e7aa200000000000000000000000044bc9f19bd2cfdfc1e4a6513bac76e7c" + }, + "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad2": { + "previousValue": "0xbc435e2200000000000000000000000078be4ce93df4bfe609f30aec506a2a3f", + "newValue": "0xbc6febfb000000000000000000000000c71839010f4cc74f5517ba71c4f474fd" + }, + "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5adb": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5adc": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x5732e9e7c62ac5deedf89f6c3025222d41c0f8409822fe3516dc0cdc538e6d3e": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000006e51936e0ed4256f9da4794b536b619c88ff0047" + }, + "0x5732e9e7c62ac5deedf89f6c3025222d41c0f8409822fe3516dc0cdc538e6d3f": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000051" + }, + "0xa33359ddb9ddbadc7daf6fb03407c59eda2a0ea158264cbd6e980b239955ae19": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x47484f2047534d203436323620737461746155534454204f7261636c65537761" + }, + "0xa33359ddb9ddbadc7daf6fb03407c59eda2a0ea158264cbd6e980b239955ae1a": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x70467265657a6572000000000000000000000000000000000000000000000000" + }, + "0xb1a4bc465a4ffb0e6ae4ebeedd020df19964db0c54942e6c606f723b58d787d0": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + "0xc9140bf4673d2d401969161656f5cbfb50ae6d2c4af77f450d01f3167c3cbb6f": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x000000000000000000000000733ab16005c39d07fd3d9d1a350aa6768d10125b" + }, + "0xc9140bf4673d2d401969161656f5cbfb50ae6d2c4af77f450d01f3167c3cbb70": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000051" + }, + "0xe014d1acee717650c993d6a7ea1e69d4a8c7cd454d43815d9e3f22fbf752345e": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x47484f2047534d203436323620737461746155534443204f7261636c65537761" + }, + "0xe014d1acee717650c993d6a7ea1e69d4a8c7cd454d43815d9e3f22fbf752345f": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x70467265657a6572000000000000000000000000000000000000000000000000" + } + } + }, + "0x3a3868898305f04bec7fea77becff04c13444112": { + "label": null, + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000037": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x00000000000000000000000006fbde909b43f01202e3c6207de1d27cc208acc1" + }, + "0x0000000000000000000000000000000000000000000000000000000000000038": { + "previousValue": "0x00000000000000000000000000000000000000000000000000002d79883d2000", + "newValue": "0x0000000000000000000022936bfae8f3000000000000000000002d79883d2000" + }, + "0x0000000000000000000000000000000000000000000000000000000000000039": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x17432191da64676ffc2c93627ec0487305690d366637a77bff078efb3d6ab107": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "0x54aa8ce151e8da021b9dde749b7107b580f1ed706eedfb4b672c505e334672f7": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "0xa5871918c6346c7bd648c060659e3180d091571857cea690f38eb10724ec2109": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + } + }, + "0x40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f": { + "label": "AaveV3Ethereum.ASSETS.GHO.UNDERLYING, AaveV3EthereumLido.ASSETS.GHO.UNDERLYING, GhoEthereum.GHO_TOKEN, UmbrellaEthereum.UMBRELLA_STAKE_ASSETS.STK_GHO_V1.UNDERLYING", + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000002": { + "previousValue": "0x0000000000000000000000000000000000000000016a674f2ab268e844e12000", + "newValue": "0x0000000000000000000000000000000000000000018c383207f170a03f000000" + }, + "0x0000000000000000000000000000000000000000000000000000000000000008": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000005" + }, + "0x03d9388f3e045e1053b73eca46cb3169b44db9fcb54d5b7c90fec3c4514cfe2f": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000006", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + "0x09454ce099cbd30cf073b5e20499981064e7c9f62a2cba06771953710b938e7d": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + "0x0cf6c0e03008c3bebfd72d8c571bf6e20559c65f10f09fc70658e709f7200661": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x10c481845f6bd8574866d85e4b9349442e2472a0c0114168db07cab9a1718c03": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x00000000000000000000000000000000000000000021c65f7533ee93dc646000" + }, + "0x1a9ee732f525a7c8a2038e874994a6edfba7aa65fcc6af45b3a169251e5424f7": { + "previousValue": "0x000000000024315ed4c760ba00a6c000000000000031a17e847807b1bc000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x1a9ee732f525a7c8a2038e874994a6edfba7aa65fcc6af45b3a169251e5424f8": { + "previousValue": "0x47534d2034363236207374617461555344430000000000000000000000000024", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x2c15592d2493968dfe0487341abeb42c2bdbed7a1428461e5ea5d85443a16d8d": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000003", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x2e6a1a5205def75aa5a1020ea39f6d3837fdf832a97cb3d54bb950fd745ad492": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x3107e6fb53c93683833e8824cc59e9c9f27821bf7d710a977a825c1959995195": { + "previousValue": "0x000000000000000000000000000000000000000000003e90e52d4d71ed0e8537", + "newValue": "0x00000000000000000000000000000000000000000000491f0e37d85d2b7d1837" + }, + "0x6aef63ee11073e7a3a7aba77fefc95f331f2f8199fd68c9b0c802b58e3fd3532": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000004", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x72230c738511913814bdd026bfa2c17ee999c70120b23b41d8860cadf9686b25": { + "previousValue": "0x00000000000000000000000000000000000000000000000ac0ff71c720b41300", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x8091aa93ce847a0e85ab3885c1eb272ccd904aa67d4b269f68a493806a8aca26": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x89f4444109b1ce2fe5265477fa09b0f44061c82a9ba98ba4e60d1136a0dfc015": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x97703fc8d333e3ecaf9971d3c5625cf418f784e5809e649c5e588f7a46c4533a": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xc56a1d3766776e80b38811b7c013168a535b3c2cb5ae579e110a7ec029f76c57": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xd1cdfb08723fbaf3cf50623629284330883626b5388626c8278335dfa1afbc06": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000464f733baa0ae6750000000000000000464f733baa0ae675000000" + }, + "0xd1cdfb08723fbaf3cf50623629284330883626b5388626c8278335dfa1afbc07": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000047" + }, + "0xda6ffa25f1185c4c569c2121d468bfd50bb3c26102b3c85374f6b6e48022585c": { + "previousValue": "0x0000000000004d3189a3a2747a3a600000000000001cf389cd46047d03000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xda6ffa25f1185c4c569c2121d468bfd50bb3c26102b3c85374f6b6e48022585d": { + "previousValue": "0x47534d2034363236207374617461555344540000000000000000000000000024", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xeb77986abe42f20ea78965761c9ea34bf2a0686d955e404a032487df9c2f0d7a": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x4f776e61626c65466163696c697461746f722047686f2047534d73204d61696e" + }, + "0xeb77986abe42f20ea78965761c9ea34bf2a0686d955e404a032487df9c2f0d7b": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x6e65740000000000000000000000000000000000000000000000000000000000" + }, + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee5": { + "previousValue": "0x000000000000000000000000535b2f7c20b9c83d70e519cf9991578ef9816b7b", + "newValue": "0x000000000000000000000000e10c78a3ac7f016ed2de1a89c5479b1039eab9ea" + }, + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee6": { + "previousValue": "0x000000000000000000000000feeb6fe430b7523fef2a38327241ee7153779535", + "newValue": "0x000000000000000000000000616aee98f73c79fe59548cfe7631c0badbda3165" + }, + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee8": { + "previousValue": "0x000000000000000000000000e10c78a3ac7f016ed2de1a89c5479b1039eab9ea", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xf3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee9": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + } + }, + "0x46aa1063e5265b43663e81329333b47c517a5409": { + "label": "GhoEthereum.GHO_BUCKET_STEWARD", + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000003": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000005", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000004" + }, + "0x05fbc94f3250049d3e9dfe0bfa28daaf380571d1da3365b93adc37afa759355c": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "0x2097943567ccab03484397b1f46a753d482e50a171960efebb9e11a0c19ed9b8": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000002", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x272ad2dcc0ae203f11abc389e9cd9d26a6a9f9b4d0b1d382899a7c8de70ff05b": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000003", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x28ee76ea4cea4b8b4dc0099793457d158c93003da09f2d69858b9bca8cf80bb0": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000005", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000002" + }, + "0x521f025d7969ed440c86f631cf342e8d12982d2e90271160bb39c7bcfe746a68": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x64bb3e373fee954cecb4f64f5b1022cb4994bb699bc5e9f1a2ad7f7a9cae8f35": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000003" + }, + "0x8e7953a60bc64b776c3fba21ac81fb1165bb1b9c205022d1f189eb1e8a9c46db": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c": { + "previousValue": "0x000000000000000000000000535b2f7c20b9c83d70e519cf9991578ef9816b7b", + "newValue": "0x000000000000000000000000e10c78a3ac7f016ed2de1a89c5479b1039eab9ea" + }, + "0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85d": { + "previousValue": "0x000000000000000000000000feeb6fe430b7523fef2a38327241ee7153779535", + "newValue": "0x000000000000000000000000616aee98f73c79fe59548cfe7631c0badbda3165" + }, + "0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85f": { + "previousValue": "0x000000000000000000000000e10c78a3ac7f016ed2de1a89c5479b1039eab9ea", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f860": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + } + }, + "0x514910771af9ca656af840dff83e8264ecf986ca": { + "label": "AaveV2Ethereum.ASSETS.LINK.UNDERLYING, AaveV3Ethereum.ASSETS.LINK.UNDERLYING", + "balanceDiff": null, + "stateDiff": { + "0x040e85d679fc53ac947a4a6f5511069b612a8826774610b23ba6efc6f54bf488": { + "previousValue": "0x000000000000000000000000000000000000000000000b0635fee254f0cb1800", + "newValue": "0x000000000000000000000000000000000000000000000b0ee271129d8f4b1800" + }, + "0x5c582b08904103541653438b3e840fa055a8ca147282c09b21a925650db28c07": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x7f08dda3d3cd2857722336f88d3b3c9ed09b910cb3e5757c24e935c7ea336b33": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x8cc09dda3ba4cb8121665ea86c158dfc87a15a09a005d2743dcdc05bd7e960da": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x90dd2d19bc9ac5a445da688e434e69aa0f18fa4d13a44ffdf6c19d740d2715ed": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xdae4082b17861c7d82e21b4a4c7bb9fa7ad9df1c0133f315d870700d9f955f7e": { + "previousValue": "0x0000000000000000000000000000000000000000000b08b32ecf771ecfa76aa1", + "newValue": "0x0000000000000000000000000000000000000000000b08aa825d46d631276aa1" + }, + "0xfc403c4b89a2cdf463af8e36426617fcff737ccf5f9c4093be66f882051b9ca7": { + "previousValue": "0x0000000000000000000000000000000000000000000000000f4405445360a000", + "newValue": "0x0000000000000000000000000000000000000000000000000f4405445360a000" + } + } + }, + "0x535b2f7c20b9c83d70e519cf9991578ef9816b7b": { + "label": "GhoEthereum.GSM_USDT", + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000037": { + "previousValue": "0x000000000000000000000000fdb0090a92d20ee39d82ac680477b1f58f0a23de", + "newValue": "0x000000000000000000000100fdb0090a92d20ee39d82ac680477b1f58f0a23de" + }, + "0x0000000000000000000000000000000000000000000000000000000000000038": { + "previousValue": "0x00000000000000000000004a0eb44b380000000000000000000016bcc41e9000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x0000000000000000000000000000000000000000000000000000000000000039": { + "previousValue": "0x00000000000000000000000000000000000000000000000ac0ff71c720b41300", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x54aa8ce151e8da021b9dde749b7107b580f1ed706eedfb4b672c505e334672f7": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x96beb32a9f918673c243821111bf0d7eb1d8bbd6dd12a369f2a5588b5051db40": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xa5871918c6346c7bd648c060659e3180d091571857cea690f38eb10724ec2109": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + } + }, + "0x5e8c8a7243651db1384c0ddfdbe39761e8e7e51a": { + "label": "AaveV3Ethereum.ASSETS.LINK.A_TOKEN", + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000036": { + "previousValue": "0x0000000000000000000000000000000000000000000ba6b7a4dfdd7bfc1a181a", + "newValue": "0x0000000000000000000000000000000000000000000ba6aefa3d616f20cc1d3e" + }, + "0x14a553e31736f19e3e380cf55bfb2f82dfd6d880cd07235affb68d8d3e0cac4d": { + "previousValue": "0x00000000033bdac3c7b19824a8e13fef0000000000000920b994d2a6ba28f75c", + "newValue": "0x00000000033bdb1efdcafcd637c0ab0600000000000009180ef25699dedafc80" + }, + "0x7a79d58a6c2c4214189d78e4be4ba21513d55fd0a4b2ac0c119b9394eb289d20": { + "previousValue": "0x00000000033bd97abc22834a5d93f32c00000000000000000000000000000000", + "newValue": "0x00000000033bdb1efdcafcd637c0ab0600000000000000000000000000000000" + } + } + }, + "0x6593c7de001fc8542bb1703532ee1e5aa0d458fd": { + "label": null, + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000002": { + "previousValue": "0x00000000000000000000000000000000000000000000000000000000000000c6", + "newValue": "0x00000000000000000000000000000000000000000000000000000000000000c6" + }, + "0x0000000000000000000000000000000000000000000000000000000000000014": { + "previousValue": "0x015b184c0000000600000172009896800098968000000000476b78c56f0236dd", + "newValue": "0x015b184c0000000600000174009896800098968000000000476b78c56f0236dd" + }, + "0x0000000000000000000000000000000000000000000000000000000000000018": { + "previousValue": "0x000000000000000000000000000000000000000000000b030613f5ee8b02e400", + "newValue": "0x000000000000000000000000000000000000000000000b0bb28626372982e400" + }, + "0x0093128db0c7ff54c54c6d3dbd7313a496dc80614195b78168145913088f070d": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x0fd06cf9da9bc33d802c0e35c402c5a35d17f72b6fa3e428d13fa1e8d435c4b7": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x2b513b5ab089b470b4d0a77b1252a9d56e768c174a9e4a9e54099e8a2546f25d": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000050", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x2d0d87e5f6758d48bdf23bcc25877d2af0e9346c58afbbf98295e5fe1a5c6279": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000051" + }, + "0x33ce4bfc6c10154c4d24f0c40836e0e313f7e086c8ac220eb261d0ba9726ccd3": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000051", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x35fb890194fd26efbfafd081a276fa7c8aeebce79c7a5aed2d1cfda46ee45c18": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000001cdf8879ec8be012ba959eb515b11008e0cb6323" + }, + "0x3dbaf812c329f5bd8ca5f3ccb3ffa8d07f5c77423d7e882bbcfb0711aca91080": { + "previousValue": "0x000000eb5364d2650602e0ecb2d808cb34291fbaa6b38bffffffff000249f000", + "newValue": "0x000000eb5364d2650602e0ecb2d808cb34291fbaa6b38b016b07e2000249f000" + }, + "0x3dbaf812c329f5bd8ca5f3ccb3ffa8d07f5c77423d7e882bbcfb0711aca91081": { + "previousValue": "0x000000000000000000000004563918244f400000000000000000000000000000", + "newValue": "0x000000000000000000000004563918244f400000000000000000000000000000" + }, + "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5b1d": { + "previousValue": "0xbc435e2200000000000000000000000078be4ce93df4bfe609f30aec506a2a3f", + "newValue": "0xbc6febfb000000000000000000000000c71839010f4cc74f5517ba71c4f474fd" + }, + "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5b1e": { + "previousValue": "0xfa1682db000000000000000000000000a526e27103da59d6b9083cfaadd2aa97", + "newValue": "0x960e7aa200000000000000000000000044bc9f19bd2cfdfc1e4a6513bac76e7c" + }, + "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5b94": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5b95": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x44cff7e646b2ce8ad4473e17c4f56a5c541aa5edc10395b745b9edf321875327": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x5732e9e7c62ac5deedf89f6c3025222d41c0f8409822fe3516dc0cdc538e6d3e": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x000000f0a43aeca27b7cc4d01b2d19eaa0b0e562ac4432ffffffff000249f000" + }, + "0x5732e9e7c62ac5deedf89f6c3025222d41c0f8409822fe3516dc0cdc538e6d3f": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x000000000000000000000004563918244f400000000000000000000000000000" + }, + "0x7b29e5e9afc219c6f9e500a7701322b586b00074a91559b604debc7b178c7273": { + "previousValue": "0x000000163542bfd1e8484fad8b790d84acb958a6ef0063ffffffff000249f000", + "newValue": "0x000000163542bfd1e8484fad8b790d84acb958a6ef0063016b07e2000249f000" + }, + "0x7b29e5e9afc219c6f9e500a7701322b586b00074a91559b604debc7b178c7274": { + "previousValue": "0x000000000000000000000004563918244f400000000000000000000000000000", + "newValue": "0x000000000000000000000004563918244f400000000000000000000000000000" + }, + "0x902532e56011bc0fba60217becdfc61b021f29675c400dbd4ec55f021d68a575": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x98dd5aa140ea8e2838d0877604fe734e14c744f1b367e70e5cc4d523a851b00b": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000001cdf8879ec8be012ba959eb515b11008e0cb6323" + }, + "0x9cf5a70f61a8e2625b2b2c34d4217d808e8aa99a4fd4c83e2d07dcc081d20a62": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xb1a4bc465a4ffb0e6ae4ebeedd020df19964db0c54942e6c606f723b58d787d0": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000050" + }, + "0xc9140bf4673d2d401969161656f5cbfb50ae6d2c4af77f450d01f3167c3cbb6f": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x00000097c1a8c3c66145ca9e44193cd195d3b8402c7454ffffffff000249f000" + }, + "0xc9140bf4673d2d401969161656f5cbfb50ae6d2c4af77f450d01f3167c3cbb70": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x000000000000000000000004563918244f400000000000000000000000000000" + }, + "0xcdcacbeb66e04a3e7e5d794c2dab8aab85c6c0ca621013579c5b75ce409304af": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + } + }, + "0x6b0b234fb2f380309d47a7e9391e29e9a179395a": { + "label": null, + "balanceDiff": null, + "stateDiff": { + "0x3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff": { + "previousValue": "0x00000000000000000000000000000000000000000000000000016b000001f402", + "newValue": "0x00000000000000000000000000000000000000000000000000016d000001f402" + } + } + }, + "0x7bc3485026ac48b6cf9baf0a377477fff5703af8": { + "label": "AaveV3Ethereum.ASSETS.USDT.STATA_TOKEN, UmbrellaEthereum.UMBRELLA_STAKE_ASSETS.STK_WA_USDT_V1.UNDERLYING", + "balanceDiff": null, + "stateDiff": { + "0x31faaccc375cc214196213bd298e4f0b16d02b9261eb8049291f7b503901f2c6": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x8a9e78ddfbf6d2a4af644b0cf4225a94044642138c9d0cc1fe9bd89862245737": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000004a0eb44b38" + }, + "0x9122bd855985a3c7cfbf9d556c367bb50abf50fbc5944a2338c4d0d1354b80f0": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xb540c10f497cadd54cd6ccbbbc37d9ab3ec9b246cc8b739a5b77571356826e4c": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xe750561995e89789531401672a1dd49263950ab9ebb4004352b5544b182c8d40": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000004a0eb44b38", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + } + }, + "0x87870bca3f3fd6335c3f4ce8392d69350b4fa4e2": { + "label": "AaveV3Ethereum.POOL", + "balanceDiff": null, + "stateDiff": { + "0x171656ac53fe6b4f4afb5485494f9f0ac15c89bb5b5e4dc8918a7e575ea6701e": { + "previousValue": "0x0000000000004c22bdd227f7c774112200000000033bdb1e87fb25aca1b2aaa3", + "newValue": "0x0000000000004c2330f3154f79faf68c00000000033bdb1efdcafcd637c0ab06" + }, + "0x171656ac53fe6b4f4afb5485494f9f0ac15c89bb5b5e4dc8918a7e575ea6701f": { + "previousValue": "0x000000000006ea90f3a3fd74d76c1f7b000000000343c0f4b290598493288f3f", + "newValue": "0x000000000006ea962e5060c35fb057e5000000000343c0ff8076b794403993f4" + }, + "0x171656ac53fe6b4f4afb5485494f9f0ac15c89bb5b5e4dc8918a7e575ea67020": { + "previousValue": "0x0000000000000000000005006916073300000000000000002cf6b739ecb2a3e6", + "newValue": "0x00000000000000000000050069160a1b00000000000000002cf6b739ecb2a3e6" + }, + "0x171656ac53fe6b4f4afb5485494f9f0ac15c89bb5b5e4dc8918a7e575ea67025": { + "previousValue": "0x00000000000b08b320ea83ed366a3df50000000000000000be33b3918a47b011", + "newValue": "0x00000000000b08aa747853a497ea3df50000000000000000be9dd1a3e77b4b8e" + }, + "0xf9829112cce780d4a61051cb8a0049abd16e5ef129bad968336a15bba07c032d": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000020082", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000020082" + } + } + }, + "0x882285e62656b9623af136ce3078c6bdcc33f5e3": { + "label": null, + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000037": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x00000000000000000000000006fbde909b43f01202e3c6207de1d27cc208acc1" + }, + "0x0000000000000000000000000000000000000000000000000000000000000038": { + "previousValue": "0x000000000000000000000000000000000000000000000000000016bcc41e9000", + "newValue": "0x00000000000000000000004a0eb44b380000000000000000000016bcc41e9000" + }, + "0x0000000000000000000000000000000000000000000000000000000000000039": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x256791fc162d0ef0425e4db36f9700c32945f3cdef0a422d074e1207855afd2b": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "0x54aa8ce151e8da021b9dde749b7107b580f1ed706eedfb4b672c505e334672f7": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001" + }, + "0xa5871918c6346c7bd648c060659e3180d091571857cea690f38eb10724ec2109": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000001" + } + } + }, + "0x97c1a8c3c66145ca9e44193cd195d3b8402c7454": { + "label": null, + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000000": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000006593c7de001fc8542bb1703532ee1e5aa0d458fd" + } + } + }, + "0xd4fa2d31b7968e448877f69a96de69f5de8cd23e": { + "label": "AaveV3Ethereum.ASSETS.USDC.STATA_TOKEN, UmbrellaEthereum.UMBRELLA_STAKE_ASSETS.STK_WA_USDC_V1.UNDERLYING", + "balanceDiff": null, + "stateDiff": { + "0x31faaccc375cc214196213bd298e4f0b16d02b9261eb8049291f7b503901f2c6": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x6d20f148af33124b76db305d69e5583a5ec8085b648b88967fdfdb8186486501": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x000000000000000000000000000000000000000000000000000022936bfae8f3" + }, + "0x8a3e4ecf95aec2d65a3582c4b817031187cc8dbe2690fd106b9323962cba0e48": { + "previousValue": "0x000000000000000000000000000000000000000000000000000022936bfae8f3", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x9122bd855985a3c7cfbf9d556c367bb50abf50fbc5944a2338c4d0d1354b80f0": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xbafbd2f53107799460aa5af00e7f9240fa10fe08cdc121338eb9e8c77d571ddc": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + } + }, + "0xdabad81af85554e9ae636395611c58f7ec1aaec5": { + "label": "GovernanceV3Ethereum.PAYLOADS_CONTROLLER", + "balanceDiff": null, + "stateDiff": { + "0x32e830cc2d99bcd03a6b00de44c079172fc1615142526593da9060da4afbf6cd": { + "previousValue": "0x0069160a1a000000000002000000000000000000000000000000000000000000", + "newValue": "0x0069160a1a000000000003000000000000000000000000000000000000000000" + }, + "0x32e830cc2d99bcd03a6b00de44c079172fc1615142526593da9060da4afbf6ce": { + "previousValue": "0x000000000000000000093a8000000000000069442e9b00000000000000000000", + "newValue": "0x000000000000000000093a8000000000000069442e9b00000000000069160a1b" + } + } + }, + "0xf0a43aeca27b7cc4d01b2d19eaa0b0e562ac4432": { + "label": null, + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000000": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000006593c7de001fc8542bb1703532ee1e5aa0d458fd" + } + } + }, + "0xfeeb6fe430b7523fef2a38327241ee7153779535": { + "label": "GhoEthereum.GSM_USDC", + "balanceDiff": null, + "stateDiff": { + "0x0000000000000000000000000000000000000000000000000000000000000037": { + "previousValue": "0x00000000000000000000000006fbde909b43f01202e3c6207de1d27cc208acc1", + "newValue": "0x00000000000000000000010006fbde909b43f01202e3c6207de1d27cc208acc1" + }, + "0x0000000000000000000000000000000000000000000000000000000000000038": { + "previousValue": "0x0000000000000000000022936bfae8f3000000000000000000002d79883d2000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x54aa8ce151e8da021b9dde749b7107b580f1ed706eedfb4b672c505e334672f7": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0x96beb32a9f918673c243821111bf0d7eb1d8bbd6dd12a369f2a5588b5051db40": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000000", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + }, + "0xa5871918c6346c7bd648c060659e3180d091571857cea690f38eb10724ec2109": { + "previousValue": "0x0000000000000000000000000000000000000000000000000000000000000001", + "newValue": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + } + } + } +} +``` \ No newline at end of file diff --git a/src/20251113_AaveV3Ethereum_GSMMigration/AaveV3Ethereum_GSMMigration_20251113.sol b/src/20251113_AaveV3Ethereum_GSMMigration/AaveV3Ethereum_GSMMigration_20251113.sol new file mode 100644 index 000000000..98d349615 --- /dev/null +++ b/src/20251113_AaveV3Ethereum_GSMMigration/AaveV3Ethereum_GSMMigration_20251113.sol @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol'; +import {SafeERC20} from 'openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol'; +import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; +import {GhoEthereum} from 'aave-address-book/GhoEthereum.sol'; +import {MiscEthereum} from 'aave-address-book/MiscEthereum.sol'; +import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; +import {CollectorUtils, ICollector} from 'aave-helpers/src/CollectorUtils.sol'; +import {IProposalGenericExecutor} from 'aave-helpers/src/interfaces/IProposalGenericExecutor.sol'; + +import {IGhoBucketSteward} from 'src/interfaces/IGhoBucketSteward.sol'; +import {IGhoToken} from 'src/interfaces/IGhoToken.sol'; +import {IGsm} from 'src/interfaces/IGsm.sol'; +import {IGsmRegistry} from 'src/interfaces/IGsmRegistry.sol'; +import {IAaveCLRobotOperator} from 'src/interfaces/IAaveCLRobotOperator.sol'; +import {IOwnableFacilitator} from 'src/interfaces/IOwnableFacilitator.sol'; +import {IGhoReserve} from 'src/interfaces/IGhoReserve.sol'; + +/** + * @title GSM Migration + * @author @TokenLogic + * - Snapshot: https://snapshot.box/#/s:aavedao.eth/proposal/0xeb3572580924976867073ad9c8012cb9e52093c76dafebd7d3aebf318f2576fb + * - Discussion: https://governance.aave.com/t/arfc-launch-gho-on-plasma-set-aci-as-emissions-manager-for-rewards/22994/8 + */ +contract AaveV3Ethereum_GSMMigration_20251113 is IProposalGenericExecutor { + using SafeERC20 for IERC20; + using CollectorUtils for ICollector; + + // OwnableFacilitator Constants + address public constant OWNABLE_FACILITATOR = 0x616AEe98F73C79FE59548Cfe7631c0baDBdA3165; + string public constant OWNABLE_FACILITATOR_NAME = 'OwnableFacilitator Gho GSMs Mainnet'; + uint128 public constant OWNABLE_FACILITATOR_CAPACITY = 85_000_000 ether; + + // GhoReserve + // https://etherscan.io/address/0x0b0C0d8346F69EE94D29405f5630fc883A1052ab + address public constant GHO_RESERVE = 0x0b0C0d8346F69EE94D29405f5630fc883A1052ab; + + // GSM Draw Limits + uint128 public constant USDC_GSM_RESERVE_LIMIT = 55_000_000 ether; + uint128 public constant USDT_GSM_RESERVE_LIMIT = 30_000_000 ether; + + // https://etherscan.io/address/0x3a3868898305f04bec7fea77becff04c13444112 + address public constant NEW_GSM_USDC = 0x3A3868898305f04beC7FEa77BecFf04C13444112; + + // https://etherscan.io/address/0x6e51936e0ED4256f9dA4794B536B619c88Ff0047 + address public constant USDC_ORACLE_SWAP_FREEZER = 0x6e51936e0ED4256f9dA4794B536B619c88Ff0047; + + // https://etherscan.io/address/0x882285e62656b9623af136ce3078c6bdcc33f5e3 + address public constant NEW_GSM_USDT = 0x882285E62656b9623AF136Ce3078c6BdCc33F5E3; + + // https://etherscan.io/address/0x733AB16005c39d07FD3D9d1A350AA6768D10125b + address public constant USDT_ORACLE_SWAP_FREEZER = 0x733AB16005c39d07FD3D9d1A350AA6768D10125b; + + // https://etherscan.io/address/0x06fbDE909B43f01202E3C6207De1D27cC208AcC1 + address public constant FEE_STRATEGY = 0x06fbDE909B43f01202E3C6207De1D27cC208AcC1; + + uint96 public constant LINK_AMOUNT_ORACLE_FREEZER_KEEPER = 80 ether; + uint96 public constant TOTAL_LINK_AMOUNT_KEEPERS = LINK_AMOUNT_ORACLE_FREEZER_KEEPER * 2; // 2 GSMs + uint32 public constant KEEPER_GAS_LIMIT = 150_000; + + uint256 public constant EXISTING_ORACLE_SWAP_FREEZER_USDC = + 85153843967789017760384794934034524869526055173666527804449435339462659418687; + uint256 public constant EXISTING_ORACLE_SWAP_FREEZER_USDT = + 113117985912495124427864354142901529291134634735835568280477108198234580494999; + + bytes32 public immutable LIQUIDATOR_ROLE = IGsm(GhoEthereum.GSM_USDC).LIQUIDATOR_ROLE(); + bytes32 public immutable SWAP_FREEZER_ROLE = IGsm(GhoEthereum.GSM_USDC).SWAP_FREEZER_ROLE(); + + function execute() external { + uint256 balanceUsdc = IERC20(AaveV3EthereumAssets.USDC_STATA_TOKEN).balanceOf( + GhoEthereum.GSM_USDC + ); + uint256 balanceUsdt = IERC20(AaveV3EthereumAssets.USDT_STATA_TOKEN).balanceOf( + GhoEthereum.GSM_USDT + ); + + IGhoToken(AaveV3EthereumAssets.GHO_UNDERLYING).addFacilitator( + OWNABLE_FACILITATOR, + OWNABLE_FACILITATOR_NAME, + OWNABLE_FACILITATOR_CAPACITY + ); + + _seize(); + _grantAccess(); + _updateFeeStrategy(); + _registerOracles(); + _fund(balanceUsdc, balanceUsdt); + _revokeAccess(); + } + + function _seize() internal { + IGsm(GhoEthereum.GSM_USDC).grantRole(LIQUIDATOR_ROLE, GovernanceV3Ethereum.EXECUTOR_LVL_1); + IGsm(GhoEthereum.GSM_USDT).grantRole(LIQUIDATOR_ROLE, GovernanceV3Ethereum.EXECUTOR_LVL_1); + + IGsm(GhoEthereum.GSM_USDC).seize(); + IGsm(GhoEthereum.GSM_USDT).seize(); + } + + function _grantAccess() internal { + address[] memory vaults = new address[](1); + vaults[0] = OWNABLE_FACILITATOR; + IGhoBucketSteward(GhoEthereum.GHO_BUCKET_STEWARD).setControlledFacilitator(vaults, true); + + // Enroll GSMs as entities and set limit + IGhoReserve(GHO_RESERVE).addEntity(NEW_GSM_USDC); + IGhoReserve(GHO_RESERVE).addEntity(NEW_GSM_USDT); + + IGhoReserve(GHO_RESERVE).setLimit(NEW_GSM_USDC, USDC_GSM_RESERVE_LIMIT); + IGhoReserve(GHO_RESERVE).setLimit(NEW_GSM_USDT, USDT_GSM_RESERVE_LIMIT); + + // Add GSM Swap Freezer role to OracleSwapFreezers + IGsm(NEW_GSM_USDC).grantRole(SWAP_FREEZER_ROLE, USDC_ORACLE_SWAP_FREEZER); + IGsm(NEW_GSM_USDT).grantRole(SWAP_FREEZER_ROLE, USDT_ORACLE_SWAP_FREEZER); + IGsm(NEW_GSM_USDC).grantRole(SWAP_FREEZER_ROLE, GovernanceV3Ethereum.EXECUTOR_LVL_1); + IGsm(NEW_GSM_USDT).grantRole(SWAP_FREEZER_ROLE, GovernanceV3Ethereum.EXECUTOR_LVL_1); + + // Add GSMs to GSM Registry + IGsmRegistry(GhoEthereum.GSM_REGISTRY).addGsm(NEW_GSM_USDC); + IGsmRegistry(GhoEthereum.GSM_REGISTRY).addGsm(NEW_GSM_USDT); + + // GHO GSM Steward + IGsm(NEW_GSM_USDC).grantRole( + IGsm(NEW_GSM_USDC).CONFIGURATOR_ROLE(), + GhoEthereum.GHO_GSM_STEWARD + ); + IGsm(NEW_GSM_USDT).grantRole( + IGsm(NEW_GSM_USDT).CONFIGURATOR_ROLE(), + GhoEthereum.GHO_GSM_STEWARD + ); + } + + function _updateFeeStrategy() internal { + IGsm(NEW_GSM_USDC).updateFeeStrategy(FEE_STRATEGY); + IGsm(NEW_GSM_USDT).updateFeeStrategy(FEE_STRATEGY); + } + + function _registerOracles() internal { + uint256 withdrawnBalance = AaveV3Ethereum.COLLECTOR.withdrawFromV3( + CollectorUtils.IOInput({ + pool: address(AaveV3Ethereum.POOL), + underlying: AaveV3EthereumAssets.LINK_UNDERLYING, + amount: TOTAL_LINK_AMOUNT_KEEPERS + }), + address(this) + ); + IERC20(AaveV3EthereumAssets.LINK_UNDERLYING).forceApprove( + MiscEthereum.AAVE_CL_ROBOT_OPERATOR, + withdrawnBalance + ); + + IAaveCLRobotOperator(MiscEthereum.AAVE_CL_ROBOT_OPERATOR).register( + 'GHO GSM 4626 stataUSDC OracleSwapFreezer', + USDC_ORACLE_SWAP_FREEZER, + '', + KEEPER_GAS_LIMIT, + LINK_AMOUNT_ORACLE_FREEZER_KEEPER, + 0, + '' + ); + IAaveCLRobotOperator(MiscEthereum.AAVE_CL_ROBOT_OPERATOR).register( + 'GHO GSM 4626 stataUSDT OracleSwapFreezer', + USDT_ORACLE_SWAP_FREEZER, + '', + KEEPER_GAS_LIMIT, + uint96(withdrawnBalance) - LINK_AMOUNT_ORACLE_FREEZER_KEEPER, + 0, + '' + ); + } + + function _fund(uint256 balanceUsdc, uint256 balanceUsdt) internal { + IGsm(GhoEthereum.GSM_USDC).distributeFeesToTreasury(); + IGsm(GhoEthereum.GSM_USDT).distributeFeesToTreasury(); + + IOwnableFacilitator(OWNABLE_FACILITATOR).mint( + GHO_RESERVE, + USDC_GSM_RESERVE_LIMIT + USDT_GSM_RESERVE_LIMIT + ); + + AaveV3Ethereum.COLLECTOR.transfer( + IERC20(AaveV3EthereumAssets.USDC_STATA_TOKEN), + address(this), + balanceUsdc + ); + AaveV3Ethereum.COLLECTOR.transfer( + IERC20(AaveV3EthereumAssets.USDT_STATA_TOKEN), + address(this), + balanceUsdt + ); + + IERC20(AaveV3EthereumAssets.USDC_STATA_TOKEN).forceApprove(NEW_GSM_USDC, balanceUsdc); + IERC20(AaveV3EthereumAssets.USDT_STATA_TOKEN).forceApprove(NEW_GSM_USDT, balanceUsdt); + + (, uint256 amountGhoUsdc) = IGsm(NEW_GSM_USDC).sellAsset(balanceUsdc, address(this)); + (, uint256 amountGhoUsdt) = IGsm(NEW_GSM_USDT).sellAsset(balanceUsdt, address(this)); + + (, uint256 ghoUsdcNeeded) = IGhoToken(GhoEthereum.GHO_TOKEN).getFacilitatorBucket( + GhoEthereum.GSM_USDC + ); + (, uint256 ghoUsdtNeeded) = IGhoToken(GhoEthereum.GHO_TOKEN).getFacilitatorBucket( + GhoEthereum.GSM_USDT + ); + + uint256 acquiredGho = amountGhoUsdc + amountGhoUsdt; + uint256 mintedGho = ghoUsdcNeeded + ghoUsdtNeeded; + + if (mintedGho > acquiredGho) { + AaveV3Ethereum.COLLECTOR.transfer( + IERC20(GhoEthereum.GHO_TOKEN), + address(this), + mintedGho - acquiredGho + ); + } + + IERC20(GhoEthereum.GHO_TOKEN).forceApprove(GhoEthereum.GSM_USDC, ghoUsdcNeeded); + IERC20(GhoEthereum.GHO_TOKEN).forceApprove(GhoEthereum.GSM_USDT, ghoUsdtNeeded); + + IGsm(GhoEthereum.GSM_USDC).burnAfterSeize(ghoUsdcNeeded); + IGsm(GhoEthereum.GSM_USDT).burnAfterSeize(ghoUsdtNeeded); + + // Send to collector any positive difference + IERC20(GhoEthereum.GHO_TOKEN).transfer( + address(AaveV3Ethereum.COLLECTOR), + IERC20(GhoEthereum.GHO_TOKEN).balanceOf(address(this)) + ); + } + + function _revokeAccess() internal { + // Remove existing GSMs as GHO Facilitators + IGhoToken(GhoEthereum.GHO_TOKEN).removeFacilitator(GhoEthereum.GSM_USDC); + IGhoToken(GhoEthereum.GHO_TOKEN).removeFacilitator(GhoEthereum.GSM_USDT); + + // Revoke existing GSMs + address[] memory revokedVaults = new address[](2); + revokedVaults[0] = GhoEthereum.GSM_USDC; + revokedVaults[1] = GhoEthereum.GSM_USDT; + IGhoBucketSteward(GhoEthereum.GHO_BUCKET_STEWARD).setControlledFacilitator( + revokedVaults, + false + ); + + // Remove existing GSMs from Registry + IGsmRegistry(GhoEthereum.GSM_REGISTRY).removeGsm(GhoEthereum.GSM_USDC); + IGsmRegistry(GhoEthereum.GSM_REGISTRY).removeGsm(GhoEthereum.GSM_USDT); + + // Revoke Roles + IGsm(GhoEthereum.GSM_USDC).revokeRole( + SWAP_FREEZER_ROLE, + GhoEthereum.GSM_USDC_ORACLE_SWAP_FREEZER + ); + IGsm(GhoEthereum.GSM_USDT).revokeRole( + SWAP_FREEZER_ROLE, + GhoEthereum.GSM_USDT_ORACLE_SWAP_FREEZER + ); + IGsm(GhoEthereum.GSM_USDC).revokeRole(SWAP_FREEZER_ROLE, GovernanceV3Ethereum.EXECUTOR_LVL_1); + IGsm(GhoEthereum.GSM_USDT).revokeRole(SWAP_FREEZER_ROLE, GovernanceV3Ethereum.EXECUTOR_LVL_1); + + IGsm(GhoEthereum.GSM_USDC).revokeRole(LIQUIDATOR_ROLE, GovernanceV3Ethereum.EXECUTOR_LVL_1); + IGsm(GhoEthereum.GSM_USDT).revokeRole(LIQUIDATOR_ROLE, GovernanceV3Ethereum.EXECUTOR_LVL_1); + + // GHO GSM Steward + IGsm(GhoEthereum.GSM_USDC).revokeRole( + IGsm(GhoEthereum.GSM_USDC).CONFIGURATOR_ROLE(), + GhoEthereum.GHO_GSM_STEWARD + ); + IGsm(GhoEthereum.GSM_USDT).revokeRole( + IGsm(GhoEthereum.GSM_USDT).CONFIGURATOR_ROLE(), + GhoEthereum.GHO_GSM_STEWARD + ); + + // Cancel existing keepers + IAaveCLRobotOperator(MiscEthereum.AAVE_CL_ROBOT_OPERATOR).cancel( + EXISTING_ORACLE_SWAP_FREEZER_USDC + ); + IAaveCLRobotOperator(MiscEthereum.AAVE_CL_ROBOT_OPERATOR).cancel( + EXISTING_ORACLE_SWAP_FREEZER_USDT + ); + + // Manually withdraw LINK from existing keepers permissionesly ~20 blocks after cancel + } +} diff --git a/src/20251113_AaveV3Ethereum_GSMMigration/AaveV3Ethereum_GSMMigration_20251113.t.sol b/src/20251113_AaveV3Ethereum_GSMMigration/AaveV3Ethereum_GSMMigration_20251113.t.sol new file mode 100644 index 000000000..b7d2e05cf --- /dev/null +++ b/src/20251113_AaveV3Ethereum_GSMMigration/AaveV3Ethereum_GSMMigration_20251113.t.sol @@ -0,0 +1,622 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol'; +import {IERC4626} from 'openzeppelin-contracts/contracts/interfaces/IERC4626.sol'; +import {IAaveOracle} from 'aave-address-book/AaveV2.sol'; +import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol'; +import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; +import {GhoEthereum} from 'aave-address-book/GhoEthereum.sol'; +import {ProtocolV3TestBase} from 'aave-helpers/src/ProtocolV3TestBase.sol'; +import {IGhoToken} from 'src/interfaces/IGhoToken.sol'; +import {IGsm} from 'src/interfaces/IGsm.sol'; +import {IGsmFeeStrategy} from 'src/interfaces/IGsmFeeStrategy.sol'; +import {IGsmRegistry} from 'src/interfaces/IGsmRegistry.sol'; +import {IGsmSteward} from 'src/interfaces/IGsmSteward.sol'; +import {IGhoBucketSteward} from 'src/interfaces/IGhoBucketSteward.sol'; +import {IAaveCLRobotOperator} from 'src/interfaces/IAaveCLRobotOperator.sol'; +import {IGhoReserve} from 'src/interfaces/IGhoReserve.sol'; + +import {AaveV3Ethereum_GSMMigration_20251113} from './AaveV3Ethereum_GSMMigration_20251113.sol'; + +/** + * @dev Test for AaveV3Ethereum_GSMMigration_20251113 + * command: FOUNDRY_PROFILE=test forge test --match-path=src/20251113_AaveV3Ethereum_GSMMigration/AaveV3Ethereum_GSMMigration_20251113.t.sol -vv + */ +contract AaveV3Ethereum_GSMMigration_20251113_Test is ProtocolV3TestBase { + AaveV3Ethereum_GSMMigration_20251113 internal proposal; + + function setUp() public { + vm.createSelectFork(vm.rpcUrl('mainnet'), 23791536); + proposal = new AaveV3Ethereum_GSMMigration_20251113(); + } + + /** + * @dev executes the generic test suite including e2e and config snapshots + */ + function test_defaultProposalExecution() public { + defaultTest('AaveV3Ethereum_GSMMigration_20251113', AaveV3Ethereum.POOL, address(proposal)); + } + function test_checkConfig() public { + assertFalse( + IGhoBucketSteward(GhoEthereum.GHO_BUCKET_STEWARD).isControlledFacilitator( + proposal.OWNABLE_FACILITATOR() + ) + ); + + uint256 facilitatorListLengthBefore = IGhoToken(GhoEthereum.GHO_TOKEN) + .getFacilitatorsList() + .length; + + IGhoToken.Facilitator memory oldGsmUsdc = IGhoToken(GhoEthereum.GHO_TOKEN).getFacilitator( + GhoEthereum.GSM_USDC + ); + + IGhoToken.Facilitator memory oldGsmUsdt = IGhoToken(GhoEthereum.GHO_TOKEN).getFacilitator( + GhoEthereum.GSM_USDT + ); + + assertEq(IGhoReserve(proposal.GHO_RESERVE()).totalEntities(), 0); + + executePayload(vm, address(proposal)); + + assertTrue( + IGhoBucketSteward(GhoEthereum.GHO_BUCKET_STEWARD).isControlledFacilitator( + proposal.OWNABLE_FACILITATOR() + ) + ); + + // We replace 2 GSMs as facilitators with only the OwnableFacilitator + assertTrue( + IGhoToken(GhoEthereum.GHO_TOKEN).getFacilitatorsList().length == + facilitatorListLengthBefore - 1 + ); + + assertEq(IGhoReserve(proposal.GHO_RESERVE()).totalEntities(), 2); + + // USDC + uint256 limit = IGhoReserve(proposal.GHO_RESERVE()).getLimit(proposal.NEW_GSM_USDC()); + assertEq(limit, proposal.USDC_GSM_RESERVE_LIMIT()); + + (uint256 excess, uint256 deficit) = IGsm4626(proposal.NEW_GSM_USDC()).getCurrentBacking(); + assertEq(excess, 0); + assertEq(deficit, 0); + + // Asset price in GHO has changed from previous migration + assertApproxEqAbs( + IGhoReserve(proposal.GHO_RESERVE()).getUsed(proposal.NEW_GSM_USDC()), + oldGsmUsdc.bucketLevel, + 50_000 ether, + 'Delta for GHO needed on stataUSDC is too wide' + ); + + // USDT + limit = IGhoReserve(proposal.GHO_RESERVE()).getLimit(proposal.NEW_GSM_USDT()); + assertEq(limit, proposal.USDT_GSM_RESERVE_LIMIT()); + (excess, deficit) = IGsm4626(proposal.NEW_GSM_USDT()).getCurrentBacking(); + assertEq(excess, 0); + assertEq(deficit, 0); + + // Asset price in GHO has changed from previous migration + assertApproxEqAbs( + IGhoReserve(proposal.GHO_RESERVE()).getUsed(proposal.NEW_GSM_USDT()), + oldGsmUsdt.bucketLevel, + 2_500 ether, + 'Delta for GHO needed on stataUSDT is too wide' + ); + + // GSM USDC + GsmConfig memory gsmUsdcConfig = GsmConfig({ + sellFee: 0, // 0% + buyFee: 0.0010e4, // 0.1% + exposureCap: 50_000_000e6, + isFrozen: false, + isSeized: false, + freezerCanUnfreeze: true, + freezeLowerBound: 0.99e8, + freezeUpperBound: 1.01e8, + unfreezeLowerBound: 0.995e8, + unfreezeUpperBound: 1.005e8 + }); + _checkGsmConfig( + IGsm(proposal.NEW_GSM_USDC()), + AaveV3EthereumAssets.USDC_STATA_TOKEN, + IOracleSwapFreezer(proposal.USDC_ORACLE_SWAP_FREEZER()), + gsmUsdcConfig + ); + + // GSM USDT + GsmConfig memory gsmUsdtConfig = GsmConfig({ + sellFee: 0, // 0% + buyFee: 0.0010e4, // 0.1% + exposureCap: 25_000_000e6, + isFrozen: false, + isSeized: false, + freezerCanUnfreeze: true, + freezeLowerBound: 0.99e8, + freezeUpperBound: 1.01e8, + unfreezeLowerBound: 0.995e8, + unfreezeUpperBound: 1.005e8 + }); + _checkGsmConfig( + IGsm(proposal.NEW_GSM_USDT()), + AaveV3EthereumAssets.USDT_STATA_TOKEN, + IOracleSwapFreezer(proposal.USDT_ORACLE_SWAP_FREEZER()), + gsmUsdtConfig + ); + } + + function test_checkOldGSMsDisabled() public { + executePayload(vm, address(proposal)); + + assertTrue(IGsm(GhoEthereum.GSM_USDC).getIsSeized()); + assertTrue(IGsm(GhoEthereum.GSM_USDT).getIsSeized()); + + assertEq(IERC20(GhoEthereum.GHO_TOKEN).balanceOf(GhoEthereum.GSM_USDC), 0); + assertEq(IERC20(AaveV3EthereumAssets.USDC_STATA_TOKEN).balanceOf(GhoEthereum.GSM_USDC), 0); + + assertEq(IERC20(GhoEthereum.GHO_TOKEN).balanceOf(GhoEthereum.GSM_USDT), 0); + assertEq(IERC20(AaveV3EthereumAssets.USDT_STATA_TOKEN).balanceOf(GhoEthereum.GSM_USDT), 0); + + IGhoToken.Facilitator memory oldGsmUsdc = IGhoToken(GhoEthereum.GHO_TOKEN).getFacilitator( + GhoEthereum.GSM_USDC + ); + + assertEq(oldGsmUsdc.bucketCapacity, 0); + assertEq(oldGsmUsdc.bucketLevel, 0); + + IGhoToken.Facilitator memory oldGsmUsdt = IGhoToken(GhoEthereum.GHO_TOKEN).getFacilitator( + GhoEthereum.GSM_USDT + ); + + assertEq(oldGsmUsdt.bucketCapacity, 0); + assertEq(oldGsmUsdt.bucketLevel, 0); + + assertEq(IGsm(GhoEthereum.GSM_USDC).getAvailableUnderlyingExposure(), 0, 'wrong exposure cap'); + assertEq(IGsm(GhoEthereum.GSM_USDT).getAvailableUnderlyingExposure(), 0, 'wrong exposure cap'); + + assertFalse( + IGsm(GhoEthereum.GSM_USDC).hasRole( + proposal.SWAP_FREEZER_ROLE(), + GhoEthereum.GSM_USDC_ORACLE_SWAP_FREEZER + ) + ); + assertFalse( + IGsm(GhoEthereum.GSM_USDT).hasRole( + proposal.SWAP_FREEZER_ROLE(), + GhoEthereum.GSM_USDT_ORACLE_SWAP_FREEZER + ) + ); + assertFalse( + IGsm(GhoEthereum.GSM_USDC).hasRole( + proposal.SWAP_FREEZER_ROLE(), + GovernanceV3Ethereum.EXECUTOR_LVL_1 + ) + ); + assertFalse( + IGsm(GhoEthereum.GSM_USDT).hasRole( + proposal.SWAP_FREEZER_ROLE(), + GovernanceV3Ethereum.EXECUTOR_LVL_1 + ) + ); + assertFalse( + IGsm(GhoEthereum.GSM_USDC).hasRole( + proposal.LIQUIDATOR_ROLE(), + GovernanceV3Ethereum.EXECUTOR_LVL_1 + ) + ); + assertFalse( + IGsm(GhoEthereum.GSM_USDT).hasRole( + proposal.LIQUIDATOR_ROLE(), + GovernanceV3Ethereum.EXECUTOR_LVL_1 + ) + ); + assertFalse( + IGsm(GhoEthereum.GSM_USDC).hasRole( + IGsm(GhoEthereum.GSM_USDC).CONFIGURATOR_ROLE(), + GhoEthereum.GHO_GSM_STEWARD + ) + ); + assertFalse( + IGsm(GhoEthereum.GSM_USDT).hasRole( + IGsm(GhoEthereum.GSM_USDT).CONFIGURATOR_ROLE(), + GhoEthereum.GHO_GSM_STEWARD + ) + ); + } + + function test_oracleSwapFreezers() public { + // OracleSwapFreezers are not authorized + assertEq( + IGsm(proposal.NEW_GSM_USDC()).hasRole( + IGsm(proposal.NEW_GSM_USDC()).SWAP_FREEZER_ROLE(), + proposal.USDC_ORACLE_SWAP_FREEZER() + ), + false + ); + assertEq( + IGsm(proposal.NEW_GSM_USDT()).hasRole( + IGsm(proposal.NEW_GSM_USDT()).SWAP_FREEZER_ROLE(), + proposal.USDT_ORACLE_SWAP_FREEZER() + ), + false + ); + + IOracleSwapFreezer usdcFreezer = IOracleSwapFreezer(proposal.USDC_ORACLE_SWAP_FREEZER()); + IOracleSwapFreezer usdtFreezer = IOracleSwapFreezer(proposal.USDT_ORACLE_SWAP_FREEZER()); + (uint128 usdcFreezeLowerBound, ) = usdcFreezer.getFreezeBound(); + (uint128 usdcUnfreezeLowerBound, ) = usdcFreezer.getUnfreezeBound(); + (uint128 usdtFreezeLowerBound, ) = usdtFreezer.getFreezeBound(); + (uint128 usdtUnfreezeLowerBound, ) = usdtFreezer.getUnfreezeBound(); + + // Price outside the price range + // Freezers cannot execute freeze without authorization + _mockAssetPrice( + address(AaveV3Ethereum.ORACLE), + AaveV3EthereumAssets.USDC_UNDERLYING, + usdcFreezeLowerBound - 1 + ); + _mockAssetPrice( + address(AaveV3Ethereum.ORACLE), + AaveV3EthereumAssets.USDT_UNDERLYING, + usdtFreezeLowerBound - 1 + ); + + (bool canPerformUpkeep, ) = usdcFreezer.checkUpkeep(bytes('')); + assertEq(canPerformUpkeep, false); + usdcFreezer.performUpkeep(bytes('')); + assertEq(IGsm(proposal.NEW_GSM_USDC()).getIsFrozen(), false); + + (canPerformUpkeep, ) = usdtFreezer.checkUpkeep(bytes('')); + assertEq(canPerformUpkeep, false); + usdtFreezer.performUpkeep(bytes('')); + assertEq(IGsm(proposal.NEW_GSM_USDT()).getIsFrozen(), false); + + // Payload execution + executePayload(vm, address(proposal)); + + // Freezers are authorized now + assertEq( + IGsm(proposal.NEW_GSM_USDC()).hasRole( + IGsm(proposal.NEW_GSM_USDC()).SWAP_FREEZER_ROLE(), + proposal.USDC_ORACLE_SWAP_FREEZER() + ), + true + ); + assertEq( + IGsm(proposal.NEW_GSM_USDT()).hasRole( + IGsm(proposal.NEW_GSM_USDT()).SWAP_FREEZER_ROLE(), + proposal.USDT_ORACLE_SWAP_FREEZER() + ), + true + ); + + // Freezers freeze GSM contracts + (canPerformUpkeep, ) = usdcFreezer.checkUpkeep(bytes('')); + assertEq(canPerformUpkeep, true); + usdcFreezer.performUpkeep(bytes('')); + assertEq(IGsm(proposal.NEW_GSM_USDC()).getIsFrozen(), true); + + (canPerformUpkeep, ) = usdtFreezer.checkUpkeep(bytes('')); + assertEq(canPerformUpkeep, true); + usdtFreezer.performUpkeep(bytes('')); + assertEq(IGsm(proposal.NEW_GSM_USDT()).getIsFrozen(), true); + + // Price back to normal + _mockAssetPrice( + address(AaveV3Ethereum.ORACLE), + AaveV3EthereumAssets.USDC_UNDERLYING, + usdcUnfreezeLowerBound + 1 + ); + _mockAssetPrice( + address(AaveV3Ethereum.ORACLE), + AaveV3EthereumAssets.USDT_UNDERLYING, + usdtUnfreezeLowerBound + 1 + ); + + (canPerformUpkeep, ) = usdcFreezer.checkUpkeep(bytes('')); + assertEq(canPerformUpkeep, true); + usdcFreezer.performUpkeep(bytes('')); + assertEq(IGsm(proposal.NEW_GSM_USDC()).getIsFrozen(), false); + + (canPerformUpkeep, ) = usdtFreezer.checkUpkeep(bytes('')); + assertEq(canPerformUpkeep, true); + usdtFreezer.performUpkeep(bytes('')); + assertEq(IGsm(proposal.NEW_GSM_USDT()).getIsFrozen(), false); + } + + function test_checkRoles() public { + executePayload(vm, address(proposal)); + + _checkRolesConfig(IGsm(proposal.NEW_GSM_USDC())); + _checkRolesConfig(IGsm(proposal.NEW_GSM_USDT())); + } + + function test_oldGsmsAreSeized() public { + executePayload(vm, address(proposal)); + + // Old GSMs are seized + vm.expectRevert(bytes('GSM_SEIZED')); + IGsm(GhoEthereum.GSM_USDC).buyAsset(1000e6, address(this)); + vm.expectRevert(bytes('GSM_SEIZED')); + IGsm(GhoEthereum.GSM_USDT).buyAsset(1000e6, address(this)); + vm.expectRevert(bytes('GSM_SEIZED')); + IGsm(GhoEthereum.GSM_USDC).sellAsset(1000e6, address(this)); + vm.expectRevert(bytes('GSM_SEIZED')); + IGsm(GhoEthereum.GSM_USDT).sellAsset(1000e6, address(this)); + } + + function test_gsmUsdcIsOperational() public { + executePayload(vm, address(proposal)); + + deal(AaveV3EthereumAssets.USDC_STATA_TOKEN, address(this), 1_000e6); + + // New GSMs are operational + IERC20(AaveV3EthereumAssets.USDC_STATA_TOKEN).approve(proposal.NEW_GSM_USDC(), 1_000e6); + IERC20(AaveV3EthereumAssets.GHO_UNDERLYING).approve(proposal.NEW_GSM_USDC(), 1_200 ether); + + uint256 amountUnderlying = 1_000e6; + uint256 balanceBeforeUsdcGsm = IERC20(AaveV3EthereumAssets.USDC_STATA_TOKEN).balanceOf( + proposal.NEW_GSM_USDC() + ); + uint256 balanceGhoBefore = IGhoToken(GhoEthereum.GHO_TOKEN).balanceOf(address(this)); + + (, uint256 ghoBought) = IGsm(proposal.NEW_GSM_USDC()).sellAsset( + amountUnderlying, + address(this) + ); + + assertEq( + IERC20(AaveV3EthereumAssets.USDC_STATA_TOKEN).balanceOf(proposal.NEW_GSM_USDC()), + balanceBeforeUsdcGsm + amountUnderlying, + 'amounts USDC after sellAsset not equal' + ); + assertEq( + IGhoToken(GhoEthereum.GHO_TOKEN).balanceOf(address(this)), + balanceGhoBefore + ghoBought, + 'GHO balance after sellAsset not equal' + ); + + (, uint256 ghoSold) = IGsm(proposal.NEW_GSM_USDC()).buyAsset(500e6, address(this)); + + assertEq( + IERC20(AaveV3EthereumAssets.USDC_STATA_TOKEN).balanceOf(proposal.NEW_GSM_USDC()), + balanceBeforeUsdcGsm + amountUnderlying - 500e6, + 'stataUSDC balance after buyAsset not equal' + ); + assertEq( + IGhoToken(GhoEthereum.GHO_TOKEN).balanceOf(address(this)), + balanceGhoBefore + ghoBought - ghoSold, + 'GHO balance after buyAsset not equal' + ); + } + + function test_gsmUsdtIsOperational() public { + executePayload(vm, address(proposal)); + + deal(AaveV3EthereumAssets.USDT_STATA_TOKEN, address(this), 1_000e6); + + // New GSMs are operational + IERC20(AaveV3EthereumAssets.USDT_STATA_TOKEN).approve(proposal.NEW_GSM_USDT(), 1_000e6); + IERC20(AaveV3EthereumAssets.GHO_UNDERLYING).approve(proposal.NEW_GSM_USDT(), 1_200 ether); + + uint256 amountUnderlying = 1_000e6; + uint256 balanceBeforeUsdtGsm = IERC20(AaveV3EthereumAssets.USDT_STATA_TOKEN).balanceOf( + proposal.NEW_GSM_USDT() + ); + uint256 balanceGhoBefore = IGhoToken(GhoEthereum.GHO_TOKEN).balanceOf(address(this)); + + (, uint256 ghoBought) = IGsm(proposal.NEW_GSM_USDT()).sellAsset( + amountUnderlying, + address(this) + ); + + assertEq( + IERC20(AaveV3EthereumAssets.USDT_STATA_TOKEN).balanceOf(proposal.NEW_GSM_USDT()), + balanceBeforeUsdtGsm + amountUnderlying, + 'amounts USDT after sellAsset not equal' + ); + assertEq( + IGhoToken(GhoEthereum.GHO_TOKEN).balanceOf(address(this)), + balanceGhoBefore + ghoBought, + 'GHO balance after sellAsset not equal' + ); + + (, uint256 ghoSold) = IGsm(proposal.NEW_GSM_USDT()).buyAsset(500e6, address(this)); + + assertEq( + IERC20(AaveV3EthereumAssets.USDT_STATA_TOKEN).balanceOf(proposal.NEW_GSM_USDT()), + balanceBeforeUsdtGsm + amountUnderlying - 500e6, + 'stataUSDT balance after buyAsset not equal' + ); + assertEq( + IGhoToken(GhoEthereum.GHO_TOKEN).balanceOf(address(this)), + balanceGhoBefore + ghoBought - ghoSold, + 'GHO balance after buyAsset not equal' + ); + } + + function test_ghoGsmSteward_updateExposureCapUSDC() public { + executePayload(vm, address(proposal)); + + uint128 oldExposureCap = IGsm(proposal.NEW_GSM_USDC()).getExposureCap(); + uint128 newExposureCap = oldExposureCap + 1; + + vm.startPrank(GhoEthereum.RISK_COUNCIL); + IGsmSteward(GhoEthereum.GHO_GSM_STEWARD).updateGsmExposureCap( + proposal.NEW_GSM_USDC(), + newExposureCap + ); + uint128 currentExposureCap = IGsm(proposal.NEW_GSM_USDC()).getExposureCap(); + assertEq(currentExposureCap, newExposureCap); + } + + function test_ghoGsmSteward_updateExposureCapUSDT() public { + executePayload(vm, address(proposal)); + + uint128 oldExposureCap = IGsm(proposal.NEW_GSM_USDT()).getExposureCap(); + uint128 newExposureCap = oldExposureCap + 1; + + vm.startPrank(GhoEthereum.RISK_COUNCIL); + IGsmSteward(GhoEthereum.GHO_GSM_STEWARD).updateGsmExposureCap( + proposal.NEW_GSM_USDT(), + newExposureCap + ); + uint128 currentExposureCap = IGsm(proposal.NEW_GSM_USDT()).getExposureCap(); + assertEq(currentExposureCap, newExposureCap); + } + + function test_ghoGsmSteward_updateGsmBuySellFeesUSDC() public { + executePayload(vm, address(proposal)); + + address feeStrategy = IGsm(proposal.NEW_GSM_USDC()).getFeeStrategy(); + uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); + uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); + + vm.startPrank(GhoEthereum.RISK_COUNCIL); + IGsmSteward(GhoEthereum.GHO_GSM_STEWARD).updateGsmBuySellFees( + proposal.NEW_GSM_USDC(), + buyFee + 1, + sellFee + ); + address newStrategy = IGsm(proposal.NEW_GSM_USDC()).getFeeStrategy(); + uint256 newBuyFee = IGsmFeeStrategy(newStrategy).getBuyFee(1e4); + assertEq(newBuyFee, buyFee + 1); + } + + function test_ghoGsmSteward_updateGsmBuySellFeesUSDT() public { + executePayload(vm, address(proposal)); + + address feeStrategy = IGsm(proposal.NEW_GSM_USDT()).getFeeStrategy(); + uint256 buyFee = IGsmFeeStrategy(feeStrategy).getBuyFee(1e4); + uint256 sellFee = IGsmFeeStrategy(feeStrategy).getSellFee(1e4); + + vm.startPrank(GhoEthereum.RISK_COUNCIL); + IGsmSteward(GhoEthereum.GHO_GSM_STEWARD).updateGsmBuySellFees( + proposal.NEW_GSM_USDT(), + buyFee + 1, + sellFee + ); + address newStrategy = IGsm(proposal.NEW_GSM_USDT()).getFeeStrategy(); + uint256 newBuyFee = IGsmFeeStrategy(newStrategy).getBuyFee(1e4); + assertEq(newBuyFee, buyFee + 1); + } + + function _checkRolesConfig(IGsm gsm) internal view { + // DAO permissions + assertTrue( + gsm.hasRole(bytes32(0), GovernanceV3Ethereum.EXECUTOR_LVL_1), + 'Executor is not admin' + ); + assertTrue( + gsm.hasRole(gsm.SWAP_FREEZER_ROLE(), GovernanceV3Ethereum.EXECUTOR_LVL_1), + 'Executor is not swap freezer' + ); + assertTrue( + gsm.hasRole(gsm.CONFIGURATOR_ROLE(), GovernanceV3Ethereum.EXECUTOR_LVL_1), + 'Executor is not configurator' + ); + // No need to be liquidator or token rescuer at the beginning + assertFalse(gsm.hasRole(gsm.LIQUIDATOR_ROLE(), GovernanceV3Ethereum.EXECUTOR_LVL_1)); + assertFalse(gsm.hasRole(gsm.TOKEN_RESCUER_ROLE(), GovernanceV3Ethereum.EXECUTOR_LVL_1)); + + // Deployer does not have permissions + address deployer = 0x3765A685a401622C060E5D700D9ad89413363a91; + assertFalse(gsm.hasRole(bytes32(0), deployer), 'Deployer cannot be admin'); + assertFalse(gsm.hasRole(gsm.SWAP_FREEZER_ROLE(), deployer), 'Deployer cannot be swap freezer'); + assertFalse(gsm.hasRole(gsm.CONFIGURATOR_ROLE(), deployer), 'Deployer cannot be configurator'); + assertFalse(gsm.hasRole(gsm.LIQUIDATOR_ROLE(), deployer), 'Deployer cannot be liquidator'); + assertFalse( + gsm.hasRole(gsm.TOKEN_RESCUER_ROLE(), deployer), + 'Deployer cannot be token rescuer' + ); + + // GHO Steward + assertTrue( + gsm.hasRole(gsm.CONFIGURATOR_ROLE(), GhoEthereum.GHO_GSM_STEWARD), + 'Gho Steward not configured' + ); + } + + function _mockAssetPrice(address priceOracle, address asset, uint256 price) internal { + vm.mockCall( + priceOracle, + abi.encodeWithSelector(IAaveOracle.getAssetPrice.selector, asset), + abi.encode(price) + ); + } + + struct GsmConfig { + uint256 sellFee; + uint256 buyFee; + uint256 exposureCap; + bool isFrozen; + bool isSeized; + bool freezerCanUnfreeze; + uint256 freezeLowerBound; + uint256 freezeUpperBound; + uint256 unfreezeLowerBound; + uint256 unfreezeUpperBound; + } + + function _checkGsmConfig( + IGsm gsm, + address underlying, + IOracleSwapFreezer freezer, + GsmConfig memory config + ) internal view { + assertEq(gsm.UNDERLYING_ASSET(), underlying, 'wrong underlying asset'); + assertLt(gsm.getAvailableUnderlyingExposure(), config.exposureCap, 'wrong exposure cap'); + assertEq(gsm.getIsFrozen(), config.isFrozen, 'wrong freeze state'); + assertEq(gsm.getIsSeized(), config.isSeized, 'wrong seized state'); + + // Fee Strategy + IGsmFeeStrategy feeStrategy = IGsmFeeStrategy(gsm.getFeeStrategy()); + assertEq(feeStrategy.getSellFee(10000), config.sellFee, 'wrong sell fee'); + assertEq(feeStrategy.getBuyFee(10000), config.buyFee, 'wrong buy fee'); + + // Price Strategy + IFixedPriceStrategy4626 priceStrategy = IFixedPriceStrategy4626(gsm.PRICE_STRATEGY()); + assertEq( + IERC4626(underlying).previewMint(1e6) * 10 ** 12, + priceStrategy.getAssetPriceInGho(1e6, true) + ); + assertEq( + IERC4626(underlying).previewWithdraw(1 ether) / 10 ** 12, + priceStrategy.getGhoPriceInAsset(1 ether, false) + ); + + assertEq(gsm.getGhoTreasury(), address(AaveV3Ethereum.COLLECTOR)); + + // Oracle freezer + assertEq(freezer.getCanUnfreeze(), config.freezerCanUnfreeze, 'wrong freezer config'); + (uint256 lowerBound, uint256 upperBound) = freezer.getFreezeBound(); + assertEq(lowerBound, config.freezeLowerBound, 'wrong freeze lower bound'); + assertEq(upperBound, config.freezeUpperBound, 'wrong freeze upper bound'); + (lowerBound, upperBound) = freezer.getUnfreezeBound(); + assertEq(lowerBound, config.unfreezeLowerBound, 'wrong unfreeze lower bound'); + assertEq(upperBound, config.unfreezeUpperBound, 'wrong unfreeze upper bound'); + + assertEq(freezer.ADDRESS_PROVIDER(), address(AaveV3Ethereum.POOL_ADDRESSES_PROVIDER)); + assertEq(freezer.GSM(), address(gsm)); + } +} + +interface IOracleSwapFreezer { + function ADDRESS_PROVIDER() external view returns (address); + function GSM() external view returns (address); + function getCanUnfreeze() external view returns (bool); + function getFreezeBound() external view returns (uint128, uint128); + function getUnfreezeBound() external view returns (uint128, uint128); + function checkUpkeep(bytes calldata) external view returns (bool, bytes memory); + function performUpkeep(bytes calldata) external; +} + +interface IFixedPriceStrategy4626 { + function getAssetPriceInGho(uint256 assetAmount, bool roundUp) external view returns (uint256); + function getGhoPriceInAsset(uint256 ghoAmount, bool roundUp) external view returns (uint256); +} + +interface IGsm4626 { + function getCurrentBacking() external view returns (uint256, uint256); +} diff --git a/src/20251113_AaveV3Ethereum_GSMMigration/GSMMigration.md b/src/20251113_AaveV3Ethereum_GSMMigration/GSMMigration.md new file mode 100644 index 000000000..545f6bb22 --- /dev/null +++ b/src/20251113_AaveV3Ethereum_GSMMigration/GSMMigration.md @@ -0,0 +1,74 @@ +--- +title: "GSM Migration" +author: "@TokenLogic" +discussions: "https://governance.aave.com/t/arfc-launch-gho-on-plasma-set-aci-as-emissions-manager-for-rewards/22994/8" +snapshot: "https://snapshot.box/#/s:aavedao.eth/proposal/0xeb3572580924976867073ad9c8012cb9e52093c76dafebd7d3aebf318f2576fb" +--- + +## Simple Summary + +With the launch of what is known as the new Remote GSM, this publication updates the existing Mainnet GSMs to the new version. + +## Motivation + +To create a unified GSM paradigm for both mainnet and L2s, a newer version of the GSM has been developed. The new GSMs use and restore GHO to a DAO controlled GhoReserve that holds a predefined amount of GHO and the DAO allows entities (such as the GSMs) to draw GHO up to a predefined amount. + +## Specification + +- Deploy OwnableFacilitator to mint GHO for GSMs +- Deploy GhoReserve to hold GHO to be used by GSMs +- Deploy new stataUSDC and stataUSDT GSM4626 from the Gho-Core repository with their respective Oracles +- Grant the Executor the `'LIQUIDATOR_ROLE'` to be able to seize the existing GSMs +- Seize the current USDC and USDT GSMs by calling the `seize()` function. + - This freezes actions on them and transfers the underlying tokens to the collector +- Add the two new GSMs as facilitators on the GHO token contract +- Add the new stataUSDC and stataUSDT GSMs as controlled facilitators on the GhoBucketSteward +- Add new GSMs to the GSMRegistry +- Update the FeeStrategy of the new GSMs to the existing FeeStrategy: [`0x06fbDE909B43f01202E3C6207De1D27cC208AcC1`](https://etherscan.io/address/0x06fbDE909B43f01202E3C6207De1D27cC208AcC1) +- Register new swap freeze oracles +- With the withdrawn assets above (in the seize step), obtain stataUSDC and stataUSDT via deposit on the respective vaults +- With the obtained stataUSDC and stataUSDT, exchange for GHO on the new respective GSMs +- Use the obtained GHO to `burnAfterSeize()` on the current USDC and USDT GSMs. If there are any discrepancies in the amount of GHO, use GHO from the treasury to bring the minted GHO by the GSMs to zero +- Remove existing GSMs as facilitators of the GHO token +- Remove existing GSMs from the GSMRegistry +- Remove existing USDC and USDT GSMs from being a controlled facilitator on the GhoBucketSteward +- Revoke roles assigned to EXECUTOR and old GSMs + +The below details the configuration of the stataUSDC GSM. + +| Parameter | Value | +| ------------------------ | :----: | +| Draw Limit (GHO) | 55.00M | +| Exposure Capacity (USDC) | 50.00M | +| Price Strategy | 1:1 | +| Freeze Lower Bound | $0.990 | +| Freeze Upper Bound | $1.010 | +| Unfreeze Lower Bound | $0.995 | +| Unfreeze Upper Bound | $1.005 | +| Mint GHO Fee | 0.00% | +| Burn GHO Fee | 0.10% | + +The below details the configuration of the stataUSDT GSM. + +| Parameter | Value | +| ------------------------ | :----: | +| Draw Limit (GHO) | 30.00M | +| Exposure Capacity (USDT) | 25.00M | +| Price Strategy | 1:1 | +| Freeze Lower Bound | $0.990 | +| Freeze Upper Bound | $1.010 | +| Unfreeze Lower Bound | $0.995 | +| Unfreeze Upper Bound | $1.005 | +| Mint GHO Fee | 0.00% | +| Burn GHO Fee | 0.10% | + +## References + +- Implementation: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20251113_AaveV3Ethereum_GSMMigration/AaveV3Ethereum_GSMMigration_20251113.sol) +- Tests: [AaveV3Ethereum](https://github.com/bgd-labs/aave-proposals-v3/blob/main/src/20251113_AaveV3Ethereum_GSMMigration/AaveV3Ethereum_GSMMigration_20251113.t.sol) +- [Snapshot](https://snapshot.box/#/s:aavedao.eth/proposal/0xeb3572580924976867073ad9c8012cb9e52093c76dafebd7d3aebf318f2576fb) +- [Discussion](https://governance.aave.com/t/arfc-launch-gho-on-plasma-set-aci-as-emissions-manager-for-rewards/22994/8) + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/src/20251113_AaveV3Ethereum_GSMMigration/GSMMigration_20251113.s.sol b/src/20251113_AaveV3Ethereum_GSMMigration/GSMMigration_20251113.s.sol new file mode 100644 index 000000000..7e93c4830 --- /dev/null +++ b/src/20251113_AaveV3Ethereum_GSMMigration/GSMMigration_20251113.s.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/src/GovV3Helpers.sol'; +import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol'; + +import {EthereumScript} from 'solidity-utils/contracts/utils/ScriptUtils.sol'; +import {AaveV3Ethereum_GSMMigration_20251113} from './AaveV3Ethereum_GSMMigration_20251113.sol'; + +/** + * @dev Deploy Ethereum + * deploy-command: make deploy-ledger contract=src/20251113_AaveV3Ethereum_GSMMigration/GSMMigration_20251113.s.sol:DeployEthereum chain=mainnet + * verify-command: FOUNDRY_PROFILE=deploy npx catapulta-verify -b broadcast/GSMMigration_20251113.s.sol/1/run-latest.json + */ +contract DeployEthereum is EthereumScript { + function run() external broadcast { + // deploy payloads + address payload0 = GovV3Helpers.deployDeterministic( + type(AaveV3Ethereum_GSMMigration_20251113).creationCode + ); + + // compose action + IPayloadsControllerCore.ExecutionAction[] + memory actions = new IPayloadsControllerCore.ExecutionAction[](1); + actions[0] = GovV3Helpers.buildAction(payload0); + + // register action at payloadsController + GovV3Helpers.createPayload(actions); + } +} + +/** + * @dev Create Proposal + * command: make deploy-ledger contract=src/20251113_AaveV3Ethereum_GSMMigration/GSMMigration_20251113.s.sol:CreateProposal chain=mainnet + */ +contract CreateProposal is EthereumScript { + function run() external { + // create payloads + PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](1); + + // compose actions for validation + { + IPayloadsControllerCore.ExecutionAction[] + memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1); + actionsEthereum[0] = GovV3Helpers.buildAction( + type(AaveV3Ethereum_GSMMigration_20251113).creationCode + ); + payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum); + } + + // create proposal + vm.startBroadcast(); + GovV3Helpers.createProposal( + vm, + payloads, + GovernanceV3Ethereum.VOTING_PORTAL_ETH_AVAX, + GovV3Helpers.ipfsHashFile(vm, 'src/20251113_AaveV3Ethereum_GSMMigration/GSMMigration.md') + ); + } +} diff --git a/src/20251113_AaveV3Ethereum_GSMMigration/config.ts b/src/20251113_AaveV3Ethereum_GSMMigration/config.ts new file mode 100644 index 000000000..139454275 --- /dev/null +++ b/src/20251113_AaveV3Ethereum_GSMMigration/config.ts @@ -0,0 +1,16 @@ +import {ConfigFile} from '../../generator/types'; +export const config: ConfigFile = { + rootOptions: { + pools: ['AaveV3Ethereum'], + title: 'GSM Migration', + shortName: 'GSMMigration', + date: '20251113', + author: '@TokenLogic', + discussion: + 'https://governance.aave.com/t/arfc-launch-gho-on-plasma-set-aci-as-emissions-manager-for-rewards/22994/8', + snapshot: + 'https://snapshot.box/#/s:aavedao.eth/proposal/0xeb3572580924976867073ad9c8012cb9e52093c76dafebd7d3aebf318f2576fb', + votingNetwork: 'AVALANCHE', + }, + poolOptions: {AaveV3Ethereum: {configs: {OTHERS: {}}, cache: {blockNumber: 23791536}}}, +}; diff --git a/src/interfaces/IGhoReserve.sol b/src/interfaces/IGhoReserve.sol new file mode 100644 index 000000000..6a18d0a96 --- /dev/null +++ b/src/interfaces/IGhoReserve.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IGhoReserve { + function addEntity(address entity) external; + function setLimit(address entity, uint256 limit) external; + function getLimit(address entity) external view returns (uint256); + function getUsed(address entity) external view returns (uint256); + function isEntity(address entity) external view returns (bool); + function totalEntities() external view returns (uint256); +} diff --git a/src/interfaces/IGsmRegistry.sol b/src/interfaces/IGsmRegistry.sol index 6024d123e..52e0cf8f0 100644 --- a/src/interfaces/IGsmRegistry.sol +++ b/src/interfaces/IGsmRegistry.sol @@ -3,6 +3,5 @@ pragma solidity ^0.8.0; interface IGsmRegistry { function addGsm(address gsmAddress) external; - function removeGsm(address gsmAddress) external; } diff --git a/src/interfaces/IOwnableFacilitator.sol b/src/interfaces/IOwnableFacilitator.sol new file mode 100644 index 000000000..fd77ccd9b --- /dev/null +++ b/src/interfaces/IOwnableFacilitator.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IOwnableFacilitator { + function mint(address to, uint256 amount) external; +}