From 134623c2b102bb5139737927116a4193cca46379 Mon Sep 17 00:00:00 2001 From: Vladimir Stepanenko Date: Mon, 26 Sep 2022 15:21:17 +0300 Subject: [PATCH 1/7] Update --- deploy-data/sepolia2.ts | 18 +++++++++++ deploy/01-bridge.ts | 20 +++++++++++-- hardhat.config.ts | 25 +++++++++++++++- package.json | 4 +-- scripts/verify-bridge.ts | 25 ++++++++++++++++ yarn.lock | 65 ++++++++++++++++++++++++++++++++++++---- 6 files changed, 146 insertions(+), 11 deletions(-) create mode 100644 deploy-data/sepolia2.ts create mode 100644 scripts/verify-bridge.ts diff --git a/deploy-data/sepolia2.ts b/deploy-data/sepolia2.ts new file mode 100644 index 0000000..b177ec5 --- /dev/null +++ b/deploy-data/sepolia2.ts @@ -0,0 +1,18 @@ + +import DeployConfig from "./config"; + +const config: DeployConfig = { + "xorAddress": "0x9826ecfcd937c4518e1c42b3703c7cb908b61197", + "valAddress": "0x88ee18defc56d78417b0d331e794ef75799ca6d1", + "sidechainAssets": [ + ], + "erc20Addresses": [ + ], + "peers": [ + "0x981bccf6d8593dc49c22cf744a59afa5a2b23118", + "0x90dca3c91c10e802093318123ad8bb8809061765", + "0x457d710255184dbf63c019ab50f65743c6cb072f" + ] +}; + +export default config; diff --git a/deploy/01-bridge.ts b/deploy/01-bridge.ts index a5a30cb..232c240 100644 --- a/deploy/01-bridge.ts +++ b/deploy/01-bridge.ts @@ -5,12 +5,14 @@ import { default as gethConfig } from "../deploy-data/geth" import { default as rinkebyConfig } from "../deploy-data/rinkeby" import { default as mainnetConfig } from "../deploy-data/mainnet" import { default as sepoliaConfig } from "../deploy-data/sepolia" +import { default as sepolia2Config } from "../deploy-data/sepolia2" module.exports = async ({ deployments, getUnnamedAccounts, - network + network, + run }: HardhatRuntimeEnvironment) => { let [deployer] = await getUnnamedAccounts(); @@ -28,10 +30,14 @@ module.exports = async ({ case "sepolia": config = sepoliaConfig; break; + case "sepolia2": + config = sepolia2Config; + break; case "geth": config = gethConfig; break; default: + console.log("No config for network", network.name); config = ganacheConfig; break; } @@ -40,7 +46,7 @@ module.exports = async ({ let tokenAddresses = config.sidechainAssets.map((val) => val.address); let assetIds = config.sidechainAssets.map((val) => val.asset_id); - await deployments.deploy("Bridge", { + let bridge = await deployments.deploy("Bridge", { from: deployer, log: true, autoMine: true, @@ -51,4 +57,14 @@ module.exports = async ({ '0x0000000000000000000000000000000000000000000000000000000000000000' ] }); + + await run("verify:verify", { + address: bridge.address, + constructorArguments: [ + config.peers, + tokenAddresses, assetIds, config.erc20Addresses, + config.valAddress, config.xorAddress, + '0x0000000000000000000000000000000000000000000000000000000000000000' + ], + }); }; diff --git a/hardhat.config.ts b/hardhat.config.ts index cd63e9e..d032bf2 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -57,6 +57,11 @@ const config: HardhatUserConfig = { url: 'https://rpc.sepolia.org', accounts: [sepoliaPrivateKey], }, + sepolia2: { + chainId: 11155111, + url: 'https://rpc.sepolia.org', + accounts: [sepoliaPrivateKey], + }, mainnet: { chainId: 1, url: `https://mainnet.infura.io/v3/${infuraKey}`, @@ -87,7 +92,25 @@ const config: HardhatUserConfig = { timeout: 60000 }, etherscan: { - apiKey: etherscanKey + apiKey: etherscanKey, + customChains: [ + { + network: "sepolia", + chainId: 11155111, + urls: { + apiURL: "https://api-sepolia.etherscan.io/api", + browserURL: "https://sepolia.etherscan.io" + } + }, + { + network: "sepolia", + chainId: 11155111, + urls: { + apiURL: "https://api-sepolia.etherscan.io/api", + browserURL: "https://sepolia.etherscan.io" + } + } + ] } }; diff --git a/package.json b/package.json index f5d0dd5..8142b76 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "@iarna/toml": "^2.2.5", - "@nomiclabs/hardhat-etherscan": "^2.1.4", + "@nomiclabs/hardhat-etherscan": "^3.1.0", "@openzeppelin/contracts": "^4.3.2", "@openzeppelin/test-helpers": "https://github.com/Snowfork/openzeppelin-test-helpers.git#3f9c4b8", "@sora-substrate/util": "^1.8.15", @@ -49,4 +49,4 @@ "typescript": "^4.4.3", "web3": "^1.3.6" } -} +} \ No newline at end of file diff --git a/scripts/verify-bridge.ts b/scripts/verify-bridge.ts new file mode 100644 index 0000000..d89a589 --- /dev/null +++ b/scripts/verify-bridge.ts @@ -0,0 +1,25 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import DeployConfig from "../deploy-data/config"; +import { default as mainnetConfig } from "../deploy-data/mainnet" + +async function main() { + const hh: HardhatRuntimeEnvironment = require("hardhat"); + const config = mainnetConfig; + const bridgeAddress = "0x5c9e99599Fdbbb261dA0BDe3b8daD5601d332E8F"; + let tokenAddresses = config.sidechainAssets.map((val) => val.address); + let assetIds = config.sidechainAssets.map((val) => val.asset_id); + await hh.run("verify:verify", { + address: bridgeAddress, + constructorArguments: [ + config.peers, + tokenAddresses, assetIds, config.erc20Addresses, + config.valAddress, config.xorAddress, + '0x0000000000000000000000000000000000000000000000000000000000000000' + ], + }); +} + +main().then(() => process.exit(0)).catch((error) => { + console.error(error); + process.exit(1); +}); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index e573584..0b92306 100644 --- a/yarn.lock +++ b/yarn.lock @@ -869,18 +869,21 @@ resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.0.5.tgz#131b0da1b71680d5a01569f916ae878229d326d3" integrity sha512-A2gZAGB6kUvLx+kzM92HKuUF33F1FSe90L0TmkXkT2Hh0OKRpvWZURUSU2nghD2yC4DzfEZ3DftfeHGvZ2JTUw== -"@nomiclabs/hardhat-etherscan@^2.1.4": - version "2.1.8" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-2.1.8.tgz#e206275e96962cd15e5ba9148b44388bc922d8c2" - integrity sha512-0+rj0SsZotVOcTLyDOxnOc3Gulo8upo0rsw/h+gBPcmtj91YqYJNhdARHoBxOhhE8z+5IUQPx+Dii04lXT14PA== +"@nomiclabs/hardhat-etherscan@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.0.tgz#7137554862b3b1c914f1b1bf110f0529fd2dec53" + integrity sha512-JroYgfN1AlYFkQTQ3nRwFi4o8NtZF7K/qFR2dxDUgHbCtIagkUseca9L4E/D2ScUm4XT40+8PbCdqZi+XmHyQA== dependencies: "@ethersproject/abi" "^5.1.2" "@ethersproject/address" "^5.0.2" cbor "^5.0.2" + chalk "^2.4.2" debug "^4.1.1" fs-extra "^7.0.1" - node-fetch "^2.6.0" + lodash "^4.17.11" semver "^6.3.0" + table "^6.8.0" + undici "^5.4.0" "@nomiclabs/hardhat-truffle5@^2.0.0": version "2.0.5" @@ -2027,6 +2030,16 @@ ajv@^6.10.0, ajv@^6.12.3: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.1: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" @@ -2189,6 +2202,11 @@ assertion-error@^1.1.0: resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + async-eventemitter@^0.2.2, async-eventemitter@^0.2.4: version "0.2.4" resolved "https://registry.yarnpkg.com/async-eventemitter/-/async-eventemitter-0.2.4.tgz#f5e7c8ca7d3e46aab9ec40a292baf686a0bafaca" @@ -5612,6 +5630,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + json-schema@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" @@ -5929,6 +5952,11 @@ lodash.sum@^4.0.2: resolved "https://registry.yarnpkg.com/lodash.sum/-/lodash.sum-4.0.2.tgz#ad90e397965d803d4f1ff7aa5b2d0197f3b4637b" integrity sha1-rZDjl5ZdgD1PH/eqWy0Bl/O0Y3s= +lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== + lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -7390,7 +7418,7 @@ require-from-string@^1.1.0: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" integrity sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg= -require-from-string@^2.0.0: +require-from-string@^2.0.0, require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== @@ -7769,6 +7797,15 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + snake-case@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f" @@ -8196,6 +8233,17 @@ sync-rpc@^1.2.1: dependencies: get-port "^3.1.0" +table@^6.8.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" + integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== + dependencies: + ajv "^8.0.1" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + tar-fs@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" @@ -8502,6 +8550,11 @@ undici@^4.14.1: resolved "https://registry.yarnpkg.com/undici/-/undici-4.16.0.tgz#469bb87b3b918818d3d7843d91a1d08da357d5ff" integrity sha512-tkZSECUYi+/T1i4u+4+lwZmQgLXd4BLGlrc7KZPcLIW7Jpq99+Xpc30ONv7nS6F5UNOxp/HBZSSL9MafUrvJbw== +undici@^5.4.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.10.0.tgz#dd9391087a90ccfbd007568db458674232ebf014" + integrity sha512-c8HsD3IbwmjjbLvoZuRI26TZic+TSEe8FPMLLOkN1AfYRhdjnKBU6yL+IwcSCbdZiX4e5t0lfMDLDCqj4Sq70g== + unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" From bc512ee871f378bc08ec4f3f5188d1af91e265f7 Mon Sep 17 00:00:00 2001 From: Vladimir Stepanenko Date: Mon, 17 Oct 2022 02:49:45 +0300 Subject: [PATCH 2/7] Update signatures --- Bridge/Bridge.sol | 20 ++++++++++++-------- scripts/verify-bridge.ts | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Bridge/Bridge.sol b/Bridge/Bridge.sol index 90376eb..648e076 100644 --- a/Bridge/Bridge.sol +++ b/Bridge/Bridge.sol @@ -245,7 +245,8 @@ contract Bridge is EthTokenReciever { require( checkSignatures( keccak256( - abi.encodePacked( + abi.encode( + "migrate", address(this), newContractAddress, salt, @@ -306,7 +307,8 @@ contract Bridge is EthTokenReciever { require( checkSignatures( keccak256( - abi.encodePacked( + abi.encode( + "addAsset", address(this), name, symbol, @@ -412,9 +414,9 @@ contract Bridge is EthTokenReciever { require( checkSignatures( keccak256( - abi.encodePacked( - address(this), + abi.encode( "addPeer", + address(this), newPeerAddress, txHash, _networkId @@ -453,9 +455,9 @@ contract Bridge is EthTokenReciever { require( checkSignatures( keccak256( - abi.encodePacked( - address(this), + abi.encode( "removePeer", + address(this), peerAddress, txHash, _networkId @@ -499,7 +501,8 @@ contract Bridge is EthTokenReciever { require( checkSignatures( keccak256( - abi.encodePacked( + abi.encode( + "transfer", address(this), tokenAddress, amount, @@ -557,7 +560,8 @@ contract Bridge is EthTokenReciever { require( checkSignatures( keccak256( - abi.encodePacked( + abi.encode( + "transfer", address(this), sidechainAssetId, amount, diff --git a/scripts/verify-bridge.ts b/scripts/verify-bridge.ts index d89a589..b74948d 100644 --- a/scripts/verify-bridge.ts +++ b/scripts/verify-bridge.ts @@ -5,7 +5,7 @@ import { default as mainnetConfig } from "../deploy-data/mainnet" async function main() { const hh: HardhatRuntimeEnvironment = require("hardhat"); const config = mainnetConfig; - const bridgeAddress = "0x5c9e99599Fdbbb261dA0BDe3b8daD5601d332E8F"; + const bridgeAddress = "0x6F984C337aD5b7C2084805042AE942cef462e3ff"; let tokenAddresses = config.sidechainAssets.map((val) => val.address); let assetIds = config.sidechainAssets.map((val) => val.asset_id); await hh.run("verify:verify", { From 7b8db4a82901943b208c2448d4724be4319a3011 Mon Sep 17 00:00:00 2001 From: Vladimir Stepanenko Date: Wed, 19 Oct 2022 09:42:04 +0300 Subject: [PATCH 3/7] Add USDT support --- Bridge/Bridge.sol | 50 ++++++++++++++++++++++++++++++----------- Bridge/IUSDT.sol | 32 ++++++++++++++++++++++++++ deploy-data/config.ts | 1 + deploy-data/ganache.ts | 1 + deploy-data/geth.ts | 1 + deploy-data/mainnet.ts | 1 + deploy-data/rinkeby.ts | 1 + deploy-data/sepolia.ts | 1 + deploy-data/sepolia2.ts | 1 + deploy/01-bridge.ts | 2 +- hardhat.config.ts | 6 +++++ tasks/gen-config.ts | 5 ++++- tasks/send.ts | 18 +++++++++++++++ 13 files changed, 105 insertions(+), 15 deletions(-) create mode 100644 Bridge/IUSDT.sol create mode 100644 tasks/send.ts diff --git a/Bridge/Bridge.sol b/Bridge/Bridge.sol index 648e076..d64bcdc 100644 --- a/Bridge/Bridge.sol +++ b/Bridge/Bridge.sol @@ -7,6 +7,7 @@ import "./Ownable.sol"; import "./ERC20Burnable.sol"; import "./SafeERC20.sol"; import "./EthTokenReciever.sol"; +import "./IUSDT.sol"; /** * Provides functionality of the HASHI bridge @@ -43,6 +44,8 @@ contract Bridge is EthTokenReciever { /** EVM netowrk ID */ bytes32 public immutable _networkId; + IUSDT public immutable _addressUSDT; + event Withdrawal(bytes32 txHash); event Deposit( bytes32 destination, @@ -68,6 +71,7 @@ contract Bridge is EthTokenReciever { address[] memory erc20Addresses, address addressVAL, address addressXOR, + address addressUSDT, bytes32 networkId ) { require( @@ -97,6 +101,7 @@ contract Bridge is EthTokenReciever { for (uint256 i; i < erc20TokensCount; i++) { acceptedEthTokens[erc20Addresses[i]] = true; } + _addressUSDT = IUSDT(addressUSDT); } modifier shouldBeInitialized() { @@ -167,7 +172,8 @@ contract Bridge is EthTokenReciever { require( checkSignatures( keccak256( - abi.encodePacked( + abi.encode( + "addToken", address(this), newToken, ticker, @@ -205,7 +211,7 @@ contract Bridge is EthTokenReciever { require( checkSignatures( keccak256( - abi.encodePacked( + abi.encode( "prepareMigration", address(this), salt, @@ -274,6 +280,10 @@ contract Bridge is EthTokenReciever { token.balanceOf(address(this)) ); } + _addressUSDT.transfer( + newContractAddress, + _addressUSDT.balanceOf(address(this)) + ); EthTokenReciever(newContractAddress).receivePayment{ value: address(this).balance }(); @@ -383,13 +393,23 @@ contract Bridge is EthTokenReciever { acceptedEthTokens[tokenAddress], "The Token is not accepted for transfer to sidechain" ); - uint256 balanceBefore = token.balanceOf(address(this)); - token.safeTransferFrom(msg.sender, address(this), amount); - uint256 balanceAfter = token.balanceOf(address(this)); - require( - balanceAfter - balanceBefore >= amount, - "Not enough tokens transferred" - ); + if (tokenAddress == address(_addressUSDT)) { + uint256 balanceBefore = _addressUSDT.balanceOf(address(this)); + _addressUSDT.transferFrom(msg.sender, address(this), amount); + uint256 balanceAfter = _addressUSDT.balanceOf(address(this)); + require( + balanceAfter - balanceBefore >= amount, + "Not enough tokens transferred" + ); + } else { + uint256 balanceBefore = token.balanceOf(address(this)); + token.safeTransferFrom(msg.sender, address(this), amount); + uint256 balanceAfter = token.balanceOf(address(this)); + require( + balanceAfter - balanceBefore >= amount, + "Not enough tokens transferred" + ); + } } emit Deposit(to, amount, tokenAddress, sidechainAssetId); } @@ -524,9 +544,13 @@ contract Bridge is EthTokenReciever { // untrusted transfer, relies on provided cryptographic proof to.transfer(amount); } else { - IERC20 coin = IERC20(tokenAddress); - // untrusted call, relies on provided cryptographic proof - coin.safeTransfer(to, amount); + if (tokenAddress == address(_addressUSDT)) { + _addressUSDT.transfer(to, amount); + } else { + IERC20 coin = IERC20(tokenAddress); + // untrusted call, relies on provided cryptographic proof + coin.safeTransfer(to, amount); + } } emit Withdrawal(txHash); } @@ -561,7 +585,7 @@ contract Bridge is EthTokenReciever { checkSignatures( keccak256( abi.encode( - "transfer", + "transferOwned", address(this), sidechainAssetId, amount, diff --git a/Bridge/IUSDT.sol b/Bridge/IUSDT.sol new file mode 100644 index 0000000..91da04a --- /dev/null +++ b/Bridge/IUSDT.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: Apache 2.0 + +pragma solidity =0.8.17; + +// Taken from https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#code + +/** + * @title ERC20Basic + * @dev Simpler version of ERC20 interface + * @dev see https://github.com/ethereum/EIPs/issues/20 + */ +interface IUSDT { + function totalSupply() external returns (uint); + + function balanceOf(address who) external returns (uint); + + function transfer(address to, uint value) external; + + event Transfer(address indexed from, address indexed to, uint value); + + function allowance(address owner, address spender) external returns (uint); + + function transferFrom( + address from, + address to, + uint value + ) external; + + function approve(address spender, uint value) external; + + event Approval(address indexed owner, address indexed spender, uint value); +} diff --git a/deploy-data/config.ts b/deploy-data/config.ts index 91ae4e1..4a38944 100644 --- a/deploy-data/config.ts +++ b/deploy-data/config.ts @@ -6,6 +6,7 @@ interface SidechainAsset { interface DeployConfig { xorAddress: string; valAddress: string; + usdtAddress: string; erc20Addresses: string[]; sidechainAssets: SidechainAsset[]; peers: string[]; diff --git a/deploy-data/ganache.ts b/deploy-data/ganache.ts index 03f2dcf..04c13e8 100644 --- a/deploy-data/ganache.ts +++ b/deploy-data/ganache.ts @@ -4,6 +4,7 @@ import DeployConfig from "./config"; const config: DeployConfig = { "xorAddress": "0x40fd72257597aa14c7231a7b1aaa29fce868f677", "valAddress": "0xe88f8313e61a97cec1871ee37fbbe2a8bf3ed1e4", + usdtAddress: undefined, "sidechainAssets": [ { "address": "0x519C1001D550C0a1DaE7d1fC220f7d14c2A521BB", diff --git a/deploy-data/geth.ts b/deploy-data/geth.ts index 98869ac..edac138 100644 --- a/deploy-data/geth.ts +++ b/deploy-data/geth.ts @@ -3,6 +3,7 @@ import DeployConfig from "./config"; const config: DeployConfig = { xorAddress: "0x0", valAddress: "0x0", + usdtAddress: undefined, erc20Addresses: [ "0x0" ], diff --git a/deploy-data/mainnet.ts b/deploy-data/mainnet.ts index 0ac579e..f086541 100644 --- a/deploy-data/mainnet.ts +++ b/deploy-data/mainnet.ts @@ -4,6 +4,7 @@ import DeployConfig from "./config"; const config: DeployConfig = { "xorAddress": "0x40fd72257597aa14c7231a7b1aaa29fce868f677", "valAddress": "0xe88f8313e61a97cec1871ee37fbbe2a8bf3ed1e4", + "usdtAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "sidechainAssets": [ { "address": "0x519C1001D550C0a1DaE7d1fC220f7d14c2A521BB", diff --git a/deploy-data/rinkeby.ts b/deploy-data/rinkeby.ts index 488b86c..eb53c40 100644 --- a/deploy-data/rinkeby.ts +++ b/deploy-data/rinkeby.ts @@ -4,6 +4,7 @@ import DeployConfig from "./config"; const config: DeployConfig = { "xorAddress": "0x83ba842e5e26a4eda2466891221187aabbc33692", "valAddress": "0x7fcb82ab5a4762f0f18287ece64d4ec74b6071c0", + usdtAddress: undefined, "sidechainAssets": [ { "address": "0x4c8886E4B8d4bb146cbC03B851307FDDf869fe8B", diff --git a/deploy-data/sepolia.ts b/deploy-data/sepolia.ts index ce93c27..2819cd8 100644 --- a/deploy-data/sepolia.ts +++ b/deploy-data/sepolia.ts @@ -4,6 +4,7 @@ import DeployConfig from "./config"; const config: DeployConfig = { "xorAddress": "0x9826ecfcd937c4518e1c42b3703c7cb908b61197", "valAddress": "0x88ee18defc56d78417b0d331e794ef75799ca6d1", + usdtAddress: undefined, "sidechainAssets": [ { "address": "0x37F93FD8A3c606B3a8cceB84e8613238707137ee", diff --git a/deploy-data/sepolia2.ts b/deploy-data/sepolia2.ts index b177ec5..b4f03b0 100644 --- a/deploy-data/sepolia2.ts +++ b/deploy-data/sepolia2.ts @@ -4,6 +4,7 @@ import DeployConfig from "./config"; const config: DeployConfig = { "xorAddress": "0x9826ecfcd937c4518e1c42b3703c7cb908b61197", "valAddress": "0x88ee18defc56d78417b0d331e794ef75799ca6d1", + usdtAddress: undefined, "sidechainAssets": [ ], "erc20Addresses": [ diff --git a/deploy/01-bridge.ts b/deploy/01-bridge.ts index 232c240..6e4cb8b 100644 --- a/deploy/01-bridge.ts +++ b/deploy/01-bridge.ts @@ -53,7 +53,7 @@ module.exports = async ({ args: [ config.peers, tokenAddresses, assetIds, config.erc20Addresses, - config.valAddress, config.xorAddress, + config.valAddress, config.xorAddress, config.usdtAddress, '0x0000000000000000000000000000000000000000000000000000000000000000' ] }); diff --git a/hardhat.config.ts b/hardhat.config.ts index c049db9..6106cf9 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -3,6 +3,7 @@ import { resolve } from "path"; import "solidity-coverage" import * as gen_config from "./tasks/gen-config"; +import * as send from "./tasks/send"; dotenv({ path: resolve(__dirname, ".env") }); @@ -120,4 +121,9 @@ task("gen-config", "Generate config file for given network") .addParam("peers") .addParam("output").setAction(gen_config.main); +task("send", "Generate config file for given network") + .addParam("to") + .addParam("amount") + .addParam("token", "Token address", undefined, undefined, true) + .setAction(send.main); export default config; diff --git a/tasks/gen-config.ts b/tasks/gen-config.ts index e125668..2771722 100644 --- a/tasks/gen-config.ts +++ b/tasks/gen-config.ts @@ -28,12 +28,15 @@ export async function main({ contractAddress, soraEndpoint, output, peers }) { } let xorAddress; let valAddress; + let usdtAddress; let erc20Addresses = []; for (const asset of registeredAssets) { if (asset.symbol == "XOR") { xorAddress = asset.externalAddress; } else if (asset.symbol == "VAL") { valAddress = asset.externalAddress; + } else if (asset.symbol == "USDT") { + usdtAddress = asset.externalAddress; } else if (sidechainAssets.findIndex((value) => value.asset_id == asset.address) == -1) { if (asset.externalAddress != "0x0000000000000000000000000000000000000000") { erc20Addresses.push(asset.externalAddress); @@ -41,7 +44,7 @@ export async function main({ contractAddress, soraEndpoint, output, peers }) { } } let config: DeployConfig = { - xorAddress, valAddress, sidechainAssets, erc20Addresses, peers: peersArray + xorAddress, valAddress, sidechainAssets, erc20Addresses, peers: peersArray, usdtAddress } let data = ` import DeployConfig from "./config"; diff --git a/tasks/send.ts b/tasks/send.ts new file mode 100644 index 0000000..725e20a --- /dev/null +++ b/tasks/send.ts @@ -0,0 +1,18 @@ +import { HardhatRuntimeEnvironment } from 'hardhat/types'; +import DeployConfig from "../deploy-data/config"; +import * as sora from "@sora-substrate/util"; +import abi from "../abis/BridgeOld.abi"; +import { writeFile } from "fs/promises"; +import "hardhat-deploy"; + +export async function main({ to, amount, token }) { + const hh: HardhatRuntimeEnvironment = require("hardhat"); + let [deployer] = await hh.getUnnamedAccounts(); + let res; + if (!token) { + res = await hh.deployments.execute("Bridge", { from: deployer, log: true, value: amount }, "sendEthToSidechain", to); + } else { + res = await hh.deployments.execute("Bridge", { from: deployer, log: true }, "sendERC20ToSidechain", to, amount, token); + } + console.log(res); +} From a3de9138b40e40d2b04aed6af3bb21872989fc11 Mon Sep 17 00:00:00 2001 From: Vladimir Stepanenko Date: Mon, 31 Oct 2022 09:07:02 +0300 Subject: [PATCH 4/7] Remove additional code for USDT support --- Bridge/Bridge.sol | 42 ++++++++++------------------------------- deploy-data/config.ts | 1 - deploy-data/ganache.ts | 1 - deploy-data/geth.ts | 1 - deploy-data/mainnet.ts | 1 - deploy-data/rinkeby.ts | 1 - deploy-data/sepolia.ts | 1 - deploy-data/sepolia2.ts | 1 - deploy/01-bridge.ts | 2 +- tasks/gen-config.ts | 4 +--- 10 files changed, 12 insertions(+), 43 deletions(-) diff --git a/Bridge/Bridge.sol b/Bridge/Bridge.sol index d64bcdc..9672c0c 100644 --- a/Bridge/Bridge.sol +++ b/Bridge/Bridge.sol @@ -44,8 +44,6 @@ contract Bridge is EthTokenReciever { /** EVM netowrk ID */ bytes32 public immutable _networkId; - IUSDT public immutable _addressUSDT; - event Withdrawal(bytes32 txHash); event Deposit( bytes32 destination, @@ -71,7 +69,6 @@ contract Bridge is EthTokenReciever { address[] memory erc20Addresses, address addressVAL, address addressXOR, - address addressUSDT, bytes32 networkId ) { require( @@ -101,7 +98,6 @@ contract Bridge is EthTokenReciever { for (uint256 i; i < erc20TokensCount; i++) { acceptedEthTokens[erc20Addresses[i]] = true; } - _addressUSDT = IUSDT(addressUSDT); } modifier shouldBeInitialized() { @@ -280,10 +276,6 @@ contract Bridge is EthTokenReciever { token.balanceOf(address(this)) ); } - _addressUSDT.transfer( - newContractAddress, - _addressUSDT.balanceOf(address(this)) - ); EthTokenReciever(newContractAddress).receivePayment{ value: address(this).balance }(); @@ -393,23 +385,13 @@ contract Bridge is EthTokenReciever { acceptedEthTokens[tokenAddress], "The Token is not accepted for transfer to sidechain" ); - if (tokenAddress == address(_addressUSDT)) { - uint256 balanceBefore = _addressUSDT.balanceOf(address(this)); - _addressUSDT.transferFrom(msg.sender, address(this), amount); - uint256 balanceAfter = _addressUSDT.balanceOf(address(this)); - require( - balanceAfter - balanceBefore >= amount, - "Not enough tokens transferred" - ); - } else { - uint256 balanceBefore = token.balanceOf(address(this)); - token.safeTransferFrom(msg.sender, address(this), amount); - uint256 balanceAfter = token.balanceOf(address(this)); - require( - balanceAfter - balanceBefore >= amount, - "Not enough tokens transferred" - ); - } + uint256 balanceBefore = token.balanceOf(address(this)); + token.safeTransferFrom(msg.sender, address(this), amount); + uint256 balanceAfter = token.balanceOf(address(this)); + require( + balanceAfter - balanceBefore >= amount, + "Not enough tokens transferred" + ); } emit Deposit(to, amount, tokenAddress, sidechainAssetId); } @@ -544,13 +526,9 @@ contract Bridge is EthTokenReciever { // untrusted transfer, relies on provided cryptographic proof to.transfer(amount); } else { - if (tokenAddress == address(_addressUSDT)) { - _addressUSDT.transfer(to, amount); - } else { - IERC20 coin = IERC20(tokenAddress); - // untrusted call, relies on provided cryptographic proof - coin.safeTransfer(to, amount); - } + IERC20 coin = IERC20(tokenAddress); + // untrusted call, relies on provided cryptographic proof + coin.safeTransfer(to, amount); } emit Withdrawal(txHash); } diff --git a/deploy-data/config.ts b/deploy-data/config.ts index 4a38944..91ae4e1 100644 --- a/deploy-data/config.ts +++ b/deploy-data/config.ts @@ -6,7 +6,6 @@ interface SidechainAsset { interface DeployConfig { xorAddress: string; valAddress: string; - usdtAddress: string; erc20Addresses: string[]; sidechainAssets: SidechainAsset[]; peers: string[]; diff --git a/deploy-data/ganache.ts b/deploy-data/ganache.ts index 04c13e8..03f2dcf 100644 --- a/deploy-data/ganache.ts +++ b/deploy-data/ganache.ts @@ -4,7 +4,6 @@ import DeployConfig from "./config"; const config: DeployConfig = { "xorAddress": "0x40fd72257597aa14c7231a7b1aaa29fce868f677", "valAddress": "0xe88f8313e61a97cec1871ee37fbbe2a8bf3ed1e4", - usdtAddress: undefined, "sidechainAssets": [ { "address": "0x519C1001D550C0a1DaE7d1fC220f7d14c2A521BB", diff --git a/deploy-data/geth.ts b/deploy-data/geth.ts index edac138..98869ac 100644 --- a/deploy-data/geth.ts +++ b/deploy-data/geth.ts @@ -3,7 +3,6 @@ import DeployConfig from "./config"; const config: DeployConfig = { xorAddress: "0x0", valAddress: "0x0", - usdtAddress: undefined, erc20Addresses: [ "0x0" ], diff --git a/deploy-data/mainnet.ts b/deploy-data/mainnet.ts index f086541..0ac579e 100644 --- a/deploy-data/mainnet.ts +++ b/deploy-data/mainnet.ts @@ -4,7 +4,6 @@ import DeployConfig from "./config"; const config: DeployConfig = { "xorAddress": "0x40fd72257597aa14c7231a7b1aaa29fce868f677", "valAddress": "0xe88f8313e61a97cec1871ee37fbbe2a8bf3ed1e4", - "usdtAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7", "sidechainAssets": [ { "address": "0x519C1001D550C0a1DaE7d1fC220f7d14c2A521BB", diff --git a/deploy-data/rinkeby.ts b/deploy-data/rinkeby.ts index eb53c40..488b86c 100644 --- a/deploy-data/rinkeby.ts +++ b/deploy-data/rinkeby.ts @@ -4,7 +4,6 @@ import DeployConfig from "./config"; const config: DeployConfig = { "xorAddress": "0x83ba842e5e26a4eda2466891221187aabbc33692", "valAddress": "0x7fcb82ab5a4762f0f18287ece64d4ec74b6071c0", - usdtAddress: undefined, "sidechainAssets": [ { "address": "0x4c8886E4B8d4bb146cbC03B851307FDDf869fe8B", diff --git a/deploy-data/sepolia.ts b/deploy-data/sepolia.ts index 2819cd8..ce93c27 100644 --- a/deploy-data/sepolia.ts +++ b/deploy-data/sepolia.ts @@ -4,7 +4,6 @@ import DeployConfig from "./config"; const config: DeployConfig = { "xorAddress": "0x9826ecfcd937c4518e1c42b3703c7cb908b61197", "valAddress": "0x88ee18defc56d78417b0d331e794ef75799ca6d1", - usdtAddress: undefined, "sidechainAssets": [ { "address": "0x37F93FD8A3c606B3a8cceB84e8613238707137ee", diff --git a/deploy-data/sepolia2.ts b/deploy-data/sepolia2.ts index b4f03b0..b177ec5 100644 --- a/deploy-data/sepolia2.ts +++ b/deploy-data/sepolia2.ts @@ -4,7 +4,6 @@ import DeployConfig from "./config"; const config: DeployConfig = { "xorAddress": "0x9826ecfcd937c4518e1c42b3703c7cb908b61197", "valAddress": "0x88ee18defc56d78417b0d331e794ef75799ca6d1", - usdtAddress: undefined, "sidechainAssets": [ ], "erc20Addresses": [ diff --git a/deploy/01-bridge.ts b/deploy/01-bridge.ts index 6e4cb8b..232c240 100644 --- a/deploy/01-bridge.ts +++ b/deploy/01-bridge.ts @@ -53,7 +53,7 @@ module.exports = async ({ args: [ config.peers, tokenAddresses, assetIds, config.erc20Addresses, - config.valAddress, config.xorAddress, config.usdtAddress, + config.valAddress, config.xorAddress, '0x0000000000000000000000000000000000000000000000000000000000000000' ] }); diff --git a/tasks/gen-config.ts b/tasks/gen-config.ts index 2771722..59887da 100644 --- a/tasks/gen-config.ts +++ b/tasks/gen-config.ts @@ -35,8 +35,6 @@ export async function main({ contractAddress, soraEndpoint, output, peers }) { xorAddress = asset.externalAddress; } else if (asset.symbol == "VAL") { valAddress = asset.externalAddress; - } else if (asset.symbol == "USDT") { - usdtAddress = asset.externalAddress; } else if (sidechainAssets.findIndex((value) => value.asset_id == asset.address) == -1) { if (asset.externalAddress != "0x0000000000000000000000000000000000000000") { erc20Addresses.push(asset.externalAddress); @@ -44,7 +42,7 @@ export async function main({ contractAddress, soraEndpoint, output, peers }) { } } let config: DeployConfig = { - xorAddress, valAddress, sidechainAssets, erc20Addresses, peers: peersArray, usdtAddress + xorAddress, valAddress, sidechainAssets, erc20Addresses, peers: peersArray, } let data = ` import DeployConfig from "./config"; From 7fdf7b0f5a82ed124aee8768e3d191f23ec39e7c Mon Sep 17 00:00:00 2001 From: Vladimir Stepanenko Date: Mon, 31 Oct 2022 09:08:15 +0300 Subject: [PATCH 5/7] Remove USDT interface --- Bridge/Bridge.sol | 1 - Bridge/IUSDT.sol | 32 -------------------------------- 2 files changed, 33 deletions(-) delete mode 100644 Bridge/IUSDT.sol diff --git a/Bridge/Bridge.sol b/Bridge/Bridge.sol index 9672c0c..87ee5e7 100644 --- a/Bridge/Bridge.sol +++ b/Bridge/Bridge.sol @@ -7,7 +7,6 @@ import "./Ownable.sol"; import "./ERC20Burnable.sol"; import "./SafeERC20.sol"; import "./EthTokenReciever.sol"; -import "./IUSDT.sol"; /** * Provides functionality of the HASHI bridge diff --git a/Bridge/IUSDT.sol b/Bridge/IUSDT.sol deleted file mode 100644 index 91da04a..0000000 --- a/Bridge/IUSDT.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: Apache 2.0 - -pragma solidity =0.8.17; - -// Taken from https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#code - -/** - * @title ERC20Basic - * @dev Simpler version of ERC20 interface - * @dev see https://github.com/ethereum/EIPs/issues/20 - */ -interface IUSDT { - function totalSupply() external returns (uint); - - function balanceOf(address who) external returns (uint); - - function transfer(address to, uint value) external; - - event Transfer(address indexed from, address indexed to, uint value); - - function allowance(address owner, address spender) external returns (uint); - - function transferFrom( - address from, - address to, - uint value - ) external; - - function approve(address spender, uint value) external; - - event Approval(address indexed owner, address indexed spender, uint value); -} From c1599c220f02a4f6379791f35228bc7db906b706 Mon Sep 17 00:00:00 2001 From: Vladimir Stepanenko Date: Mon, 31 Oct 2022 09:10:47 +0300 Subject: [PATCH 6/7] Update gen-config.ts --- tasks/gen-config.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tasks/gen-config.ts b/tasks/gen-config.ts index 59887da..a686c81 100644 --- a/tasks/gen-config.ts +++ b/tasks/gen-config.ts @@ -1,12 +1,8 @@ -import { log } from "console"; -import { readFile } from "fs"; import { HardhatRuntimeEnvironment } from 'hardhat/types'; import DeployConfig from "../deploy-data/config"; import * as sora from "@sora-substrate/util"; import abi from "../abis/BridgeOld.abi"; import { writeFile } from "fs/promises"; -import { AnyJson } from "@polkadot/types/types"; -import { keccak256 } from "web3-utils"; export async function main({ contractAddress, soraEndpoint, output, peers }) { let peersArray = (peers as string).split(","); @@ -28,7 +24,6 @@ export async function main({ contractAddress, soraEndpoint, output, peers }) { } let xorAddress; let valAddress; - let usdtAddress; let erc20Addresses = []; for (const asset of registeredAssets) { if (asset.symbol == "XOR") { @@ -42,7 +37,7 @@ export async function main({ contractAddress, soraEndpoint, output, peers }) { } } let config: DeployConfig = { - xorAddress, valAddress, sidechainAssets, erc20Addresses, peers: peersArray, + xorAddress, valAddress, sidechainAssets, erc20Addresses, peers: peersArray } let data = ` import DeployConfig from "./config"; From 9d212bbcc7d5c20f291e6b21b1f8e189e716e275 Mon Sep 17 00:00:00 2001 From: Vladimir Stepanenko Date: Wed, 9 Nov 2022 13:07:53 +0300 Subject: [PATCH 7/7] Update deploy config --- deploy-data/mainnet.ts | 8 ++++++++ gen_mainnet_config.sh | 2 +- hardhat.config.ts | 18 ------------------ 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/deploy-data/mainnet.ts b/deploy-data/mainnet.ts index 0ac579e..9567c0b 100644 --- a/deploy-data/mainnet.ts +++ b/deploy-data/mainnet.ts @@ -16,6 +16,14 @@ const config: DeployConfig = { { "address": "0xc7D9c108D4E1dD1484D3e2568d7f74bfD763d356", "asset_id": "0x0200080000000000000000000000000000000000000000000000000000000000" + }, + { + "address": "0x5E7F20e72C21f6D0Bf0A2814FD4164176401cf8e", + "asset_id": "0x00f2f4fda40a4bf1fc3769d156fa695532eec31e265d75068524462c0b80f674" + }, + { + "address": "0xC60D6662027F5797Cf873bFe80BcF048e30Fc35e", + "asset_id": "0x0200090000000000000000000000000000000000000000000000000000000000" } ], "erc20Addresses": [ diff --git a/gen_mainnet_config.sh b/gen_mainnet_config.sh index 68ffdb3..ee8c52c 100755 --- a/gen_mainnet_config.sh +++ b/gen_mainnet_config.sh @@ -1,3 +1,3 @@ #!/bin/bash -v -npx hardhat gen-config --network mainnet --contract-address 0x1485E9852ac841b52eD44D573036429504f4F602 --sora-endpoint wss://ws.alb.sora.org --peers 0x6C9E8391a0444c739e7e2edd37A2C6e3381b1cbF,0xEf22D478a53bc8BBe854ceF8bA2eb79C49A1a171 --output deploy-data/mainnet.ts +npx hardhat gen-config --network mainnet --contract-address 0x6f984c337ad5b7c2084805042ae942cef462e3ff --sora-endpoint wss://ws.mof.sora.org --peers 0x6C9E8391a0444c739e7e2edd37A2C6e3381b1cbF,0xEf22D478a53bc8BBe854ceF8bA2eb79C49A1a171,0x6219d0ba6a0bafa69cd2b1b15633a3fd864dd371 --output deploy-data/mainnet.ts diff --git a/hardhat.config.ts b/hardhat.config.ts index 6106cf9..7b3aef8 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -94,24 +94,6 @@ const config: HardhatUserConfig = { }, etherscan: { apiKey: etherscanKey, - customChains: [ - { - network: "sepolia", - chainId: 11155111, - urls: { - apiURL: "https://api-sepolia.etherscan.io/api", - browserURL: "https://sepolia.etherscan.io" - } - }, - { - network: "sepolia", - chainId: 11155111, - urls: { - apiURL: "https://api-sepolia.etherscan.io/api", - browserURL: "https://sepolia.etherscan.io" - } - } - ] } };