diff --git a/.gitignore b/.gitignore index 6bc5e0f..868fa43 100644 --- a/.gitignore +++ b/.gitignore @@ -6,11 +6,6 @@ typechain typechain-types # Hardhat files -cache -artifacts - -#foundry test compilation files -out # pnpm pnpm-error.log diff --git a/constants/tokens.ts b/constants/tokens.ts index 953bba5..37c3c83 100644 --- a/constants/tokens.ts +++ b/constants/tokens.ts @@ -50,9 +50,9 @@ export const TOKENS: TokensMap = { symbol: 'frxETH', }, // FPI on Ethereum - // https://etherscan.io/token/0x853d955acef822db058eb8505911ed77f175b99e + // https://etherscan.io/token/0x5Ca135cB8527d76e932f34B5145575F9d8cbE08E FPI: { - address: '0x853d955aCEf822Db058eb8505911ED77F175b99e', + address: '0x5Ca135cB8527d76e932f34B5145575F9d8cbE08E', name: 'Frax Price Index', symbol: 'FPI', }, diff --git a/deploy/ofts.ts b/deploy/ofts.ts index 658ddab..eece20b 100644 --- a/deploy/ofts.ts +++ b/deploy/ofts.ts @@ -20,8 +20,8 @@ deploy.dependencies = [ // 'StakedFraxEtherOFTAdapter', // 'FraxOFT', // 'FraxOFTAdapter', - 'FraxEtherOFT', - 'FraxEtherOFTAdapter', + // 'FraxEtherOFT', + // 'FraxEtherOFTAdapter', 'FraxPriceIndexOFT', 'FraxPriceIndexOFTAdapter' ] diff --git a/deployments/base/FraxPriceIndexOFT.json b/deployments/base/FraxPriceIndexOFT.json index e46d3d4..bb31277 100644 --- a/deployments/base/FraxPriceIndexOFT.json +++ b/deployments/base/FraxPriceIndexOFT.json @@ -1,5 +1,5 @@ { - "address": "0xE41228a455700cAF09E551805A8aB37caa39D08c", + "address": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", "abi": [ { "inputs": [ @@ -1773,46 +1773,46 @@ "type": "function" } ], - "transactionHash": "0x78db3688785031d75f275bc19cf947f19dd1780256f2796009e3520ae39d9c47", + "transactionHash": "0x9d33b75b333c5b370fe80ef41d8421de9942a1d78f1886cfe6c65b2643f5f116", "receipt": { "to": null, "from": "0x1D3bE58f3B199C12FB6525aBC0265999Ec849274", - "contractAddress": "0xE41228a455700cAF09E551805A8aB37caa39D08c", - "transactionIndex": 44, + "contractAddress": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", + "transactionIndex": 106, "gasUsed": "2995057", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000001000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000001000000000000000000100000000000000000020000000000000000000800000000000010000000000000000000400000000000000000000000000000000000000000000200000000200000000000000000000000000000000000800000000000000000000000000000000000000400000040000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000010000000000000000000000", - "blockHash": "0xe1a0c29c7b5573196674697bb7d84cc6065884d9cc5d12c1108bf986ed0e8ce6", - "transactionHash": "0x78db3688785031d75f275bc19cf947f19dd1780256f2796009e3520ae39d9c47", + "logsBloom": "0x00000000000000000000000400000000000000000000000000800000001000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000001000000000000000000100000000000000000020000000000000000004800000000000010000000000000000000400000000000000000000000000000000010000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000010000000000000000000000", + "blockHash": "0xf2a35b0be115eb29f658cae173735068a06989e26dabf72430ddc0fb72119bdd", + "transactionHash": "0x9d33b75b333c5b370fe80ef41d8421de9942a1d78f1886cfe6c65b2643f5f116", "logs": [ { - "transactionIndex": 44, - "blockNumber": 16362455, - "transactionHash": "0x78db3688785031d75f275bc19cf947f19dd1780256f2796009e3520ae39d9c47", - "address": "0xE41228a455700cAF09E551805A8aB37caa39D08c", + "transactionIndex": 106, + "blockNumber": 19260122, + "transactionHash": "0x9d33b75b333c5b370fe80ef41d8421de9942a1d78f1886cfe6c65b2643f5f116", + "address": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274" ], "data": "0x", - "logIndex": 128, - "blockHash": "0xe1a0c29c7b5573196674697bb7d84cc6065884d9cc5d12c1108bf986ed0e8ce6" + "logIndex": 173, + "blockHash": "0xf2a35b0be115eb29f658cae173735068a06989e26dabf72430ddc0fb72119bdd" }, { - "transactionIndex": 44, - "blockNumber": 16362455, - "transactionHash": "0x78db3688785031d75f275bc19cf947f19dd1780256f2796009e3520ae39d9c47", + "transactionIndex": 106, + "blockNumber": 19260122, + "transactionHash": "0x9d33b75b333c5b370fe80ef41d8421de9942a1d78f1886cfe6c65b2643f5f116", "address": "0x1a44076050125825900e736c501f859c50fE728c", "topics": [ "0x6ee10e9ed4d6ce9742703a498707862f4b00f1396a87195eb93267b3d7983981" ], - "data": "0x000000000000000000000000e41228a455700caf09e551805a8ab37caa39d08c0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274", - "logIndex": 129, - "blockHash": "0xe1a0c29c7b5573196674697bb7d84cc6065884d9cc5d12c1108bf986ed0e8ce6" + "data": "0x0000000000000000000000006eca253b102d41b6b69ac815b9cc6bd47ef1979d0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274", + "logIndex": 174, + "blockHash": "0xf2a35b0be115eb29f658cae173735068a06989e26dabf72430ddc0fb72119bdd" } ], - "blockNumber": 16362455, - "cumulativeGasUsed": "9415698", + "blockNumber": 19260122, + "cumulativeGasUsed": "18939522", "status": 1, "byzantium": true }, diff --git a/deployments/blast/FraxPriceIndexOFT.json b/deployments/blast/FraxPriceIndexOFT.json index 7e3d5ed..495a85d 100644 --- a/deployments/blast/FraxPriceIndexOFT.json +++ b/deployments/blast/FraxPriceIndexOFT.json @@ -1,5 +1,5 @@ { - "address": "0xE41228a455700cAF09E551805A8aB37caa39D08c", + "address": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", "abi": [ { "inputs": [ @@ -1773,46 +1773,46 @@ "type": "function" } ], - "transactionHash": "0xb462edd4fc6fbf2a10fd63b6439ffe828ddff63a36f464c6646e04cc0990511a", + "transactionHash": "0xd89032e0ef2b8807fd72b57502938f69226d8e57e3004a1f7c9903e29af4a145", "receipt": { "to": null, "from": "0x1D3bE58f3B199C12FB6525aBC0265999Ec849274", - "contractAddress": "0xE41228a455700cAF09E551805A8aB37caa39D08c", - "transactionIndex": 8, + "contractAddress": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", + "transactionIndex": 14, "gasUsed": "2995057", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000001000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000001000000000000000000100000000000000000020000000000000000000800000000000010000000000000000000400000000000000000000000000000000000000000000200000000200000000000000000000000000000000000800000000000000000000000000000000000000400000040000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000010000000000000000000000", - "blockHash": "0xbf8e924423120100a5c5cee7e48c80bee30332a84122c08f1733d7944fa0e159", - "transactionHash": "0xb462edd4fc6fbf2a10fd63b6439ffe828ddff63a36f464c6646e04cc0990511a", + "logsBloom": "0x00000000000000000000000400000000000000000000000000800000001000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000001000000000000000000100000000000000000020000000000000000004800000000000010000000000000000000400000000000000000000000000000000010000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000010000000000000000000000", + "blockHash": "0xfdae866a5b7fdb179d492b5c043a6f6f051d1b56baa2928b3e9c5899b40364a7", + "transactionHash": "0xd89032e0ef2b8807fd72b57502938f69226d8e57e3004a1f7c9903e29af4a145", "logs": [ { - "transactionIndex": 8, - "blockNumber": 5352220, - "transactionHash": "0xb462edd4fc6fbf2a10fd63b6439ffe828ddff63a36f464c6646e04cc0990511a", - "address": "0xE41228a455700cAF09E551805A8aB37caa39D08c", + "transactionIndex": 14, + "blockNumber": 8249888, + "transactionHash": "0xd89032e0ef2b8807fd72b57502938f69226d8e57e3004a1f7c9903e29af4a145", + "address": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274" ], "data": "0x", - "logIndex": 15, - "blockHash": "0xbf8e924423120100a5c5cee7e48c80bee30332a84122c08f1733d7944fa0e159" + "logIndex": 5, + "blockHash": "0xfdae866a5b7fdb179d492b5c043a6f6f051d1b56baa2928b3e9c5899b40364a7" }, { - "transactionIndex": 8, - "blockNumber": 5352220, - "transactionHash": "0xb462edd4fc6fbf2a10fd63b6439ffe828ddff63a36f464c6646e04cc0990511a", + "transactionIndex": 14, + "blockNumber": 8249888, + "transactionHash": "0xd89032e0ef2b8807fd72b57502938f69226d8e57e3004a1f7c9903e29af4a145", "address": "0x1a44076050125825900e736c501f859c50fE728c", "topics": [ "0x6ee10e9ed4d6ce9742703a498707862f4b00f1396a87195eb93267b3d7983981" ], - "data": "0x000000000000000000000000e41228a455700caf09e551805a8ab37caa39d08c0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274", - "logIndex": 16, - "blockHash": "0xbf8e924423120100a5c5cee7e48c80bee30332a84122c08f1733d7944fa0e159" + "data": "0x0000000000000000000000006eca253b102d41b6b69ac815b9cc6bd47ef1979d0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274", + "logIndex": 6, + "blockHash": "0xfdae866a5b7fdb179d492b5c043a6f6f051d1b56baa2928b3e9c5899b40364a7" } ], - "blockNumber": 5352220, - "cumulativeGasUsed": "3948391", + "blockNumber": 8249888, + "cumulativeGasUsed": "4967776", "status": 1, "byzantium": true }, diff --git a/deployments/ethereum/FraxPriceIndexOFTAdapter.json b/deployments/ethereum/FraxPriceIndexOFTAdapter.json index 286d6d9..e92fc6b 100644 --- a/deployments/ethereum/FraxPriceIndexOFTAdapter.json +++ b/deployments/ethereum/FraxPriceIndexOFTAdapter.json @@ -1,5 +1,5 @@ { - "address": "0xE41228a455700cAF09E551805A8aB37caa39D08c", + "address": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", "abi": [ { "inputs": [ @@ -1316,51 +1316,51 @@ "type": "function" } ], - "transactionHash": "0x5823267dcad0a2e96c5f29c9d84b58209171dfd7a54110eec18c7ab062a27f7a", + "transactionHash": "0x33929ff37b1ea0e2662e4b95ff511322caa9d01a94d3383277c6995b541de934", "receipt": { "to": null, "from": "0x1D3bE58f3B199C12FB6525aBC0265999Ec849274", - "contractAddress": "0xE41228a455700cAF09E551805A8aB37caa39D08c", - "transactionIndex": 115, - "gasUsed": "2506474", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000001000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000001000000000000000000100000000000000000020000000000000000000800000000000010000000000000000000400000000000000000000000000000000000000000000200000000200000000000000000000000000000000000800000000000000000000000000000000000000400000040000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000010000000000000000000000", - "blockHash": "0xd16f7ad0613f11d904ff156668dcec943bd5eaddcfc9fec0895fd8e642c39036", - "transactionHash": "0x5823267dcad0a2e96c5f29c9d84b58209171dfd7a54110eec18c7ab062a27f7a", + "contractAddress": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", + "transactionIndex": 65, + "gasUsed": "2506345", + "logsBloom": "0x00000000000000000000000400000000000000000000000000800000001000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000001000000000000000000100000000000000000020000000000000000004800000000000010000000000000000000400000000000000000000000000000000010000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000010000000000000000000000", + "blockHash": "0x44a9ee1afd0533389d9b517d793486a2a5411ec42c64221a3c37d3e7c32e3bfc", + "transactionHash": "0x33929ff37b1ea0e2662e4b95ff511322caa9d01a94d3383277c6995b541de934", "logs": [ { - "transactionIndex": 115, - "blockNumber": 20184929, - "transactionHash": "0x5823267dcad0a2e96c5f29c9d84b58209171dfd7a54110eec18c7ab062a27f7a", - "address": "0xE41228a455700cAF09E551805A8aB37caa39D08c", + "transactionIndex": 65, + "blockNumber": 20665333, + "transactionHash": "0x33929ff37b1ea0e2662e4b95ff511322caa9d01a94d3383277c6995b541de934", + "address": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274" ], "data": "0x", - "logIndex": 253, - "blockHash": "0xd16f7ad0613f11d904ff156668dcec943bd5eaddcfc9fec0895fd8e642c39036" + "logIndex": 178, + "blockHash": "0x44a9ee1afd0533389d9b517d793486a2a5411ec42c64221a3c37d3e7c32e3bfc" }, { - "transactionIndex": 115, - "blockNumber": 20184929, - "transactionHash": "0x5823267dcad0a2e96c5f29c9d84b58209171dfd7a54110eec18c7ab062a27f7a", + "transactionIndex": 65, + "blockNumber": 20665333, + "transactionHash": "0x33929ff37b1ea0e2662e4b95ff511322caa9d01a94d3383277c6995b541de934", "address": "0x1a44076050125825900e736c501f859c50fE728c", "topics": [ "0x6ee10e9ed4d6ce9742703a498707862f4b00f1396a87195eb93267b3d7983981" ], - "data": "0x000000000000000000000000e41228a455700caf09e551805a8ab37caa39d08c0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274", - "logIndex": 254, - "blockHash": "0xd16f7ad0613f11d904ff156668dcec943bd5eaddcfc9fec0895fd8e642c39036" + "data": "0x0000000000000000000000006eca253b102d41b6b69ac815b9cc6bd47ef1979d0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274", + "logIndex": 179, + "blockHash": "0x44a9ee1afd0533389d9b517d793486a2a5411ec42c64221a3c37d3e7c32e3bfc" } ], - "blockNumber": 20184929, - "cumulativeGasUsed": "11090697", + "blockNumber": 20665333, + "cumulativeGasUsed": "9725653", "status": 1, "byzantium": true }, "args": [ - "0x853d955aCEf822Db058eb8505911ED77F175b99e", + "0x5Ca135cB8527d76e932f34B5145575F9d8cbE08E", "0x1a44076050125825900e736c501f859c50fE728c", "0x1D3bE58f3B199C12FB6525aBC0265999Ec849274" ], diff --git a/deployments/metis/FraxPriceIndexOFT.json b/deployments/metis/FraxPriceIndexOFT.json index 14db190..2774ed3 100644 --- a/deployments/metis/FraxPriceIndexOFT.json +++ b/deployments/metis/FraxPriceIndexOFT.json @@ -1,5 +1,5 @@ { - "address": "0xE41228a455700cAF09E551805A8aB37caa39D08c", + "address": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", "abi": [ { "inputs": [ @@ -1773,22 +1773,22 @@ "type": "function" } ], - "transactionHash": "0x59b3bf7ba36457b1fb2b63cea941375fa53f36ee4c1e13b016bd0675c9fd1029", + "transactionHash": "0x017f7e270531dc6240dbbdde554a4b15f891a7f549e306708a53ed549e258fda", "receipt": { "to": null, "from": "0x1D3bE58f3B199C12FB6525aBC0265999Ec849274", - "contractAddress": "0xE41228a455700cAF09E551805A8aB37caa39D08c", + "contractAddress": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", "transactionIndex": 0, "gasUsed": "2994119", - "logsBloom": "0x00000000000000000000000000000000000000000000000000800000001000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000001000000000000000000100000000000000000020000000000000000000800000000000010000000000000000000400000000000000000000000000000000000000000000200000000200000000000000000000000000000000000800000000000000000000000000000000000000400000040000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000010000000000000000000000", - "blockHash": "0x3ea40a7c2c5783b0039a50ddeabc07bc87a70f1817424d323b32f73b7975108c", - "transactionHash": "0x59b3bf7ba36457b1fb2b63cea941375fa53f36ee4c1e13b016bd0675c9fd1029", + "logsBloom": "0x00000000000000000000000400000000000000000000000000800000001000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000001000000000000000000100000000000000000020000000000000000004800000000000010000000000000000000400000000000000000000000000000000010000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000200000000000010000000000000000000000", + "blockHash": "0xef6cfa84d80cc2308bb326630a557460c43e3fa5898a835383d5d860316f1c04", + "transactionHash": "0x017f7e270531dc6240dbbdde554a4b15f891a7f549e306708a53ed549e258fda", "logs": [ { "transactionIndex": 0, - "blockNumber": 17480232, - "transactionHash": "0x59b3bf7ba36457b1fb2b63cea941375fa53f36ee4c1e13b016bd0675c9fd1029", - "address": "0xE41228a455700cAF09E551805A8aB37caa39D08c", + "blockNumber": 18326819, + "transactionHash": "0x017f7e270531dc6240dbbdde554a4b15f891a7f549e306708a53ed549e258fda", + "address": "0x6Eca253b102D41B6B69AC815B9CC6bD47eF1979d", "topics": [ "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1796,22 +1796,22 @@ ], "data": "0x", "logIndex": 0, - "blockHash": "0x3ea40a7c2c5783b0039a50ddeabc07bc87a70f1817424d323b32f73b7975108c" + "blockHash": "0xef6cfa84d80cc2308bb326630a557460c43e3fa5898a835383d5d860316f1c04" }, { "transactionIndex": 0, - "blockNumber": 17480232, - "transactionHash": "0x59b3bf7ba36457b1fb2b63cea941375fa53f36ee4c1e13b016bd0675c9fd1029", + "blockNumber": 18326819, + "transactionHash": "0x017f7e270531dc6240dbbdde554a4b15f891a7f549e306708a53ed549e258fda", "address": "0x1a44076050125825900e736c501f859c50fE728c", "topics": [ "0x6ee10e9ed4d6ce9742703a498707862f4b00f1396a87195eb93267b3d7983981" ], - "data": "0x000000000000000000000000e41228a455700caf09e551805a8ab37caa39d08c0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274", + "data": "0x0000000000000000000000006eca253b102d41b6b69ac815b9cc6bd47ef1979d0000000000000000000000001d3be58f3b199c12fb6525abc0265999ec849274", "logIndex": 1, - "blockHash": "0x3ea40a7c2c5783b0039a50ddeabc07bc87a70f1817424d323b32f73b7975108c" + "blockHash": "0xef6cfa84d80cc2308bb326630a557460c43e3fa5898a835383d5d860316f1c04" } ], - "blockNumber": 17480232, + "blockNumber": 18326819, "cumulativeGasUsed": "2994119", "status": 1, "byzantium": true diff --git a/tasks/send.ts b/tasks/send.ts new file mode 100644 index 0000000..64b56c7 --- /dev/null +++ b/tasks/send.ts @@ -0,0 +1,72 @@ +import { BigNumber } from 'ethers' +import { hexZeroPad } from 'ethers/lib/utils' +import { task, types } from 'hardhat/config' +import { ActionType, HardhatRuntimeEnvironment } from 'hardhat/types' + +// struct SendParam { +// uint32 dstEid; // Destination endpoint ID. +// bytes32 to; // Recipient address. +// uint256 amountLD; // Amount to send in local decimals. +// uint256 minAmountLD; // Minimum amount to send in local decimals. +// bytes extraOptions; // Additional options supplied by the caller to be used in the LayerZero message. +// bytes composeMsg; // The composed message for the send() operation. +// bytes oftCmd; // The OFT command to be executed, unused in default OFT implementations. +// } + +interface TaskArguments { + dstEid: number + amount: string + to: string + contractName: string +} + +const action: ActionType = async ( + { dstEid, amount, to, contractName }, + hre: HardhatRuntimeEnvironment +) => { + const signer = (await hre.ethers.getSigners())[0] + const Oft = await hre.deployments.get(contractName) + const oft = await hre.ethers.getContractAt(Oft.abi, Oft.address, signer) + + // approve the amount to be sent adapters only + if (hre.network.name.startsWith('ethereum')) { + const erc20Token = await hre.ethers.getContractAt('IERC20', (await oft.functions.token())[0]) + const approvalTxResponse = await erc20Token.approve(oft.address, amount) + const approvalTxReceipt = await approvalTxResponse.wait() + console.log(`approved: ${amount}: ${approvalTxReceipt.transactionHash}`) + console.log('balance: ', (await erc20Token.balanceOf(signer.address)).toString()) + } else { + console.log('balance: ', (await oft.balanceOf(signer.address)).toString()) + } + + console.log('amount: ', amount) + + const amountLD = BigNumber.from(amount) + const sendParam = { + dstEid, + to: hexZeroPad(to, 32), + amountLD: amountLD.toString(), + minAmountLD: amountLD.mul(9_000).div(10_000).toString(), + // calls with 60k gas + the existing enforced options + // extraOptions: '0x0003010011010000000000000000000000000000ea60', + extraOptions: '0x', + composeMsg: '0x', + oftCmd: '0x', + } + const [msgFee] = await oft.functions.quoteSend(sendParam, false) + console.log('msgFee: ', msgFee.nativeFee.toString()) + const txResponse = await oft.functions.send(sendParam, msgFee, to, { + value: msgFee.nativeFee, + // gasLimit: 1000000, + }) + console.log(txResponse) + const txReceipt = await txResponse.wait() + console.log(`send: ${amount} to ${to}: ${txReceipt.transactionHash}`) +} + +task('send', 'Sends a transaction') + .setAction(action) + .addParam('dstEid', 'Destination endpoint ID', undefined, types.int, false) + .addParam('amount', 'Amount to send in wei', undefined, types.string, false) + .addParam('to', 'Recipient address', undefined, types.string, false) + .addParam('contractName', 'Contract name', undefined, types.string, false) diff --git a/tasks/sendFromSolana.ts b/tasks/sendFromSolana.ts new file mode 100644 index 0000000..98dd968 --- /dev/null +++ b/tasks/sendFromSolana.ts @@ -0,0 +1,199 @@ +import assert from 'assert' + +import { fetchDigitalAsset } from '@metaplex-foundation/mpl-token-metadata' +import { + fetchAddressLookupTable, + findAssociatedTokenPda, + mplToolbox, + setComputeUnitLimit, + setComputeUnitPrice, +} from '@metaplex-foundation/mpl-toolbox' +import { + AddressLookupTableInput, + TransactionBuilder, + createSignerFromKeypair, + signerIdentity, +} from '@metaplex-foundation/umi' +import { createUmi } from '@metaplex-foundation/umi-bundle-defaults' +import { + fromWeb3JsInstruction, + fromWeb3JsKeypair, + fromWeb3JsPublicKey, + toWeb3JsPublicKey, +} from '@metaplex-foundation/umi-web3js-adapters' +import { TOKEN_PROGRAM_ID } from '@solana/spl-token' +import { Keypair, PublicKey } from '@solana/web3.js' +import { getExplorerLink, getSimulationComputeUnits } from '@solana-developers/helpers' +import bs58 from 'bs58' +import { hexlify } from 'ethers/lib/utils' +import { task } from 'hardhat/config' + +import { formatEid } from '@layerzerolabs/devtools' +import { types } from '@layerzerolabs/devtools-evm-hardhat' +import { EndpointId } from '@layerzerolabs/lz-definitions' +import { OFT_SEED, OftPDADeriver, OftProgram, OftTools, SendHelper } from '@layerzerolabs/lz-solana-sdk-v2' +import { Options, addressToBytes32 } from '@layerzerolabs/lz-v2-utilities' + +import { createSolanaConnectionFactory } from '../common/utils' +import getFee from '../utils/getFee' + +interface Args { + amount: number + to: string + fromEid: EndpointId + toEid: EndpointId + programId: string + mint: string +} + +const LOOKUP_TABLE_ADDRESS: Partial> = { + [EndpointId.SOLANA_V2_MAINNET]: new PublicKey('AokBxha6VMLLgf97B5VYHEtqztamWmYERBmmFvjuTzJB'), + [EndpointId.SOLANA_V2_TESTNET]: new PublicKey('9thqPdbR27A1yLWw2spwJLySemiGMXxPnEvfmXVk4KuK'), +} + +// Define a Hardhat task for sending OFT from Solana +task('lz:oft:solana:send', 'Send tokens from Solana to a target EVM chain') + .addParam('amount', 'The amount of tokens to send', undefined, types.int) + .addParam('fromEid', 'The source endpoint ID', undefined, types.eid) + .addParam('to', 'The recipient address on the destination chain') + .addParam('toEid', 'The destination endpoint ID', undefined, types.eid) + .addParam('mint', 'The OFT token mint public key', undefined, types.string) + .addParam('programId', 'The OFT program ID', undefined, types.string) + .setAction(async (taskArgs: Args) => { + const privateKey = process.env.SOLANA_PRIVATE_KEY + assert(!!privateKey, 'SOLANA_PRIVATE_KEY is not defined in the environment variables.') + + const keypair = Keypair.fromSecretKey(bs58.decode(privateKey)) + const umiKeypair = fromWeb3JsKeypair(keypair) + + const lookupTableAddress = LOOKUP_TABLE_ADDRESS[taskArgs.fromEid] + assert(lookupTableAddress != null, `No lookup table found for ${formatEid(taskArgs.fromEid)}`) + + const connectionFactory = createSolanaConnectionFactory() + const connection = await connectionFactory(taskArgs.fromEid) + + // Initialize Solana connection and UMI framework + const umi = createUmi(connection.rpcEndpoint).use(mplToolbox()) + const umiWalletSigner = createSignerFromKeypair(umi, umiKeypair) + umi.use(signerIdentity(umiWalletSigner)) + + // Define OFT program and token mint public keys + const oftProgramId = new PublicKey(taskArgs.programId) + const mintPublicKey = new PublicKey(taskArgs.mint) + const umiMintPublicKey = fromWeb3JsPublicKey(mintPublicKey) + + // Find the associated token account + const tokenAccount = findAssociatedTokenPda(umi, { + mint: umiMintPublicKey, + owner: umiWalletSigner.publicKey, + }) + + // Derive the OFT configuration PDA + const [oftConfigPda] = PublicKey.findProgramAddressSync( + [Buffer.from(OFT_SEED), mintPublicKey.toBuffer()], + oftProgramId + ) + + // Fetch token metadata + const mintInfo = (await fetchDigitalAsset(umi, umiMintPublicKey)).mint + const destinationEid: EndpointId = taskArgs.toEid + const amount = taskArgs.amount * 10 ** mintInfo.decimals + + // Derive peer address and fetch peer information + const deriver = new OftPDADeriver(oftProgramId) + const [peerAddress] = deriver.peer(oftConfigPda, destinationEid) + const peerInfo = await OftProgram.accounts.Peer.fromAccountAddress(connection, peerAddress) + + // Set up send helper and convert recipient address to bytes32 + const sendHelper = new SendHelper() + const recipientAddressBytes32 = addressToBytes32(taskArgs.to) + + // Quote the fee for the cross-chain transfer + const feeQuote = await OftTools.quoteWithUln( + connection, + keypair.publicKey, + mintPublicKey, + destinationEid, + BigInt(amount), + (BigInt(amount) * BigInt(9)) / BigInt(10), + Options.newOptions().addExecutorLzReceiveOption(0, 0).toBytes(), + Array.from(recipientAddressBytes32), + false, // payInZRO + undefined, // tokenEscrow + undefined, // composeMsg + peerInfo.address, + await sendHelper.getQuoteAccounts( + connection, + keypair.publicKey, + oftConfigPda, + destinationEid, + hexlify(peerInfo.address) + ), + TOKEN_PROGRAM_ID, // SPL Token Program + oftProgramId // OFT Program + ) + + console.log(feeQuote) + + // Create the instruction for sending tokens + const sendInstruction = await OftTools.sendWithUln( + connection, + keypair.publicKey, // payer + mintPublicKey, // tokenMint + toWeb3JsPublicKey(tokenAccount[0]), // tokenSource + destinationEid, + BigInt(amount), + (BigInt(amount) * BigInt(9)) / BigInt(10), + Options.newOptions().addExecutorLzReceiveOption(0, 0).toBytes(), + Array.from(recipientAddressBytes32), + feeQuote.nativeFee, + undefined, // payInZRO + undefined, + undefined, + peerInfo.address, + undefined, + TOKEN_PROGRAM_ID, // SPL Token Program + oftProgramId // OFT Program + ) + + // Convert the instruction and create the transaction builder + const convertedInstruction = fromWeb3JsInstruction(sendInstruction) + const transactionBuilder = new TransactionBuilder([ + { + instruction: convertedInstruction, + signers: [umiWalletSigner], + bytesCreatedOnChain: 0, + }, + ]) + + // Fetch simulation compute units and set compute unit price + const { averageFeeExcludingZeros } = await getFee() + const priorityFee = Math.round(averageFeeExcludingZeros) + const computeUnitPrice = BigInt(priorityFee) + console.log(`Compute unit price: ${computeUnitPrice}`) + + const addressLookupTableInput: AddressLookupTableInput = await fetchAddressLookupTable( + umi, + fromWeb3JsPublicKey(lookupTableAddress) + ) + const { value: lookupTableAccount } = await connection.getAddressLookupTable(new PublicKey(lookupTableAddress)) + const computeUnits = await getSimulationComputeUnits(connection, [sendInstruction], keypair.publicKey, [ + lookupTableAccount!, + ]) + + // Build and send the transaction + const transactionSignature = await transactionBuilder + .add(setComputeUnitPrice(umi, { microLamports: computeUnitPrice * BigInt(4) })) + .add(setComputeUnitLimit(umi, { units: computeUnits! * 1.1 })) + .setAddressLookupTables([addressLookupTableInput]) + .sendAndConfirm(umi) + + // Encode the transaction signature and generate explorer links + const transactionSignatureBase58 = bs58.encode(transactionSignature.signature) + const solanaTxLink = getExplorerLink('tx', transactionSignatureBase58.toString(), 'mainnet-beta') + const layerZeroTxLink = `https://layerzeroscan.com/tx/${transactionSignatureBase58}` + + console.log(`✅ Sent ${taskArgs.amount} token(s) to destination EID: ${destinationEid}!`) + console.log(`View Solana transaction here: ${solanaTxLink}`) + console.log(`Track cross-chain transfer here: ${layerZeroTxLink}`) + }) \ No newline at end of file diff --git a/tasks/transferDelegate.ts b/tasks/transferDelegate.ts new file mode 100644 index 0000000..75cb867 --- /dev/null +++ b/tasks/transferDelegate.ts @@ -0,0 +1,25 @@ +import { task, types } from 'hardhat/config' +import { ActionType, HardhatRuntimeEnvironment, TaskArguments } from 'hardhat/types' + +import { MULTISIGS } from '../constants/multisigs' + +const action: ActionType = async ({ contractName }, hre: HardhatRuntimeEnvironment) => { + // Needs to be the delegate wallet index + const signer = (await hre.ethers.getSigners())[0] + const Oft = await hre.deployments.get(contractName) + const oft = await hre.ethers.getContractAt(Oft.abi, Oft.address, signer) + const owner = MULTISIGS[hre.network.name] + + if (!owner) { + throw new Error('No owner found for this network') + } + + const txResponse = await oft.functions.setDelegate(owner) + console.log(txResponse) + const txReceipt = await txResponse.wait() + console.log(`tx hash: ${txReceipt.transactionHash}`) +} + +task('transferDelegate', 'Transfers delegate of a contract to another address') + .setAction(action) + .addParam('contractName', 'Contract name', undefined, types.string, false) diff --git a/tasks/transferOwnership.ts b/tasks/transferOwnership.ts new file mode 100644 index 0000000..0c79c5e --- /dev/null +++ b/tasks/transferOwnership.ts @@ -0,0 +1,25 @@ +import { task, types } from 'hardhat/config' +import { ActionType, HardhatRuntimeEnvironment, TaskArguments } from 'hardhat/types' + +import { MULTISIGS } from '../constants/multisigs' + +const action: ActionType = async ({ contractName }, hre: HardhatRuntimeEnvironment) => { + // Needs to be the delegate wallet index + const signer = (await hre.ethers.getSigners())[0] + const Oft = await hre.deployments.get(contractName) + const oft = await hre.ethers.getContractAt(Oft.abi, Oft.address, signer) + const owner = MULTISIGS[hre.network.name] + + if (!owner) { + throw new Error('No owner found for this network') + } + + const txResponse = await oft.functions.transferOwnership(owner) + console.log(txResponse) + const txReceipt = await txResponse.wait() + console.log(`tx hash: ${txReceipt.transactionHash}`) +} + +task('transferOwnership', 'Transfers ownership of a contract to another address') + .setAction(action) + .addParam('contractName', 'Contract name', undefined, types.string, false)