From 8b130ade8c283f081c814d164877688c50817cba Mon Sep 17 00:00:00 2001 From: Nelson Taveras <4562733+nvtaveras@users.noreply.github.com> Date: Tue, 22 Oct 2024 16:36:03 +0200 Subject: [PATCH] feat: $cCOP relayers deployment scripts (#228) --- .../42220/run-latest.json | 127 ++++++++++++ .../44787/run-latest.json | 139 +++++++++++++ .../COPWhitelist.sol/44787/run-latest.json | 133 +++++++++++++ .../44787/run-COPUSD.json | 73 +++++++ .../dev/dev-DeployMockChainlinkAggregator.sol | 4 +- .../dev-UpdateMockChainlinkAggregators.sol | 5 + script/upgrades/COPWhitelist/COPWhitelist.sol | 184 ++++++++++++++++++ .../COPWhitelist/COPWhitelistChecks.sol | 95 +++++++++ ...PWhitelist-00-Deploy-ChainlinkRelayers.sol | 97 +++++++++ script/upgrades/dependencies.json | 9 +- 10 files changed, 861 insertions(+), 5 deletions(-) create mode 100644 broadcast/COPWhitelist-00-Deploy-ChainlinkRelayers.sol/42220/run-latest.json create mode 100644 broadcast/COPWhitelist-00-Deploy-ChainlinkRelayers.sol/44787/run-latest.json create mode 100644 broadcast/COPWhitelist.sol/44787/run-latest.json create mode 100644 broadcast/dev-DeployMockChainlinkAggregator.sol/44787/run-COPUSD.json create mode 100644 script/upgrades/COPWhitelist/COPWhitelist.sol create mode 100644 script/upgrades/COPWhitelist/COPWhitelistChecks.sol create mode 100644 script/upgrades/COPWhitelist/deploy/COPWhitelist-00-Deploy-ChainlinkRelayers.sol diff --git a/broadcast/COPWhitelist-00-Deploy-ChainlinkRelayers.sol/42220/run-latest.json b/broadcast/COPWhitelist-00-Deploy-ChainlinkRelayers.sol/42220/run-latest.json new file mode 100644 index 0000000..dd63f2c --- /dev/null +++ b/broadcast/COPWhitelist-00-Deploy-ChainlinkRelayers.sol/42220/run-latest.json @@ -0,0 +1,127 @@ +{ + "transactions": [ + { + "hash": "0x454f3a7fd6dedcb6b8027ef52b195928a6a73618b1b4218649a0605afe1e56fc", + "transactionType": "CALL", + "contractName": null, + "contractAddress": "0x247Cb6ECf21bDd2Bc29d726CcCC8d2F066211663", + "function": "deployRelayer(address,string,uint256,(address,bool)[])", + "arguments": [ + "0x32ABF1cBdFdcD56790f427694be2658d4B1A83bC", + "CELO/COP (CELO/USD:USD/COP)", + "86400", + "[(0x0568fD19986748cEfF3301e55c0eb1E729E0Ab7e, false), (0x97b770B0200CCe161907a9cbe0C6B177679f8F7C, true)]" + ], + "transaction": { + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0x247Cb6ECf21bDd2Bc29d726CcCC8d2F066211663", + "gas": "0x1791b8", + "value": "0x0", + "input": "0x472a111100000000000000000000000032abf1cbdfdcd56790f427694be2658d4b1a83bc0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000001b43454c4f2f434f50202843454c4f2f5553443a5553442f434f5029000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000568fd19986748ceff3301e55c0eb1e729e0ab7e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097b770b0200cce161907a9cbe0c6b177679f8f7c0000000000000000000000000000000000000000000000000000000000000001", + "nonce": "0x2b6", + "chainId": "0xa4ec" + }, + "additionalContracts": [], + "isFixedGasLimit": false + }, + { + "hash": "0x9314d4aca4e10f22e673b30636234cf837bd93f5113b342f5a053c51c0aacb11", + "transactionType": "CALL", + "contractName": null, + "contractAddress": "0x247Cb6ECf21bDd2Bc29d726CcCC8d2F066211663", + "function": "deployRelayer(address,string,uint256,(address,bool)[])", + "arguments": [ + "0x0196D1F4FdA21fA442e53EaF18Bf31282F6139F1", + "COP/USD", + "0", + "[(0x97b770B0200CCe161907a9cbe0C6B177679f8F7C, false)]" + ], + "transaction": { + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0x247Cb6ECf21bDd2Bc29d726CcCC8d2F066211663", + "gas": "0x178221", + "value": "0x0", + "input": "0x472a11110000000000000000000000000196d1f4fda21fa442e53eaf18bf31282f6139f10000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000007434f502f55534400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000097b770b0200cce161907a9cbe0c6b177679f8f7c0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x2b7", + "chainId": "0xa4ec" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x1a5ca8", + "logs": [ + { + "address": "0x247Cb6ECf21bDd2Bc29d726CcCC8d2F066211663", + "topics": [ + "0xa293edbc5018bd43c95bab416b1cb297eb58222c3471c76b3b87051f720acb05", + "0x0000000000000000000000005926f76d43ce2d778880226b3c4e7156c8ece99e", + "0x00000000000000000000000032abf1cbdfdcd56790f427694be2658d4b1a83bc" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001b43454c4f2f434f50202843454c4f2f5553443a5553442f434f5029000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000568fd19986748ceff3301e55c0eb1e729e0ab7e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097b770b0200cce161907a9cbe0c6b177679f8f7c0000000000000000000000000000000000000000000000000000000000000001", + "blockHash": "0x6806ef4bc707cd53a9e38264a5f85ac53c9703b48d76caa8dec1f0798f7a1824", + "blockNumber": "0x1ae461a", + "transactionHash": "0x454f3a7fd6dedcb6b8027ef52b195928a6a73618b1b4218649a0605afe1e56fc", + "transactionIndex": "0x2", + "logIndex": "0xe", + "removed": false + } + ], + "logsBloom": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000001000000000000000000000000000000000040000000100000000000000004000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000a0000000000008000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000", + "type": "0x0", + "transactionHash": "0x454f3a7fd6dedcb6b8027ef52b195928a6a73618b1b4218649a0605afe1e56fc", + "transactionIndex": "0x2", + "blockHash": "0x6806ef4bc707cd53a9e38264a5f85ac53c9703b48d76caa8dec1f0798f7a1824", + "blockNumber": "0x1ae461a", + "gasUsed": "0x11104f", + "effectiveGasPrice": "0x2540be400", + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0x247Cb6ECf21bDd2Bc29d726CcCC8d2F066211663", + "contractAddress": null + }, + { + "status": "0x1", + "cumulativeGasUsed": "0x2b61ad", + "logs": [ + { + "address": "0x247Cb6ECf21bDd2Bc29d726CcCC8d2F066211663", + "topics": [ + "0xa293edbc5018bd43c95bab416b1cb297eb58222c3471c76b3b87051f720acb05", + "0x000000000000000000000000783f947126adb7646c2a459b867f5b526d2e6603", + "0x0000000000000000000000000196d1f4fda21fa442e53eaf18bf31282f6139f1" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000007434f502f55534400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000097b770b0200cce161907a9cbe0c6b177679f8f7c0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x6806ef4bc707cd53a9e38264a5f85ac53c9703b48d76caa8dec1f0798f7a1824", + "blockNumber": "0x1ae461a", + "transactionHash": "0x9314d4aca4e10f22e673b30636234cf837bd93f5113b342f5a053c51c0aacb11", + "transactionIndex": "0x3", + "logIndex": "0xf", + "removed": false + } + ], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000800000000000000000400000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081000000000008000000000000000000000000000000000100000000000000000000000a00000000000000000000000000000000200000000002000000000000000000000000000000000000000000000000000000000", + "type": "0x0", + "transactionHash": "0x9314d4aca4e10f22e673b30636234cf837bd93f5113b342f5a053c51c0aacb11", + "transactionIndex": "0x3", + "blockHash": "0x6806ef4bc707cd53a9e38264a5f85ac53c9703b48d76caa8dec1f0798f7a1824", + "blockNumber": "0x1ae461a", + "gasUsed": "0x110505", + "effectiveGasPrice": "0x2540be400", + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0x247Cb6ECf21bDd2Bc29d726CcCC8d2F066211663", + "contractAddress": null + } + ], + "libraries": [ + "lib/mento-core-2.0.0/contracts/common/linkedlists/AddressLinkedList.sol:AddressLinkedList:0x6200F54D73491d56b8d7A975C9ee18EFb4D518Df", + "lib/mento-core-2.0.0/contracts/common/linkedlists/AddressSortedLinkedListWithMedian.sol:AddressSortedLinkedListWithMedian:0xED477A99035d0c1e11369F1D7A4e587893cc002B" + ], + "pending": [], + "returns": {}, + "timestamp": 1728664414, + "chain": 42220, + "commit": "a9f3de3" +} \ No newline at end of file diff --git a/broadcast/COPWhitelist-00-Deploy-ChainlinkRelayers.sol/44787/run-latest.json b/broadcast/COPWhitelist-00-Deploy-ChainlinkRelayers.sol/44787/run-latest.json new file mode 100644 index 0000000..64a95f2 --- /dev/null +++ b/broadcast/COPWhitelist-00-Deploy-ChainlinkRelayers.sol/44787/run-latest.json @@ -0,0 +1,139 @@ +{ + "transactions": [ + { + "hash": "0xa5fc6a3df2785b03bc40c2b07fd50c5483176e22fa375127818b184208d5b027", + "transactionType": "CALL", + "contractName": null, + "contractAddress": "0x172d6273364cC0c0B2be73aA1d4F20eb010CD1eB", + "function": "deployRelayer(address,string,uint256,(address,bool)[])", + "arguments": [ + "0x32ABF1cBdFdcD56790f427694be2658d4B1A83bC", + "CELO/COP (CELO/USD:USD/COP)", + "86400", + "[(0x022F9dCC73C5Fb43F2b4eF2EF9ad3eDD1D853946, false), (0x8c07f12022FD7AfC700A410a0f109dD349d89B49, true)]" + ], + "transaction": { + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0x172d6273364cC0c0B2be73aA1d4F20eb010CD1eB", + "gas": "0x1791b8", + "value": "0x0", + "input": "0x472a111100000000000000000000000032abf1cbdfdcd56790f427694be2658d4b1a83bc0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000001518000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000001b43454c4f2f434f50202843454c4f2f5553443a5553442f434f502900000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000022f9dcc73c5fb43f2b4ef2ef9ad3edd1d85394600000000000000000000000000000000000000000000000000000000000000000000000000000000000000008c07f12022fd7afc700a410a0f109dd349d89b490000000000000000000000000000000000000000000000000000000000000001", + "nonce": "0x654", + "chainId": "0xaef3" + }, + "additionalContracts": [], + "isFixedGasLimit": false + }, + { + "hash": "0x2825c34515a48f3e12a7b94ea933ae5f8b6e2314a83a7f83d4f85305526c6c8e", + "transactionType": "CALL", + "contractName": null, + "contractAddress": "0x172d6273364cC0c0B2be73aA1d4F20eb010CD1eB", + "function": "deployRelayer(address,string,uint256,(address,bool)[])", + "arguments": [ + "0x0196D1F4FdA21fA442e53EaF18Bf31282F6139F1", + "COP/USD", + "0", + "[(0x8c07f12022FD7AfC700A410a0f109dD349d89B49, false)]" + ], + "transaction": { + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0x172d6273364cC0c0B2be73aA1d4F20eb010CD1eB", + "gas": "0x178221", + "value": "0x0", + "input": "0x472a11110000000000000000000000000196d1f4fda21fa442e53eaf18bf31282f6139f10000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000007434f502f5553440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000008c07f12022fd7afc700a410a0f109dd349d89b490000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x655", + "chainId": "0xaef3" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x11bd51", + "logs": [ + { + "address": "0x172d6273364cC0c0B2be73aA1d4F20eb010CD1eB", + "topics": [ + "0xa293edbc5018bd43c95bab416b1cb297eb58222c3471c76b3b87051f720acb05", + "0x000000000000000000000000ab461a2742291515e126a353c05ba0587117060a", + "0x00000000000000000000000032abf1cbdfdcd56790f427694be2658d4b1a83bc" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000001b43454c4f2f434f50202843454c4f2f5553443a5553442f434f502900000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000022f9dcc73c5fb43f2b4ef2ef9ad3edd1d85394600000000000000000000000000000000000000000000000000000000000000000000000000000000000000008c07f12022fd7afc700a410a0f109dd349d89b490000000000000000000000000000000000000000000000000000000000000001", + "blockHash": "0x93a5bcfbb52729cd5fab9340a9af6d0aaf4377bfd3dbd01eb5c60d1c6896af1a", + "blockNumber": "0x1a6cf4c", + "transactionHash": "0xa5fc6a3df2785b03bc40c2b07fd50c5483176e22fa375127818b184208d5b027", + "transactionIndex": "0x1", + "logIndex": "0x0", + "removed": false + } + ], + "logsBloom": "0x00000000000000010000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000008040000000000000004000000000000000100000000000000000000000000000000000004000000000000000000000000000000000000000040000400000000000000000000000000000000000000000", + "type": "0x0", + "transactionHash": "0xa5fc6a3df2785b03bc40c2b07fd50c5483176e22fa375127818b184208d5b027", + "transactionIndex": "0x1", + "blockHash": "0x93a5bcfbb52729cd5fab9340a9af6d0aaf4377bfd3dbd01eb5c60d1c6896af1a", + "blockNumber": "0x1a6cf4c", + "gasUsed": "0x1111f7", + "effectiveGasPrice": "0x5d22cfc40", + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0x172d6273364cC0c0B2be73aA1d4F20eb010CD1eB", + "contractAddress": null, + "l1BaseFeeScalar": "0x558", + "l1BlobBaseFee": "0x1", + "l1BlobBaseFeeScalar": "0xc5fc5", + "l1Fee": "0x5a3b00e5b", + "l1GasPrice": "0x1775049de", + "l1GasUsed": "0xafb" + }, + { + "status": "0x1", + "cumulativeGasUsed": "0x22c3fa", + "logs": [ + { + "address": "0x172d6273364cC0c0B2be73aA1d4F20eb010CD1eB", + "topics": [ + "0xa293edbc5018bd43c95bab416b1cb297eb58222c3471c76b3b87051f720acb05", + "0x00000000000000000000000046d7bb2ce340f677fd059181c77bab3a3cddac09", + "0x0000000000000000000000000196d1f4fda21fa442e53eaf18bf31282f6139f1" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000007434f502f5553440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000008c07f12022fd7afc700a410a0f109dd349d89b490000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x93a5bcfbb52729cd5fab9340a9af6d0aaf4377bfd3dbd01eb5c60d1c6896af1a", + "blockNumber": "0x1a6cf4c", + "transactionHash": "0x2825c34515a48f3e12a7b94ea933ae5f8b6e2314a83a7f83d4f85305526c6c8e", + "transactionIndex": "0x2", + "logIndex": "0x1", + "removed": false + } + ], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000200000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000008040000000000000000000000000000000100000000000000000000000800000000000000000000000000000000200000000102000000000040000000000000000000000000000000000000000000000", + "type": "0x0", + "transactionHash": "0x2825c34515a48f3e12a7b94ea933ae5f8b6e2314a83a7f83d4f85305526c6c8e", + "transactionIndex": "0x2", + "blockHash": "0x93a5bcfbb52729cd5fab9340a9af6d0aaf4377bfd3dbd01eb5c60d1c6896af1a", + "blockNumber": "0x1a6cf4c", + "gasUsed": "0x1106a9", + "effectiveGasPrice": "0x5d22cfc40", + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0x172d6273364cC0c0B2be73aA1d4F20eb010CD1eB", + "contractAddress": null, + "l1BaseFeeScalar": "0x558", + "l1BlobBaseFee": "0x1", + "l1BlobBaseFeeScalar": "0xc5fc5", + "l1Fee": "0x44c19db47", + "l1GasPrice": "0x1775049de", + "l1GasUsed": "0x85e" + } + ], + "libraries": [ + "lib/mento-core-2.0.0/contracts/common/linkedlists/AddressLinkedList.sol:AddressLinkedList:0x2F0F7686fFFEfc3C266403Ad600035581deaedff", + "lib/mento-core-2.0.0/contracts/common/linkedlists/AddressSortedLinkedListWithMedian.sol:AddressSortedLinkedListWithMedian:0x29B1B5e05217c751038861aF2C77494EAB10A257" + ], + "pending": [], + "returns": {}, + "timestamp": 1728664586, + "chain": 44787, + "commit": "88bce40" +} \ No newline at end of file diff --git a/broadcast/COPWhitelist.sol/44787/run-latest.json b/broadcast/COPWhitelist.sol/44787/run-latest.json new file mode 100644 index 0000000..1d25b39 --- /dev/null +++ b/broadcast/COPWhitelist.sol/44787/run-latest.json @@ -0,0 +1,133 @@ +{ + "transactions": [ + { + "hash": "0xcc101a4b747a6c5aa0e4983c49db532ccd2bd7f37b7ec2516324f2fc90040e34", + "transactionType": "CALL", + "contractName": null, + "contractAddress": "0xAA963FC97281d9632d96700aB62A4D1340F9a28a", + "function": "minDeposit()", + "arguments": [], + "transaction": { + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0xAA963FC97281d9632d96700aB62A4D1340F9a28a", + "gas": "0x9bcc", + "value": "0x0", + "input": "0x41b3d185", + "nonce": "0x656", + "chainId": "0xaef3" + }, + "additionalContracts": [], + "isFixedGasLimit": false + }, + { + "hash": "0x9d1ded3a9ff00355faebfcb420c63951ac75327e2142e87d3cf96d3f7811ba37", + "transactionType": "CALL", + "contractName": null, + "contractAddress": "0xAA963FC97281d9632d96700aB62A4D1340F9a28a", + "function": "propose(uint256[],address[],bytes,uint256[],string)", + "arguments": [ + "[0, 0, 0, 0, 0]", + "[0xFdd8bD58115FfBf04e47411c1d228eCC45E93075, 0xFdd8bD58115FfBf04e47411c1d228eCC45E93075, 0xFdd8bD58115FfBf04e47411c1d228eCC45E93075, 0xFdd8bD58115FfBf04e47411c1d228eCC45E93075, 0xFdd8bD58115FfBf04e47411c1d228eCC45E93075]", + "0xf0ca4adb00000000000000000000000032abf1cbdfdcd56790f427694be2658d4b1a83bc000000000000000000000000ab461a2742291515e126a353c05ba0587117060afc20935d00000000000000000000000032abf1cbdfdcd56790f427694be2658d4b1a83bc0000000000000000000000000000000000000000000000000000000000000168f0ca4adb0000000000000000000000000196d1f4fda21fa442e53eaf18bf31282f6139f100000000000000000000000046d7bb2ce340f677fd059181c77bab3a3cddac09fc20935d0000000000000000000000000196d1f4fda21fa442e53eaf18bf31282f6139f10000000000000000000000000000000000000000000000000000000000000168145d8d180000000000000000000000008812241880c2d02e414d12dac392e6152587b66e00000000000000000000000032abf1cbdfdcd56790f427694be2658d4b1a83bc", + "[68, 68, 68, 68, 68]", + "https://TODO" + ], + "transaction": { + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0xAA963FC97281d9632d96700aB62A4D1340F9a28a", + "gas": "0x11f42e", + "value": "0x56bc75e2d63100000", + "input": "0x65bbdaa000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000003a000000000000000000000000000000000000000000000000000000000000004600000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000fdd8bd58115ffbf04e47411c1d228ecc45e93075000000000000000000000000fdd8bd58115ffbf04e47411c1d228ecc45e93075000000000000000000000000fdd8bd58115ffbf04e47411c1d228ecc45e93075000000000000000000000000fdd8bd58115ffbf04e47411c1d228ecc45e93075000000000000000000000000fdd8bd58115ffbf04e47411c1d228ecc45e930750000000000000000000000000000000000000000000000000000000000000154f0ca4adb00000000000000000000000032abf1cbdfdcd56790f427694be2658d4b1a83bc000000000000000000000000ab461a2742291515e126a353c05ba0587117060afc20935d00000000000000000000000032abf1cbdfdcd56790f427694be2658d4b1a83bc0000000000000000000000000000000000000000000000000000000000000168f0ca4adb0000000000000000000000000196d1f4fda21fa442e53eaf18bf31282f6139f100000000000000000000000046d7bb2ce340f677fd059181c77bab3a3cddac09fc20935d0000000000000000000000000196d1f4fda21fa442e53eaf18bf31282f6139f10000000000000000000000000000000000000000000000000000000000000168145d8d180000000000000000000000008812241880c2d02e414d12dac392e6152587b66e00000000000000000000000032abf1cbdfdcd56790f427694be2658d4b1a83bc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000004400000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000000c68747470733a2f2f544f444f0000000000000000000000000000000000000000", + "nonce": "0x657", + "chainId": "0xaef3" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x28ee3", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "type": "0x0", + "transactionHash": "0xcc101a4b747a6c5aa0e4983c49db532ccd2bd7f37b7ec2516324f2fc90040e34", + "transactionIndex": "0x2", + "blockHash": "0x1eb1b83aae0b17ec93506d9e02d1b45d527398e6a5d69adcb218352df7776b8d", + "blockNumber": "0x1a6d0ba", + "gasUsed": "0x70cc", + "effectiveGasPrice": "0x5d22cfc40", + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0xAA963FC97281d9632d96700aB62A4D1340F9a28a", + "contractAddress": null, + "l1BaseFeeScalar": "0x558", + "l1BlobBaseFee": "0x1", + "l1BlobBaseFeeScalar": "0xc5fc5", + "l1Fee": "0x2d6f7fa61", + "l1GasPrice": "0x14c2192ff", + "l1GasUsed": "0x640" + }, + { + "status": "0x1", + "cumulativeGasUsed": "0xf8e71", + "logs": [ + { + "address": "0xAA963FC97281d9632d96700aB62A4D1340F9a28a", + "topics": [ + "0x3e069fb74dcf5fbc07740b0d40d7f7fc48e9c0ca5dc3d19eb34d2e05d74c5543", + "0x000000000000000000000000000000000000000000000000000000000000014f" + ], + "data": "0x0000000000000000000000000000000000000000000000000000000067095572", + "blockHash": "0x1eb1b83aae0b17ec93506d9e02d1b45d527398e6a5d69adcb218352df7776b8d", + "blockNumber": "0x1a6d0ba", + "transactionHash": "0x9d1ded3a9ff00355faebfcb420c63951ac75327e2142e87d3cf96d3f7811ba37", + "transactionIndex": "0x3", + "logIndex": "0x2", + "removed": false + }, + { + "address": "0xAA963FC97281d9632d96700aB62A4D1340F9a28a", + "topics": [ + "0x1bfe527f3548d9258c2512b6689f0acfccdd0557d80a53845db25fc57e93d8fe", + "0x0000000000000000000000000000000000000000000000000000000000000150", + "0x00000000000000000000000056fd3f2bee130e9867942d0f463a16fbe49b8d81" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000056bc75e2d631000000000000000000000000000000000000000000000000000000000000067095572", + "blockHash": "0x1eb1b83aae0b17ec93506d9e02d1b45d527398e6a5d69adcb218352df7776b8d", + "blockNumber": "0x1a6d0ba", + "transactionHash": "0x9d1ded3a9ff00355faebfcb420c63951ac75327e2142e87d3cf96d3f7811ba37", + "transactionIndex": "0x3", + "logIndex": "0x3", + "removed": false + } + ], + "logsBloom": "0x00000000000000000000000000000000000000000000000020000000000000000000000000000000000002004000010000000000000200000000000000000000000000000000010010000000010000000040000000000000080000000000000000000000010000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000004000000000000000000000000002001000000001000000000000000000000", + "type": "0x0", + "transactionHash": "0x9d1ded3a9ff00355faebfcb420c63951ac75327e2142e87d3cf96d3f7811ba37", + "transactionIndex": "0x3", + "blockHash": "0x1eb1b83aae0b17ec93506d9e02d1b45d527398e6a5d69adcb218352df7776b8d", + "blockNumber": "0x1a6d0ba", + "gasUsed": "0xcff8e", + "effectiveGasPrice": "0x5d22cfc40", + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": "0xAA963FC97281d9632d96700aB62A4D1340F9a28a", + "contractAddress": null, + "l1BaseFeeScalar": "0x558", + "l1BlobBaseFee": "0x1", + "l1BlobBaseFeeScalar": "0xc5fc5", + "l1Fee": "0x85d18b1b8", + "l1GasPrice": "0x14c2192ff", + "l1GasUsed": "0x1268" + } + ], + "libraries": [ + "lib/mento-core-2.0.0/contracts/common/linkedlists/AddressLinkedList.sol:AddressLinkedList:0x2F0F7686fFFEfc3C266403Ad600035581deaedff", + "lib/mento-core-2.0.0/contracts/common/linkedlists/AddressSortedLinkedListWithMedian.sol:AddressSortedLinkedListWithMedian:0x29B1B5e05217c751038861aF2C77494EAB10A257" + ], + "pending": [], + "returns": {}, + "timestamp": 1728664952, + "chain": 44787, + "commit": "3de0d08" +} \ No newline at end of file diff --git a/broadcast/dev-DeployMockChainlinkAggregator.sol/44787/run-COPUSD.json b/broadcast/dev-DeployMockChainlinkAggregator.sol/44787/run-COPUSD.json new file mode 100644 index 0000000..d71e238 --- /dev/null +++ b/broadcast/dev-DeployMockChainlinkAggregator.sol/44787/run-COPUSD.json @@ -0,0 +1,73 @@ +{ + "transactions": [ + { + "hash": "0x7ef1864a61ccd5ac0e0872b57860690a955250ec34b54f563d23aa39b6ad197e", + "transactionType": "CREATE", + "contractName": "MockChainlinkAggregator", + "contractAddress": "0x8c07f12022FD7AfC700A410a0f109dD349d89B49", + "function": null, + "arguments": [ + "COPUSD" + ], + "transaction": { + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "gas": "0x7e74e", + "value": "0x0", + "input": "0x60806040523461023c576107a98038038061001981610241565b9283398101906020808284031261023c5781516001600160401b039283821161023c570192601f9080828601121561023c57845184811161021257601f199561006782850188168601610241565b9282845285838301011161023c57849060005b8381106102285750506000918301018190528054336001600160a01b0319821681178355916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a3805193841161021257600254926001938481811c91168015610208575b828210146101f2578381116101ab575b508092851160011461014557508394509083929160009461013a575b50501b916000199060031b1c1916176002555b60405161054290816102678239f35b015192503880610118565b929484908116600260005284600020946000905b888383106101915750505010610178575b505050811b0160025561012b565b015160001960f88460031b161c1916905538808061016a565b858701518855909601959485019487935090810190610159565b6002600052816000208480880160051c8201928489106101e9575b0160051c019085905b8281106101dd5750506100fc565b600081550185906101cf565b925081926101c6565b634e487b7160e01b600052602260045260246000fd5b90607f16906100ec565b634e487b7160e01b600052604160045260246000fd5b81810183015185820184015286920161007a565b600080fd5b6040519190601f01601f191682016001600160401b038111838210176102125760405256fe608060408181526004918236101561001657600080fd5b600092833560e01c918263313ce5671461049b57508163715018a61461041a5781637284e4161461024b5781638da5cb5b1461021857816399213cd8146101f6578163e1e244d8146101d7578163f2fde38b146100b4575063feaf968c1461007d57600080fd5b346100b057816003193601126100b0578160a0926001549280519382855260208501528301524260608301526080820152f35b5080fd5b919050346101d35760206003193601126101d35781359173ffffffffffffffffffffffffffffffffffffffff918284168094036101cf576100f36104b6565b831561014c5750508254827fffffffffffffffffffffffff00000000000000000000000000000000000000008216178455167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08380a380f35b90602060849251917f08c379a0000000000000000000000000000000000000000000000000000000008352820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152fd5b8480fd5b8280fd5b5050346100b057816003193601126100b0576020906001549051908152f35b8390346100b05760206003193601126100b0576102116104b6565b3560015580f35b5050346100b057816003193601126100b05773ffffffffffffffffffffffffffffffffffffffff60209254169051908152f35b919050346101d357826003193601126101d35780518360025460019581871c878316978815610410575b6020938483108a146103e457848798999a84895291826000146103a9575050600114610355575b5050601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe095869203011683019583871067ffffffffffffffff881117610329575085929391838652818452845191828186015281955b8387106103115750508394508582601f949501015201168101030190f35b868101820151898801890152958101958895506102f3565b8260416024927f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b600285528492507f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace5b8284106103935750505083018101388061029c565b805488850186015287965092840192810161037e565b915093507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091501682860152151560051b840101388061029c565b60248660228b7f4e487b7100000000000000000000000000000000000000000000000000000000835252fd5b90607f1690610275565b83346104985780600319360112610498576104336104b6565b8073ffffffffffffffffffffffffffffffffffffffff81547fffffffffffffffffffffffff000000000000000000000000000000000000000081168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a380f35b80fd5b8490346100b057816003193601126100b05780600860209252f35b73ffffffffffffffffffffffffffffffffffffffff6000541633036104d757565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fdfea164736f6c6343000812000a00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006434f505553440000000000000000000000000000000000000000000000000000", + "nonce": "0x651", + "chainId": "0xaef3" + }, + "additionalContracts": [], + "isFixedGasLimit": false + } + ], + "receipts": [ + { + "status": "0x1", + "cumulativeGasUsed": "0x6c040", + "logs": [ + { + "address": "0x8c07f12022FD7AfC700A410a0f109dD349d89B49", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x00000000000000000000000056fd3f2bee130e9867942d0f463a16fbe49b8d81" + ], + "data": "0x", + "blockHash": "0xb76d4e248049e9c79801032d4e4a49df99a8dc0aaa761888ca227e3ea881d45c", + "blockNumber": "0x1a6cb0c", + "transactionHash": "0x7ef1864a61ccd5ac0e0872b57860690a955250ec34b54f563d23aa39b6ad197e", + "transactionIndex": "0x1", + "logIndex": "0x0", + "removed": false + } + ], + "logsBloom": "0x00000000000000000000000000000000000000000000000020800000000000000000000000400000000000000000010000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000001000000020000000000000000000800000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000004000000000000000000000000000000000000000000000000000000000000", + "type": "0x0", + "transactionHash": "0x7ef1864a61ccd5ac0e0872b57860690a955250ec34b54f563d23aa39b6ad197e", + "transactionIndex": "0x1", + "blockHash": "0xb76d4e248049e9c79801032d4e4a49df99a8dc0aaa761888ca227e3ea881d45c", + "blockNumber": "0x1a6cb0c", + "gasUsed": "0x614e6", + "effectiveGasPrice": "0x5d22cfc40", + "from": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", + "to": null, + "contractAddress": "0x8c07f12022FD7AfC700A410a0f109dD349d89B49", + "l1BaseFeeScalar": "0x558", + "l1BlobBaseFee": "0x1", + "l1BlobBaseFeeScalar": "0xc5fc5", + "l1Fee": "0x28987ef339", + "l1GasPrice": "0x176a2bf02", + "l1GasUsed": "0x4f35" + } + ], + "libraries": [ + "lib/mento-core-2.0.0/contracts/common/linkedlists/AddressLinkedList.sol:AddressLinkedList:0x2F0F7686fFFEfc3C266403Ad600035581deaedff", + "lib/mento-core-2.0.0/contracts/common/linkedlists/AddressSortedLinkedListWithMedian.sol:AddressSortedLinkedListWithMedian:0x29B1B5e05217c751038861aF2C77494EAB10A257" + ], + "pending": [], + "returns": {}, + "timestamp": 1728663500, + "chain": 44787, + "commit": "704ed3d" +} \ No newline at end of file diff --git a/script/dev/dev-DeployMockChainlinkAggregator.sol b/script/dev/dev-DeployMockChainlinkAggregator.sol index 714f9c8..ac38b36 100644 --- a/script/dev/dev-DeployMockChainlinkAggregator.sol +++ b/script/dev/dev-DeployMockChainlinkAggregator.sol @@ -13,8 +13,8 @@ import { MockChainlinkAggregator } from "contracts/MockChainlinkAggregator.sol"; * Used to deploy mock Chainlink Aggregators to Alfajores and Baklava to be used * in testnet relayers to mimic mainnet more closely. * ========== IMPORTANT ====================================== - * @dev After deploying the script save the broadcast file as {rateFeed}.json, - * update the reference in `dependencies.json` to the ne waddress, + * @dev After deploying the script save the broadcast file as run-{rateFeed}.json, + * update the reference in `dependencies.json` to the new waddress, * and update the dev-UpdateMockChainlinkAggregators script if it's a new aggregator * =========================================================== */ diff --git a/script/dev/dev-UpdateMockChainlinkAggregators.sol b/script/dev/dev-UpdateMockChainlinkAggregators.sol index 5222548..40c874c 100644 --- a/script/dev/dev-UpdateMockChainlinkAggregators.sol +++ b/script/dev/dev-UpdateMockChainlinkAggregators.sol @@ -34,6 +34,7 @@ contract UpdateMockChainlinkAggregators is Script { using Contracts for Contracts.Cache; address private constant PHPUSDMainnetAggregator = 0x4ce8e628Bb82Ea5271908816a6C580A71233a66c; address private constant CELOUSDMainnetAggregator = 0x0568fD19986748cEfF3301e55c0eb1E729E0Ab7e; + address private constant COPUSDMainnetAggregator = 0x97b770B0200CCe161907a9cbe0C6B177679f8F7C; mapping(address => address) private mockForAggregator; mapping(address => int256) private aggregatorAnswers; @@ -54,10 +55,14 @@ contract UpdateMockChainlinkAggregators is Script { /// @dev Load additional deployed aggregators here to forward rates contracts.loadSilent("dev-DeployMockChainlinkAggregator", "PHPUSD"); address PHPUSDTestnetMock = contracts.deployed("MockChainlinkAggregator"); + contracts.loadSilent("dev-DeployMockChainlinkAggregator", "COPUSD"); + address COPUSDTestnetMock = contracts.deployed("MockChainlinkAggregator"); mockForAggregator[PHPUSDMainnetAggregator] = PHPUSDTestnetMock; + mockForAggregator[COPUSDMainnetAggregator] = COPUSDTestnetMock; aggregatorsToForward.push(PHPUSDMainnetAggregator); + aggregatorsToForward.push(COPUSDMainnetAggregator); } function setUp_baklava() internal { diff --git a/script/upgrades/COPWhitelist/COPWhitelist.sol b/script/upgrades/COPWhitelist/COPWhitelist.sol new file mode 100644 index 0000000..5f8f888 --- /dev/null +++ b/script/upgrades/COPWhitelist/COPWhitelist.sol @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// solhint-disable func-name-mixedcase, contract-name-camelcase, function-max-lines, var-name-mixedcase +pragma solidity ^0.5.13; +pragma experimental ABIEncoderV2; + +import { GovernanceScript } from "script/utils/Script.sol"; +import { console } from "forge-std/console.sol"; +import { Contracts } from "script/utils/Contracts.sol"; +import { Chain } from "script/utils/Chain.sol"; +import { Arrays } from "script/utils/Arrays.sol"; + +import { IChainlinkRelayerFactory } from "mento-core-2.5.0/interfaces/IChainlinkRelayerFactory.sol"; +import { IChainlinkRelayer } from "mento-core-2.5.0/interfaces/IChainlinkRelayer.sol"; + +import { IMentoUpgrade, ICeloGovernance } from "script/interfaces/IMentoUpgrade.sol"; + +interface ISortedOracles { + function addOracle(address, address) external; + + function removeOracle(address, address, uint256) external; + + function setEquivalentToken(address, address) external; + + function getEquivalentToken(address) external returns (address); + + function medianRate(address) external returns (uint256, uint256); + + function getOracles(address) external returns (address[] memory); + + function setTokenReportExpiry(address, uint256) external; + + function getTokenReportExpirySeconds(address) external returns (uint256); + + function tokenReportExpirySeconds(address) external returns (uint256); +} + +/** + forge script {file} --rpc-url $BAKLAVA_RPC_URL + --broadcast --legacy + * @dev depends on: ../deploy/*.sol + */ +contract COPWhitelist is IMentoUpgrade, GovernanceScript { + using Contracts for Contracts.Cache; + + bool public hasChecks = true; + ICeloGovernance.Transaction[] private transactions; + + // Mento contracts + IChainlinkRelayerFactory private relayerFactory; + ISortedOracles private sortedOracles; + address private cCOP; + + mapping(address => IChainlinkRelayer) private relayersByRateFeedId; + + function prepare() public { + loadDeployedContracts(); + setAddresses(); + } + + /** + * @dev Loads the deployed contracts from previous deployments + */ + function loadDeployedContracts() public { + contracts.loadSilent("MU07-Deploy-ChainlinkRelayerFactory", "latest"); + contracts.loadSilent("cCOP-00-Create-Proxies", "latest"); + } + + /** + * @dev Sets the addresses of the various contracts needed for the proposal. + */ + function setAddresses() public { + relayerFactory = IChainlinkRelayerFactory(contracts.deployed("ChainlinkRelayerFactoryProxy")); + sortedOracles = ISortedOracles(contracts.celoRegistry("SortedOracles")); + cCOP = contracts.deployed("StableTokenCOPProxy"); + + address[] memory relayers = relayerFactory.getRelayers(); + for (uint i = 0; i < relayers.length; i++) { + IChainlinkRelayer relayer = IChainlinkRelayer(relayers[i]); + relayersByRateFeedId[relayer.rateFeedId()] = relayer; + } + } + + function run() public { + prepare(); + + address governance = contracts.celoRegistry("Governance"); + ICeloGovernance.Transaction[] memory _transactions = buildProposal(); + + vm.startBroadcast(Chain.deployerPrivateKey()); + { + createProposal(_transactions, "https://github.com/celo-org/governance/blob/main/CGPs/cgp-0150.md", governance); + } + vm.stopBroadcast(); + } + + function buildProposal() public returns (ICeloGovernance.Transaction[] memory) { + require(transactions.length == 0, "buildProposal() should only be called once"); + + // We are increasing this to 6 minutes because chainlink often reports new prices very close to the 5 minute mark + // and sometimes the pool becomes inactive for about a minute until we relay the new price to sorted oracles. + // This is not really relevant for CELOCOP since it's not used for a pool, but we are keeping it consistent. + uint256 tokenReportExpiry = 6 minutes; + proposal_whitelistRelayerFor("relayed:CELOCOP", tokenReportExpiry); + proposal_whitelistRelayerFor("relayed:COPUSD", tokenReportExpiry); + proposal_setEquivalentTokenForCOP(); + + return transactions; + } + + /** + * @notice For a give rateFeed string, see if there's a register deployed relayer, and ensure + * it is the only whitelisted oracle for that rate feed. + * If there are multiple oracles whitelisted, remove them. + * If the existing relayer isn't whitelisted, add it. + */ + function proposal_whitelistRelayerFor(string memory rateFeed, uint256 tokenReportExpiry) private { + address rateFeedId = toRateFeedId(rateFeed); + IChainlinkRelayer relayer = relayersByRateFeedId[rateFeedId]; + require( + address(relayer) != address(0), + string(abi.encodePacked("Relayer for rateFeed=", rateFeed, " not deployed")) + ); + + address[] memory oracles = sortedOracles.getOracles(rateFeedId); + bool isOracle = false; + + for (uint i = 0; i < oracles.length; i++) { + isOracle = isOracle || (oracles[i] == address(relayer)); + if (oracles[i] == address(relayer)) continue; + + // Remove other whitelisted relayers + transactions.push( + ICeloGovernance.Transaction({ + value: 0, + destination: address(sortedOracles), + data: abi.encodeWithSelector(ISortedOracles(0).removeOracle.selector, rateFeedId, oracles[i], i) + }) + ); + } + + if (!isOracle) { + transactions.push( + ICeloGovernance.Transaction({ + value: 0, + destination: address(sortedOracles), + data: abi.encodeWithSelector(ISortedOracles(0).addOracle.selector, rateFeedId, address(relayer)) + }) + ); + uint256 currentExpiry = sortedOracles.tokenReportExpirySeconds(rateFeedId); + if (currentExpiry != tokenReportExpiry) { + transactions.push( + ICeloGovernance.Transaction({ + value: 0, + destination: address(sortedOracles), + data: abi.encodeWithSelector(ISortedOracles(0).setTokenReportExpiry.selector, rateFeedId, tokenReportExpiry) + }) + ); + } + } + } + + /** + * @notice Sorted Oracles has this new feature of equivalent tokens. When a token has an + * equivalent token configured, SortedOracles will return the equivalent token's median + * rate when asked. This was used for gas payments with USDC, by setting USDC's equivalent + * token to be cUSD. But this also allows us to remove this duality between rate feeds that + * are tokens, and rate feeds derived from identifiers. + * In the context of cCOP it means that we can report to the rateFeed defined by the + * canonical id: `relayed:CELOCOP`, and then have address(cCOP) point to that for + * gas payments. + */ + function proposal_setEquivalentTokenForCOP() private { + require(!Chain.isBaklava(), "Baklava is not suported for this deployment."); + + address CELOCOPRateFeedId = toRateFeedId("relayed:CELOCOP"); + transactions.push( + ICeloGovernance.Transaction({ + value: 0, + destination: address(sortedOracles), + data: abi.encodeWithSelector(ISortedOracles(0).setEquivalentToken.selector, cCOP, CELOCOPRateFeedId) + }) + ); + } +} diff --git a/script/upgrades/COPWhitelist/COPWhitelistChecks.sol b/script/upgrades/COPWhitelist/COPWhitelistChecks.sol new file mode 100644 index 0000000..cbd19ee --- /dev/null +++ b/script/upgrades/COPWhitelist/COPWhitelistChecks.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// solhint-disable var-name-mixedcase, func-name-mixedcase +pragma solidity ^0.5.13; +pragma experimental ABIEncoderV2; + +import { Test } from "forge-std/Test.sol"; +import { console } from "forge-std/console.sol"; +import { Contracts } from "script/utils/Contracts.sol"; +import { Chain } from "script/utils/Chain.sol"; +import { Arrays } from "script/utils/Arrays.sol"; +import { GovernanceScript } from "script/utils/Script.sol"; + +import { IChainlinkRelayerFactory } from "mento-core-2.5.0/interfaces/IChainlinkRelayerFactory.sol"; +import { IChainlinkRelayer } from "mento-core-2.5.0/interfaces/IChainlinkRelayer.sol"; + +import { ISortedOracles } from "./COPWhitelist.sol"; + +contract COPWhitelistChecks is GovernanceScript, Test { + using Contracts for Contracts.Cache; + + IChainlinkRelayerFactory private relayerFactory; + ISortedOracles private sortedOracles; + address private cCOP; + address CELOCOPRateFeed; + address COPUSDRateFeed; + + function prepare() public { + contracts.loadSilent("MU07-Deploy-ChainlinkRelayerFactory", "latest"); + contracts.loadSilent("cCOP-00-Create-Proxies", "latest"); + + relayerFactory = IChainlinkRelayerFactory(contracts.deployed("ChainlinkRelayerFactoryProxy")); + sortedOracles = ISortedOracles(contracts.celoRegistry("SortedOracles")); + cCOP = contracts.deployed("StableTokenCOPProxy"); + CELOCOPRateFeed = toRateFeedId("relayed:CELOCOP"); + COPUSDRateFeed = toRateFeedId("relayed:COPUSD"); + } + + function run() public { + prepare(); + assert_relayersAreWhitelisted(); + assert_relayersReport(); + assert_tokenReportExpiryEq(CELOCOPRateFeed, 6 minutes); + assert_tokenReportExpiryEq(COPUSDRateFeed, 6 minutes); + } + + function assert_relayersReport() internal { + address[] memory copRelayers = Arrays.addresses( + relayerFactory.getRelayer(CELOCOPRateFeed), + relayerFactory.getRelayer(COPUSDRateFeed) + ); + + for (uint i = 0; i < copRelayers.length; i++) { + IChainlinkRelayer relayer = IChainlinkRelayer(copRelayers[i]); + + relayer.relay(); + (uint256 rate, ) = sortedOracles.medianRate(relayer.rateFeedId()); + emit log_named_decimal_uint(relayer.rateFeedDescription(), rate, 24); + } + + console.log("✅ CELO/COP and COP/USD relayers relayed successfully"); + } + + function assert_relayersAreWhitelisted() internal { + require(sortedOracles.getOracles(CELOCOPRateFeed).length == 1); + require(sortedOracles.getOracles(COPUSDRateFeed).length == 1); + + address CELOCOPWhitelisted = sortedOracles.getOracles(CELOCOPRateFeed)[0]; + address COPUSDWhitelisted = sortedOracles.getOracles(COPUSDRateFeed)[0]; + + require(CELOCOPWhitelisted == relayerFactory.getRelayer(CELOCOPRateFeed), "Wrong CELO/COP relayer whitelisted"); + require(COPUSDWhitelisted == relayerFactory.getRelayer(COPUSDRateFeed), "Wrong COP/USD relayer whitelisted"); + + console.log("✅ CELO/COP and COP/USD relayers whitelisted correctly"); + } + + function assert_equivalentTokenEq(address token, address expected) internal { + require(!Chain.isBaklava(), "Baklava is not suported for this deployment."); + + address actual = sortedOracles.getEquivalentToken(token); + if (actual != expected) { + console.log("❌ Equivalent token mismatch for $cCOP (%s)."); + } + assertEq(actual, expected); + console.log("✅ $cCOP [%s] equivalent token is correct", cCOP); + } + + function assert_tokenReportExpiryEq(address rateFeedId, uint256 expected) internal { + uint256 actual = sortedOracles.getTokenReportExpirySeconds(rateFeedId); + if (actual != expected) { + console.log("❌ Token report expiry mismatch for rateFeedId [%s].", rateFeedId); + } + assertEq(actual, expected); + console.log("✅ Token report expiry for rateFeedId [%s] is correct", rateFeedId); + } +} diff --git a/script/upgrades/COPWhitelist/deploy/COPWhitelist-00-Deploy-ChainlinkRelayers.sol b/script/upgrades/COPWhitelist/deploy/COPWhitelist-00-Deploy-ChainlinkRelayers.sol new file mode 100644 index 0000000..5df270c --- /dev/null +++ b/script/upgrades/COPWhitelist/deploy/COPWhitelist-00-Deploy-ChainlinkRelayers.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// solhint-disable contract-name-camelcase +pragma solidity ^0.8.18; + +import { console } from "forge-std-next/console.sol"; +import { Script } from "script/utils/mento/Script.sol"; +import { Chain as ChainLib } from "script/utils/mento/Chain.sol"; +import { Contracts } from "script/utils/mento/Contracts.sol"; + +import { ChainlinkRelayerFactory } from "mento-core-2.5.0/oracles/ChainlinkRelayerFactory.sol"; +import { ChainlinkRelayerFactoryProxy } from "mento-core-2.5.0/oracles/ChainlinkRelayerFactoryProxy.sol"; +import { ChainlinkRelayerFactoryProxyAdmin } from "mento-core-2.5.0/oracles/ChainlinkRelayerFactoryProxyAdmin.sol"; +import { IChainlinkRelayer } from "mento-core-2.5.0/interfaces/IChainlinkRelayer.sol"; +import { toRateFeedId, aggregators } from "script/utils/mento/Oracles.sol"; + +contract cCOP_Deploy_ChainlinkRelayers is Script { + using Contracts for Contracts.Cache; + using { toRateFeedId } for string; + + struct Relayer { + string rateFeed; + string rateFeedDescription; + uint256 maxTimestampSpread; + IChainlinkRelayer.ChainlinkAggregator[] aggregators; + } + + Relayer[] private relayers = [ + Relayer({ + rateFeed: "relayed:CELOCOP", + rateFeedDescription: "CELO/COP (CELO/USD:USD/COP)", + maxTimestampSpread: 24 hours, + aggregators: aggregators( + IChainlinkRelayer.ChainlinkAggregator({ aggregator: contracts.dependency("Chainlink.CELOUSD"), invert: false }), + IChainlinkRelayer.ChainlinkAggregator({ aggregator: contracts.dependency("Chainlink.COPUSD"), invert: true }) + ) + }), + Relayer({ + rateFeed: "relayed:COPUSD", + rateFeedDescription: "COP/USD", + maxTimestampSpread: 0, + aggregators: aggregators( + IChainlinkRelayer.ChainlinkAggregator({ aggregator: contracts.dependency("Chainlink.COPUSD"), invert: false }) + ) + }) + ]; + + ChainlinkRelayerFactory private relayerFactory; + + constructor() Script() { + contracts.load("MU07-Deploy-ChainlinkRelayerFactory", "latest"); + relayerFactory = ChainlinkRelayerFactory(contracts.deployed("ChainlinkRelayerFactoryProxy")); + } + + function run() public { + vm.startBroadcast(ChainLib.deployerPrivateKey()); + { + for (uint i = 0; i < relayers.length; i++) { + deployRelayerIfNoneOrDifferent(relayers[i]); + } + } + vm.stopBroadcast(); + + for (uint i = 0; i < relayers.length; i++) { + address rateFeedId = toRateFeedId(relayers[i].rateFeed); + address relayer = relayerFactory.getRelayer(rateFeedId); + console.log("%s - ratefeed:%s, relayer:%s", relayers[i].rateFeed, rateFeedId, relayer); + } + } + + function deployRelayerIfNoneOrDifferent(Relayer memory relayer) internal { + address rateFeedId = relayer.rateFeed.toRateFeedId(); + address relayerAddress = address(relayerFactory.deployedRelayers(rateFeedId)); + address newRelayerAddress = relayerFactory.computedRelayerAddress( + rateFeedId, + relayer.rateFeedDescription, + relayer.maxTimestampSpread, + relayer.aggregators + ); + if (newRelayerAddress != relayerAddress) { + if (relayerAddress == address(0)) { + relayerFactory.deployRelayer( + rateFeedId, + relayer.rateFeedDescription, + relayer.maxTimestampSpread, + relayer.aggregators + ); + } else { + relayerFactory.redeployRelayer( + rateFeedId, + relayer.rateFeedDescription, + relayer.maxTimestampSpread, + relayer.aggregators + ); + } + } + } +} diff --git a/script/upgrades/dependencies.json b/script/upgrades/dependencies.json index 697c37f..54c926c 100644 --- a/script/upgrades/dependencies.json +++ b/script/upgrades/dependencies.json @@ -20,7 +20,8 @@ "FractalSigner": "0xacD08d6714ADba531beFF582e6FD5DA1AFD6bc65", "MentoFoundationMultisig": "0x3468D23A0B1aB3Ab9A537813166A8f7ff1947014", "Chainlink.CELOUSD": "0x0568fD19986748cEfF3301e55c0eb1E729E0Ab7e", - "Chainlink.PHPUSD": "0x4ce8e628Bb82Ea5271908816a6C580A71233a66c" + "Chainlink.PHPUSD": "0x4ce8e628Bb82Ea5271908816a6C580A71233a66c", + "Chainlink.COPUSD": "0x97b770B0200CCe161907a9cbe0C6B177679f8F7C" }, "62320": { "BridgedUSDC": "0xD4079B322c392D6b196f90AA4c439fC2C16d6770", @@ -43,7 +44,8 @@ "MentoLiquiditySupport": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", "FractalSigner": "0x56fD3F2bEE130e9867942D0F463a16fBE49B8d81", "Chainlink.CELOUSD": "0xBC2684ABEeefc606a92fbf94ce4357E98D267286", - "Chainlink.PHPUSD": "0xF4143259C91B4acdC03bff740b1C4CC663F60CB6" + "Chainlink.PHPUSD": "0xF4143259C91B4acdC03bff740b1C4CC663F60CB6", + "Chainlink.COPUSD": "0xBaklavaNotSupported" }, "44787": { "BridgedUSDC": "0x87D61dA3d668797786D73BC674F053f87111570d", @@ -66,6 +68,7 @@ "MentoLiquiditySupport": "0x6bD481a12cb2790E7EE805b9E6e7E91917DeEe6a", "FractalSigner": "0x2fCAb633adFA6aF8266025D63228047033c3ceD0", "Chainlink.CELOUSD": "0x022F9dCC73C5Fb43F2b4eF2EF9ad3eDD1D853946", - "Chainlink.PHPUSD": "0xcf79c1445c69cd17b1bdecf790416085a4ff808a" + "Chainlink.PHPUSD": "0xcf79c1445c69cd17b1bdecf790416085a4ff808a", + "Chainlink.COPUSD": "0x8c07f12022FD7AfC700A410a0f109dD349d89B49" } }