diff --git a/.gitignore b/.gitignore index 419f54e6..9ba18366 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ tsconfig.tsbuildinfo *~ *mnemonic* .envrc +.DS_Store diff --git a/package-lock.json b/package-lock.json index 240ea4a1..d4bcf5e0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -50004,7 +50004,7 @@ }, "target_chains/ethereum/sdk/js": { "name": "@pythnetwork/pyth-evm-js", - "version": "1.15.0", + "version": "1.16.0", "license": "Apache-2.0", "dependencies": { "@pythnetwork/price-service-client": "*", diff --git a/target_chains/ethereum/contracts/.env.prod.canto b/target_chains/ethereum/contracts/.env.prod.canto new file mode 100644 index 00000000..a1a4da9a --- /dev/null +++ b/target_chains/ethereum/contracts/.env.prod.canto @@ -0,0 +1,5 @@ +MIGRATIONS_DIR=./migrations/prod-receiver +MIGRATIONS_NETWORK=canto +WORMHOLE_CHAIN_NAME=canto +CLUSTER=mainnet +VALID_TIME_PERIOD_SECONDS=60 diff --git a/target_chains/ethereum/contracts/Deploying.md b/target_chains/ethereum/contracts/Deploying.md index 89feedac..4d1e3c5a 100644 --- a/target_chains/ethereum/contracts/Deploying.md +++ b/target_chains/ethereum/contracts/Deploying.md @@ -204,3 +204,12 @@ contract or a new contract do the following steps in addition to the steps descr 5. If you wish to deploy the contract run `npx hardhat deploy-zksync --network --script deploy/zkSyncDeploy` to deploy it to the new network. Otherwise run `npx hardhat deploy-zksync --network --script deploy/zkSyncDeployNewPythImpl.ts` to get a new implementation address. Then put it in `..new_impl` file and run the deployment script to handle the rest of the changes. + +# Deploy/Upgrade on Canto + +Canto network rewards some percentage of the gas usage to the contracts. To enable the rewards we have modified the contract upon +deployment to register its own address as the receiver of the rewards and also assigned Pyth to received Wormhole Receiver rewards +too. The registration only happens once for contract. The contracts are registered with token id 654. We don't need to register +the contracts upon upgrades because the proxy address doesn't change. The contract changes for registration are stored in +[this diff](./canto-deployment-patch.diff) for future reference. Please note that if we switch to another Wormhole Receiver +(a new address) we will need to register the new contract. diff --git a/target_chains/ethereum/contracts/canto-deployment-patch.diff b/target_chains/ethereum/contracts/canto-deployment-patch.diff new file mode 100644 index 00000000..af4ec312 --- /dev/null +++ b/target_chains/ethereum/contracts/canto-deployment-patch.diff @@ -0,0 +1,64 @@ +diff --git a/target_chains/ethereum/contracts/contracts/pyth/PythUpgradable.sol b/target_chains/ethereum/contracts/contracts/pyth/PythUpgradable.sol +index 7f9a2a22..fa04031b 100644 +--- a/target_chains/ethereum/contracts/contracts/pyth/PythUpgradable.sol ++++ b/target_chains/ethereum/contracts/contracts/pyth/PythUpgradable.sol +@@ -13,6 +13,10 @@ import "./PythGovernance.sol"; + import "./Pyth.sol"; + import "@pythnetwork/pyth-sdk-solidity/PythErrors.sol"; + ++interface ITurnstile { ++ function register(address) external returns(uint256); ++} ++ + contract PythUpgradable is + Initializable, + OwnableUpgradeable, +@@ -45,6 +49,10 @@ contract PythUpgradable is + ); + + renounceOwnership(); ++ ++ uint256 csrTokenId = ITurnstile(0xEcf044C5B4b867CFda001101c617eCd347095B44) ++ .register(address(this)); ++ PythGetters.wormhole().assignCsr(csrTokenId); + } + + /// Ensures the contract cannot be uninitialized and taken over. +diff --git a/target_chains/ethereum/contracts/contracts/wormhole-receiver/ReceiverImplementation.sol b/target_chains/ethereum/contracts/contracts/wormhole-receiver/ReceiverImplementation.sol +index 4b2fc3c5..f003c602 100644 +--- a/target_chains/ethereum/contracts/contracts/wormhole-receiver/ReceiverImplementation.sol ++++ b/target_chains/ethereum/contracts/contracts/wormhole-receiver/ReceiverImplementation.sol +@@ -8,6 +8,10 @@ import "./ReceiverGovernance.sol"; + + import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol"; + ++interface ITurnstile { ++ function assign(uint256) external returns(uint256); ++} ++ + contract ReceiverImplementation is ReceiverGovernance { + modifier initializer() { + address implementation = ERC1967Upgrade._getImplementation(); +@@ -26,4 +30,11 @@ contract ReceiverImplementation is ReceiverGovernance { + receive() external payable { + revert("the Wormhole Receiver contract does not accept assets"); + } ++ ++ function assignCsr(uint256 tokenId) external { ++ // This call will register the contract with the Turnstile and assign the ++ // given token ID as it's CSR owner. One it is called, it is registered ++ // and subsequent calls will fail. ++ ITurnstile(0xEcf044C5B4b867CFda001101c617eCd347095B44).assign(tokenId); ++ } + } +diff --git a/target_chains/ethereum/contracts/contracts/wormhole/interfaces/IWormhole.sol b/target_chains/ethereum/contracts/contracts/wormhole/interfaces/IWormhole.sol +index 69d60a62..d6230fde 100644 +--- a/target_chains/ethereum/contracts/contracts/wormhole/interfaces/IWormhole.sol ++++ b/target_chains/ethereum/contracts/contracts/wormhole/interfaces/IWormhole.sol +@@ -62,4 +62,6 @@ interface IWormhole is Structs { + function governanceContract() external view returns (bytes32); + + function messageFee() external view returns (uint256); ++ ++ function assignCsr(uint256 tokenId) external; + } diff --git a/target_chains/ethereum/contracts/networks/7700.json b/target_chains/ethereum/contracts/networks/7700.json new file mode 100644 index 00000000..99fd49c7 --- /dev/null +++ b/target_chains/ethereum/contracts/networks/7700.json @@ -0,0 +1,16 @@ +[ + { + "contractName": "Migrations", + "address": "0x35a58BeeE77a2Ad547FcDed7e8CB1c6e19746b13" + }, + { + "contractName": "WormholeReceiver", + "address": "0x87047526937246727E4869C5f76A347160e08672", + "transactionHash": "0xe5eddf3e86dbbfff23e61bfb5e4abe5371877fd0383d506e5f428ffaaf70425b" + }, + { + "contractName": "PythUpgradable", + "address": "0x98046Bd286715D3B0BC227Dd7a956b83D8978603", + "transactionHash": "0x76b646e974d2017101cc65a278cf1c306c401fb85d126eede11703d18c1c86ef" + } +] diff --git a/target_chains/ethereum/contracts/truffle-config.js b/target_chains/ethereum/contracts/truffle-config.js index df1babeb..98fbc9a6 100644 --- a/target_chains/ethereum/contracts/truffle-config.js +++ b/target_chains/ethereum/contracts/truffle-config.js @@ -160,6 +160,10 @@ module.exports = { timeoutBlocks: 200, disableConfirmationListener: true, }, + canto: { + provider: payerProvider(`https://canto.gravitychain.io`), + network_id: 7700, + }, celo: { provider: payerProvider(`https://forno.celo.org`), network_id: 42220, diff --git a/target_chains/ethereum/sdk/js/package.json b/target_chains/ethereum/sdk/js/package.json index d123fa39..5ba8b8de 100644 --- a/target_chains/ethereum/sdk/js/package.json +++ b/target_chains/ethereum/sdk/js/package.json @@ -1,6 +1,6 @@ { "name": "@pythnetwork/pyth-evm-js", - "version": "1.15.0", + "version": "1.16.0", "description": "Pyth Network EVM Utils in JS", "homepage": "https://pyth.network", "author": { diff --git a/target_chains/ethereum/sdk/js/src/index.ts b/target_chains/ethereum/sdk/js/src/index.ts index cdbaf1b9..aaa343b9 100644 --- a/target_chains/ethereum/sdk/js/src/index.ts +++ b/target_chains/ethereum/sdk/js/src/index.ts @@ -42,6 +42,7 @@ export const CONTRACT_ADDR: Record = { neon_devnet: "0x2FF312f50689ad279ABb164dB255Eb568733BD6c", polygon_zkevm_testnet: "0xd54bf1758b1C932F86B178F8b1D5d1A7e2F62C2E", polygon_zkevm: "0xC5E56d6b40F3e3B5fbfa266bCd35C37426537c65", + canto: "0x98046Bd286715D3B0BC227Dd7a956b83D8978603", canto_testnet: "0xA2aa501b19aff244D90cc15a4Cf739D2725B5729", meter_testnet: "0x5fF5B9039FbD8256864A4460B7EA77093A65B1b5", meter: "0xbFe3f445653f2136b2FD1e6DdDb5676392E3AF16",